在我的Activity
中,我有一个GridView
从这个XML布局中膨胀:
<GridView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="@dimen/thumbnail_size"
android:gravity="fill"
android:horizontalSpacing="16dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="16dp" />
其中的项目为RelativeLayout
个,每个都设置为固定高度。在分析我的Activity
时,我注意到当我输入ActionMode
时,会导致测量通过,从而导致重新测量GridView
。 GridView
依次多次调用我的适配器上的getView()
来测量所有子视图。这是不必要的工作,因为(a)哪些儿童可见并没有改变,所以它已经拥有了所需的所有观点; (b)儿童意见均无法改变规模。
我知道ListView
和GridView
有许多技巧可以避免在简单的情况下工作,这似乎是他们可能有优化的特殊情况。我可以在GridView
上设置一些内容,以帮助它意识到这里不需要再次呼叫getView()
吗?或者,我可以向上移动堆栈并避免在进入和离开ActionMode
时措施完全通过吗?为了清楚起见,我的适配器的行为是正确的,getView()
调用不会导致我出现问题:我只是想让我的应用程序烧掉更少的周期。
NB 即使我将项目设置为固定宽度和高度,并使用以下内容替换GridView
,也不会更改{{1}的数量调用(但它确实使我的getView()
丑陋)。
Activity
答案 0 :(得分:2)
使用ListView而不是GridView。查看实现(API 16):
ListView.onMeasure(...) {
...
if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
heightMode == MeasureSpec.UNSPECIFIED)) {
final View child = obtainView(0, mIsScrap);
...
}
和
GridView.onMeasure(...) {
...
final int count = mItemCount;
if (count > 0) {
final View child = obtainView(0, mIsScrap);
...
}
它看起来像一个bug。
答案 1 :(得分:2)
使GridView
表现得更好的一些通用方法:
最重要的是:尽快让getView()
尽快。例如,将任何IO或重计算远离UI线程。
出于测量/布局目的,似乎总是请求位置0中的视图。您可以自己缓存此视图,以便在getView()
。
删除任何可能的LinearLayout
layout_weight
,因为每个嵌套级别都会使所需的度量/布局次数增加一倍。
答案 2 :(得分:1)
下一个解决方案如何:
在适配器中添加一个标志,一旦设置,在getView()中,它将返回convertView而不做任何更改。
如果用户触摸了listView,请将该标志设置为false。
如果某些内容导致listView更改其大小(例如actionMode),请将其设置为true。
编辑:您必须检查所有内容是否正常 - 每个视图仍然显示之前显示的相同项目。它不只是“返回convertView”。这取决于发生了什么。