Измерьте всю иерархию представлений перед рисованием в Android

У меня есть следующая иерархия представления:

     <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:gravity="center">
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/group_bg"
            android:gravity="center_vertical" 
            android:baselineAligned="false">
            <LinearLayout
                android:id="@+id/itemplace"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="5dp"
                android:layout_weight="1" >
                <include
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    layout="@layout/pin" />
            </LinearLayout>
            <FrameLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/arrow_black"/>
        </LinearLayout>
    </LinearLayout>

Мне нужно получить ширину элемента, прежде чем эта иерархия будет отрисовываться. Я не могу использовать OnLayoutChangeListener, потому что использую API уровня 7.

Я знаю, что я должен использовать методы Measure() и layout() для расчета размера моих представлений, но я не знаю, как это сделать.

Корневой вид в моей иерархии должен заполнять всю ширину экрана, поэтому ширина элемента зависит от размера родительского элемента, родительского заполнения и ширины FrameLayout.

Что я должен сделать, чтобы получить его ширину?


person Nik    schedule 11.07.2012    source источник
comment
представления возвращают 0 по ширине, когда вы пытаетесь получить длину?   -  person Carnal    schedule 11.07.2012


Ответы (2)


У меня есть способ получить ширину просмотра. Я могу получить его после измерения Android, но перед рисованием с помощью OnPreDrawListener в ViewTreeObserver:

    view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener()
    {
        @Override
        public boolean onPreDraw()
        {
            int avaliableWidth = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight();

            Log.d("width", String.valueOf(avaliableWidth));

            return true;
        }
    });

Из документации Android:

Метод обратного вызова, который будет вызываться перед отрисовкой дерева представления. К этому моменту все виды в дереве были измерены и получили кадр. Клиенты могут использовать это, чтобы настроить свои границы прокрутки или даже запросить новый макет до того, как произойдет рисование.

person Nik    schedule 11.07.2012
comment
но я также хочу иметь возможность самостоятельно вычислять ширину представления, используя методы Measure() и layout(). Как это делать? - person Nik; 11.07.2012

Это доступно с API 1:

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

    int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
}
person Carnal    schedule 11.07.2012
comment
У меня нет возможности изменить класс просмотра. У меня есть только объект View, возвращаемый из LayoutInflater. - person Nik; 11.07.2012
comment
Итак, у вас есть View view = ... и вам нужен witdh view? - person Carnal; 11.07.2012
comment
какой метод вы используете, когда ширина возвращает 0? - person Carnal; 11.07.2012
comment
Иерархию представлений из верхнего поста я надуваю из LayoutInflater и получаю объект View. Я знаю, что представление должно заполнять всю ширину экрана. Есть все, что у меня есть. Мне нужно получить ширину одного представления из иерархии, прежде чем она будет нарисована. Вот и вся задача. Один из способов сделать это я уже нашел — использование OnPreDrawListener. Но было бы здорово, если бы я знал другой способ получить ширину представления с помощью Measure() и layout(), как это делает Android. - person Nik; 11.07.2012
comment
Сначала я попытался вызвать функцию измерения (MeasureSpec.EXACTLY, MeasureSpec.EXACTLY); а затем я вызываю layout(0, 0, screenWidth, 100); В документации Android сказано, что с помощью этих двух методов Android вычисляет ширину и высоту представления перед рисованием. Но после использования этих методов view.getMeasuredWidth() возвращает 0. - person Nik; 11.07.2012
comment
Хорошо, нет, извините, я не могу помочь. Сначала подумал, что у тебя проблема в чем-то другом. - person Carnal; 11.07.2012