Android: изменение пользовательских видов.Размер родительского элемента изменен, но изменения ширины / высоты не переданы дочернему виду - PullRequest
8 голосов
/ 04 мая 2011

В настоящее время я пытаюсь сделать игру, основанную на настольной игре линейного корабля старой школы, с использованием 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 доской. Это делается путем переопределения метода onMeasure () из расширения View. Ширина вида остается такой же, но высота имеет то же значение, что и ширина, что дает идеальный квадрат.

@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. Я проверяю размеры ShipView с помощью метода onMeasure () аналогичным образом.

@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 (), ничего не изменилось и игнорирует ограничения размеров, которые я установил. Я не уверен, имеет ли это какое-либо отношение к RelativeLayout в ShipView. Должен ли я установить LayoutParams для этого, так как они изменились? Я думал, что если вы измените размер представления родительского объекта, он будет передан дочерним элементам.

Является ли это правильным способом сделать это для игры такого рода, безусловно, подлежит обсуждению, но в любом случае я хотел бы знать, как это можно сделать (я полагаю, что это возможно ...?). Любая помощь будет высоко ценится.

1 Ответ

1 голос
/ 14 декабря 2015

Кредит на этот вопрос :

@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));
    }
}
...