Ответил
У меня есть RelativeLayout, где я динамически добавляю представления, когда пользователь прокручивает по вертикали или по горизонтали. Я прокрутил свой собственный ViewRecycler, так как потенциально есть тысячи представлений, которые могли бы составить все, что можно прокручивать, но я показываю только 30 или около того в любое время. Подумайте о увеличенном виде календаря.
У меня возникают проблемы с производительностью, когда я добавляю представления, которые должны быть видны, onMeasure вызывается для RelativeLayout, каскадно переходящего к onMeasure, вызываемому для всех его дочерних представлений. У меня уже есть рассчитанный размер того, насколько большим будет RelativeLayout, и я установил его на свой LayoutParameters, так что измерение ViewGroup не требуется, равно как и повторное измерение видов, которые уже были добавлены, с их окончательным размером и новым добавленное представление не имеет отношения к этим представлениям.
Простым примером, демонстрирующим проблему, является добавление / удаление View для 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?