已回答
我有一个 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/