自定义适配器getView方法与位置0频繁调用 [英] Custom Adapter getView method called frequently with position 0

查看:261
本文介绍了自定义适配器getView方法与位置0频繁调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有绑定到自定义ArrayAdapter推导的GridView。

 < GridView控件
        机器人:ID =@ + ID /测量
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:columnWidth时=100dp
        机器人:比重=中心
        机器人:为numColumns =auto_fit
        机器人:方向=横向
        机器人:stretchMode =columnWidth中/>

每个项目膨胀到一个视图(我用的视图模式再造)如下图所示。

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直的android:背景=#8800CC00>    < TextView的机器人:ID =@ + ID / widget_view_id
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent/>    < TextView的机器人:ID =@ + ID / widget_status
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:layout_gravity =中心/>
    < TextView的机器人:ID =@ + ID / widget_timestamp
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:layout_gravity =中心/>< / LinearLayout中>

我有一个HandlerThread的填充,然后定期与数据值每个插件。

不过,我看到的第一个观点是冻结 - 没有更新。 LogCat中让我发现,
适配器#getView(位置= 0)被调用几乎一样,如果它是在一个循环。

 公共类WidgetAdapter扩展ArrayAdapter<&DataItem的GT;
    {
        私人DataServiceProxy _dataServiceProxy;        公共WidgetAdapter(上下文的背景下,列表与LT; D​​ataItem的>对象,DataServiceProxy dataServiceProxy){
            超(背景下,0,对象);
            _dataServiceProxy = dataServiceProxy;        }
        @覆盖
        公共查看getView(INT位置,查看convertView,父母的ViewGroup){                查看视图。
                的DataItem的DataItem =的getItem(位置);                如果(convertView == NULL)
                {
                    鉴于= getActivity()getLayoutInflater()膨胀(R.layout.item_dataItem,父母,假)。
                    view.setPadding(8,8,8,8);
                }
                其他
                {
                    鉴于= convertView;
                    。INT OLDID =((整数)view.getTag())的intValue();
                    _dataServiceProxy.removeListener(WidgetView.getFor(视图),OLDID);
                }                ((的TextView)view.findViewById(R.id.widget_view_id))的setText(观#+ dataItem.id)。
                view.setTag(Integer.valueOf(dataItem.id));                _dataServiceProxy.addListener(新WidgetView(查看,DataItem的),dataItem.id);
                返回视图。
        }
...

上一次发生这种情况,我已经固定它 - 在所有的GridView项模板子视图替换高度='WRAP_CONTENT'到'match_parent。 (参考:罗曼盖伊的谷歌IO谈话)

但它的背部和我发疯...

当我在getView设置一个断点调用堆栈(POS = 0)显示


  

主题[< 1>主要在(吊(断点线255
  WidgetFragment $ WidgetAdapter))WidgetFragment $ WidgetAdapter.getView(INT,查看,
  ViewGroup中)线:255 GridView控件(AbsListView).obtainView(INT,
  布尔[])行:2456 GridView.onMeasure(INT,INT)行:1030
    GridView控件(视图).measure(INT,INT)线:15562结果
    RelativeLayout.measureChildHorizo​​ntal(查看,
  RelativeLayout的$的LayoutParams,INT,INT)线:617结果
    RelativeLayout.onMeasure(INT,INT)线:399结果
    的RelativeLayout(查看).measure(INT,INT)线:15562结果
    的FrameLayout(ViewGroup中).measureChildWithMargins(查看,INT,INT,INT,
  INT)行:5109 FrameLayout.onMeasure(INT,INT)线:310结果
    的FrameLayout(查看).measure(INT,INT)线:15562
    的FrameLayout(ViewGroup中).measureChildWithMargins(查看,INT,INT,INT,
  INT)行:5109 FrameLayout.onMeasure(INT,INT)线:310结果
    的FrameLayout(查看).measure(INT,INT)线:15562
    LinearLayout.measureVertical(INT,INT)线:833结果
    LinearLayout.onMeasure(INT,INT)线:574结果
    的LinearLayout(查看).measure(INT,INT)线:15562结果
    PhoneWindow $ DecorView(ViewGroup中).measureChildWithMargins(查看,INT,
  INT,INT,INT)行:5109



解决方案

找到了解决 - 不知道的道理,虽然

通过排除法,我结束了明知getView(POS = 0)调用启动空的TextView被HandlerThread更新后才能查验。我仔细检查了该UI正在正确的线程上更新了线程ID。

然后我开始扭捏的TextView的属性和下面的结合使症状消失,第一个视图现在可以正确更新。基本上的高度必须是硬codeD ,match_parent有上述问题,并WRAP_CONTENT是一个没有没有按照Android的家伙

 < TextView的机器人:ID =@ + ID / widget_status
        机器人:layout_width =match_parent
        机器人:layout_height =20dp
        机器人:比重=中心/>

I have a GridView bound to a custom ArrayAdapter derivation.

<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"/>

Each item is inflated to a view (I use the view-recycling pattern) as shown below.

<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>

I have a HandlerThread that then populates each widget with data values on a periodic basis.

However I see that the first view is 'frozen' - no updates. LogCat shows me that adapter#getView(position = 0) is being called almost as if it's in a loop.

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;
        }
...     

The last time this happened, I had fixed it - by replacing height='wrap_content' to 'match_parent' in all GridView item template sub-views. (Ref:Romain Guy's Google IO talk )

But it's back and driving me nuts...

Call stack when I set a breakpoint at the getView(pos=0) shows

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

解决方案

Found a fix - not sure about the reasoning though.

By process of elimination, I ended up with knowing that the getView(pos=0) calls start pinging only after the empty textview is updated by the HandlerThread. I double checked the Thread Ids that the UI is being updated on the right thread.

I then started tweaking the attributes of the textview and the following combination makes the symptoms go away and the first view is updating correctly now. Basically the height needs to be hard coded, match_parent has the above mentioned problem and wrap_content is a no-no as per the android guys

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

这篇关于自定义适配器getView方法与位置0频繁调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆