android - 自定义适配器 getView 方法在位置 0 处频繁调用

标签 android gridview adapter

我有一个绑定(bind)到自定义 ArrayAdapter 派生的 GridView。

<GridView
        android:id="@+id/measurements"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="100dp"
        android:gravity="center"


        android:numColumns="auto_fit"
        android:orientation="horizontal"
        android:stretchMode="columnWidth"/>

每个项目都扩展到一个 View (我使用 View 回收模式),如下所示。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:orientation="vertical" android:background="#8800CC00">

    <TextView android:id="@+id/widget_view_id" 
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView android:id="@+id/widget_status" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        android:layout_gravity="center"/>
    <TextView android:id="@+id/widget_timestamp" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_gravity="center"/>

</LinearLayout>

我有一个 HandlerThread,然后它定期用数据值填充每个小部件。

但是我看到第一个 View 是“卡住”的 - 没有更新。 LogCat 向我展示了这一点 调用适配器#getView(position = 0) 几乎就像在循环中一样。

public class WidgetAdapter extends ArrayAdapter<DataItem>
    {
        private DataServiceProxy _dataServiceProxy;

        public WidgetAdapter(Context context, List<DataItem> objects, DataServiceProxy dataServiceProxy) {
            super(context, 0, objects);
            _dataServiceProxy = dataServiceProxy;

        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

                View view;
                DataItem dataItem = getItem(position);

                if (convertView == null)
                {
                    view = getActivity().getLayoutInflater().inflate(R.layout.item_dataItem, parent, false);
                    view.setPadding(8, 8, 8, 8);
                }
                else
                {
                    view = convertView;
                    int oldId = ((Integer)view.getTag()).intValue();
                    _dataServiceProxy.removeListener(WidgetView.getFor(view), oldId);
                }

                ((TextView) view.findViewById(R.id.widget_view_id)).setText("View# " + dataItem.id);
                view.setTag(Integer.valueOf(dataItem.id));

                _dataServiceProxy.addListener(new WidgetView(view, dataItem), dataItem.id);
                return view;
        }
...     

上次发生这种情况时,我已经修复了它 - 通过在所有 GridView 项模板 subview 中将 height='wrap_content' 替换为 'match_parent' 。 (引用:Romain Guy 的 Google IO 演讲)

但它又回来了,让我发疯......

当我在 getView(pos=0) 设置断点时调用堆栈显示

Thread [<1> main] (Suspended (breakpoint at line 255 in WidgetFragment$WidgetAdapter)) WidgetFragment$WidgetAdapter.getView(int, View, ViewGroup) line: 255 GridView(AbsListView).obtainView(int, boolean[]) line: 2456 GridView.onMeasure(int, int) line: 1030 GridView(View).measure(int, int) line: 15562
RelativeLayout.measureChildHorizontal(View, RelativeLayout$LayoutParams, int, int) line: 617
RelativeLayout.onMeasure(int, int) line: 399
RelativeLayout(View).measure(int, int) line: 15562
FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5109 FrameLayout.onMeasure(int, int) line: 310
FrameLayout(View).measure(int, int) line: 15562 FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5109 FrameLayout.onMeasure(int, int) line: 310
FrameLayout(View).measure(int, int) line: 15562 LinearLayout.measureVertical(int, int) line: 833
LinearLayout.onMeasure(int, int) line: 574
LinearLayout(View).measure(int, int) line: 15562
PhoneWindow$DecorView(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5109

最佳答案

找到了修复方法 - 但不确定原因。

通过排除过程,我最终知道 getView(pos=0) 调用仅在 HandlerThread 更新空 TextView 后才开始 ping。我仔细检查了线程 ID,确认 UI 正在正确的线程上更新。

然后我开始调整 TextView 的属性,以下组合使症状消失,第一个 View 现在可以正确更新。基本上高度需要硬编码,match_parent有上述问题,而wrap_content对于android来说是禁忌

<TextView android:id="@+id/widget_status" 
        android:layout_width="match_parent" 
        android:layout_height="20dp"
        android:gravity="center"/>

关于android - 自定义适配器 getView 方法在位置 0 处频繁调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27377046/

相关文章:

java - Android java if 语句不适用于 OnClickListener

android - 通过蓝牙流复制后损坏的音频文件

java - 采用字符串的不可见 ActiveX

安卓初学者 : Adapter for simple view or direct DB query?

java - 为什么adapter.add()会创建无限循环并崩溃?

Android Studio 无法正确呈现预览

android - 在 Android 的 AchartEngine 中,条形颜色对于 0 值可见

android - 在 Kotlin 中构建 GridView 时无法传递上下文

php - yii2 中 gridview 中的图像

c# - GridView 和列表<>