测量GridView时可以避免使用getView()调用吗?

时间:2013-03-30 16:09:31

标签: android android-gridview

在我的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时,会导致测量通过,从而导致重新测量GridViewGridView依次多次调用我的适配器上的getView()来测量所有子视图。这是不必要的工作,因为(a)哪些儿童可见并没有改变,所以它已经拥有了所需的所有观点; (b)儿童意见均无法改变规模。

我知道ListViewGridView有许多技巧可以避免在简单的情况下工作,这似乎是他们可能有优化的特殊情况。我可以在GridView上设置一些内容,以帮助它意识到这里不需要再次呼叫getView()吗?或者,我可以向上移动堆栈并避免在进入和离开ActionMode时措施完全通过吗?为了清楚起见,我的适配器的行为是正确的,getView()调用不会导致我出现问题:我只是想让我的应用程序烧掉更少的周期。

NB 即使我将项目设置为固定宽度和高度,并使用以下内容替换GridView,也不会更改{{1}的数量调用(但它确实使我的getView()丑陋)。

Activity

3 个答案:

答案 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”。这取决于发生了什么。