Android:调整自定义视图的大小。父视图已调整大小,但宽度/高度更改不会传递给子视图

Android:调整自定义视图的大小。父视图已调整大小,但宽度/高度更改不会传递给子视图,android,parent-child,dimensions,custom-view,Android,Parent Child,Dimensions,Custom View,我目前正在尝试使用android制作一个基于老式战舰棋盘游戏的游戏。我现在只是在胡闹,试图对它和我可能需要制作游戏的组件有一个感觉 目前布局xml文件中的基本内容如下: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android

我目前正在尝试使用android制作一个基于老式战舰棋盘游戏的游戏。我现在只是在胡闹,试图对它和我可能需要制作游戏的组件有一个感觉

目前布局xml文件中的基本内容如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<org.greene.battleship.BoardView
    android:id="@+id/board_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <org.greene.battleship.ShipView
            android:id="@+id/ships_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:clickable="true" />
    </RelativeLayout>
</RelativeLayout>
我通过重写views onSizeChanged()函数并检查其中的值来检查视图维度是否已更改

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
    Log.d("BOARD_VIEW", "BoardView.onSizeChanged : width = " + w + ", height = " + h);
    board = new Board(w, h, game_activity);
    super.onSizeChanged(w, h, oldw, oldh);

}
从布局文件可以看出,我有一个RelativeLayout视图组,它作为子视图保存另一个名为ShipView的自定义视图。理想情况下,我想要发生的是,当我去测量它的尺寸时,它的尺寸被限制在测量中设定的范围内。我以类似的方式通过其onMeasure()方法检查ShipView的尺寸

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){

    int parent_width = MeasureSpec.getSize(widthMeasureSpec);
    int parent_height = MeasureSpec.getSize(heightMeasureSpec);

    Log.d("SHIP_VIEW", "ShipView.onMeasure : width = " + parent_width + ", height = " + parent_height);

    this.setMeasuredDimension(parent_width, parent_height);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
日志文件向我显示了以下内容(onMeasure()方法似乎被调用了不止一次,但所有的值都是相同的,因此我不必麻烦显示多个日志,因为这些值都是相同的):

当我通过ShipViews onMeasure()获取尺寸时,似乎没有任何变化,并且忽略了我设置的尺寸限制。我不确定这是否与ShipView的相对位置有关。我是否必须为此设置LayoutParams,因为它们已更改?我认为,如果更改父视图的视图维度,它将被传递给子视图

对于这类游戏来说,这是否是一种正确的方式,这当然有待讨论,但无论哪种方式,我都想知道如何做到这一点(我认为它可以……?)。任何帮助都将不胜感激。

这要归功于:

@覆盖
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
//让超类处理计算
超级测量(宽度测量、高度测量);
//再次设置尺寸,这次按照我们的要求计算
setMeasuredDimension(getMeasuredWidth(),getMeasuredWidth()/2);
//这是必需的,因为子级保留超级类计算的尺寸(这不适用于新的MyFrameLayout尺寸)
最终整数计数=getChildCount();
for(int i=0;i
将布局高度属性保留在xml中的自定义控件之外(假设您正在设置这些属性)会有什么不同吗?我在论坛上看到有人这样做,所以我会检查一下并与您联系。我觉得这与重写onLayout()函数有关,正如我之前提到的一样。很抱歉延迟!不,那没用!然而,我最终得到了想要的尺寸传递给孩子,但这导致孩子因为某种原因根本没有被画出来。也许我的方法在我试图做的事情上是错误的。因此,我将后退一步,阅读更多的文档,也许会找到更好的方法来解决这个问题。如果我找到了我想做的事情的解决方案,我会把它发回到这里,因为有一天可能会有人遇到类似的问题!我当然想知道如果你发现了怎么办!
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){

    int parent_width = MeasureSpec.getSize(widthMeasureSpec);
    int parent_height = MeasureSpec.getSize(heightMeasureSpec);

    Log.d("SHIP_VIEW", "ShipView.onMeasure : width = " + parent_width + ", height = " + parent_height);

    this.setMeasuredDimension(parent_width, parent_height);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
05-04 16:36:19.428: DEBUG/BOARD_VIEW(405): BoardView.onMeasure : width = 320, height = 320
05-04 16:36:19.939: DEBUG/BOARD_VIEW(405): BoardView.onSizeChanged : width = 320, height = 320
05-04 16:36:20.429: DEBUG/SHIP_VIEW(405): ShipView.onMeasure : width = 320, height = 430
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // let the super class handle calculations
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    // set again the dimensions, this time calculated as we want
    setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth() / 2);
    // this is required because the children keep the super class calculated dimensions (which will not work with the new MyFrameLayout sizes) 
    final int count = getChildCount();
    for (int i = 0; i < count; i++) {
        final View v = getChildAt(i);
        // this works because you set the dimensions of the ImageView to FILL_PARENT          
        v.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(),
                MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
                getMeasuredHeight(), MeasureSpec.EXACTLY));
    }
}