Можно ли пропустить onMeasure при добавлении представления в группу представлений?

Отвечено

У меня есть RelativeLayout, в котором я добавляю представления динамически, когда пользователь прокручивает вертикально или горизонтально. Я свернул свой собственный ViewRecycler, поскольку потенциально существуют тысячи представлений, которые могут составить все, что можно прокручивать, но я показываю только 30 или около того в любое время. Представьте себе увеличенный вид календаря.

У меня возникают проблемы с производительностью, когда я добавляю представления, которые вот-вот появятся, onMeasure вызывается в RelativeLayout, каскадно вниз, чтобы onMeasure вызывается во всех его дочерних представлениях. У меня уже есть рассчитанный размер того, насколько большим будет RelativeLayout, и я установил его в LayoutParameters, поэтому измерение ViewGroup не требуется, равно как и повторное измерение уже добавленных представлений с их окончательным размером и новым добавленное представление не имеет отношения к этому представлению.

Простой пример, демонстрирующий проблему, - это добавление / удаление представления в RelativeLayout и наблюдение за вызовом onMeasure, несмотря на то, что это не влияет на размер RelativeLayout или положение объекта другие представления.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/shell"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
</LinearLayout>

MyActivity.java

public class MyActivity extends Activity
{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ViewGroup shell = (ViewGroup) findViewById(R.id.shell);

        final RelativeLayout container = new RelativeLayout(this) {
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                Log.d("MyActvity", "onMeasure called on map");
            }
        };
        container.setBackgroundColor(Color.rgb(255, 0, 0));
        ViewGroup.LayoutParams containerParams = new ViewGroup.LayoutParams(300, 300);

        final TextView childView = new TextView(this);
        childView.setBackgroundColor(Color.rgb(0, 255, 0));
        childView.setText("Child View");

        Button viewToggle = (Button) findViewById(R.id.button);
        viewToggle.setText("Add/Remove Child View");

        viewToggle.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                if (childView.getParent() == null) {
                    container.addView(childView, 400, 30);
                } else {
                   container.removeView(childView);
                }
            }
        });

        shell.addView(container, containerParams);
    }
}

Запустив это, вы увидите 2 начальных (ожидаемых) вызова onMeasure, а затем по одному при каждом добавлении / удалении представления, щелкнув кнопку . Это, очевидно, работает нормально, но вы можете видеть, где постоянные вызовы onMeasure при сложной структуре вложенных представлений могут стать проблематичными.

Есть ли рекомендуемый способ обойти эти вызовы onMeasure или, по крайней мере, onMeasure, вызывающий measureChildren?

10
задан Kelly Merrell 5 August 2011 в 18:42
поделиться