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

时间:2011-05-04 15:51:04

标签: 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: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>

我希望BoardView只占用屏幕的某个部分,即视图应该是我想在此视图中创建的内容的大小。在这种情况下,它是2D板。这是通过从扩展View覆盖onMeasure()方法来完成的。视图的宽度保持不变,但高度与宽度相同,给出了完美的正方形。

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

    int parent_width = MeasureSpec.getSize(widthMeasureSpec);
    this.setMeasuredDimension(parent_width, parent_width);
    Log.d("BOARD_VIEW", "BoardView.onMeasure : width = " + this.getMeasuredWidth() + ", height = " 
            + this.getMeasuredHeight());
}

我通过覆盖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中设定的尺寸。我以类似的方式通过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()方法似乎被多次调用但所有值都相同,所以我不打算显示多个日志,因为值都是相同的):

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

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

对于这种类型的游戏来说,这是否正确的做法是绝对值得讨论,但无论哪种方式我都想知道它是如何完成的(我认为它可以......?)。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

相信这个question

@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));
    }
}
相关问题