android - 给ViewGroup添加View可以跳过onMeasure吗?

标签 android layout viewgroup

已回答

我有一个 RelativeLayout,当用户垂直或水平滚动时,我会在其中动态添加 View 。我推出了自己的 ViewRecycler,因为可能有数千个 View 可以组成所有可以滚动的内容,但我每次只显示 30 个左右。想想日历的放大 View 。

当我添加即将看到的 View 时,我遇到了性能问题,在 RelativeLayout 上调用 onMeasure 级联到 onMeasure 在它的所有 subview 上调用。我已经计算出 RelativeLayout 的大小,并将其设置在 LayoutParameters 上,因此不需要测量 ViewGroup,也不需要重新测量已经添加的 Views 及其最终大小和新的添加的 View 与这些 View 无关。

演示该问题的简单示例是向 RelativeLayout 添加/删除 View 并观察 onMeasure 被调用,尽管它不会影响 RelativeLayout 的大小或其他 View 的位置。

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

运行此程序,您会看到对 onMeasure 的 2 次初始(预期)调用,然后每次通过单击按钮添加/删除 View 时调用一次。这显然运行良好,但您可以看到,当您拥有复杂的嵌套 View 布局时,不断调用 onMeasure 可能会出现问题。

是否有推荐的方法来绕过这些 onMeasure 调用或至少 onMeasure 调用 measureChildren?

最佳答案

我没有滚动自己的布局管理器(我将来可能仍会这样做),而是将 onMeasure 更改为:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int count = getChildCount();
    for (int i = 0; count > i; i++) {
        View v = getChildAt(i);

        if (v.getVisibility() != GONE) {
            if (v.getMeasuredWidth() <= 0 || v.getMeasuredHeight() <= 0) {
                measureChild(v,
                    MeasureSpec.makeMeasureSpec(v.getLayoutParams().width,
                        MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(v.getLayoutParams().height,
                        MeasureSpec.AT_MOST));
            }
        }
    }

    setMeasuredDimension(resolveSize(staticContainerWidth, widthMeasureSpec),
        resolveSize(staticContainerHeight, heightMeasureSpec));
}

... 并为容器添加了一个 sudo 硬编码的高度和宽度作为变量。将这些设置为您期望的超出了此解决方案的范围。

int staticContainerHeight = 300;
int staticContainerWidth = 300;

关于android - 给ViewGroup添加View可以跳过onMeasure吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6298827/

相关文章:

android - 将按钮背景颜色反转为 Android SDK 中的默认颜色

c# - Xamarin Forms - 将光标更改为等待光标

android - 在 Android 4.0 上设计(Tab 布局)

javascript - vbox内的extjs布局滚动

html - 无法强制文本换行

android - 如何将 ViewGroup 对齐到屏幕底部

Android Studio 当我在应用程序中添加 Java 模块时会出错

android - 主题 ActionBarSherlock 给出 api 级错误

java - toolbar.getChildCount() 返回 0

android - 在什么时候创建了所有 Viewgroup 子级并准备好设置一些初始属性?