2

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

Gishu
  • 134,492
  • 47
  • 225
  • 308
  • Its a default behaviour we cant judge how many times will called – kalyan pvs Dec 09 '14 at 10:49
  • For more check here http://stackoverflow.com/questions/2618272/custom-listview-adapter-getview-method-being-called-multiple-times-and-in-no-co/2639159#2639159 – kalyan pvs Dec 09 '14 at 10:49
  • @kalyanpvs - I've already incorporated that nugget of not setting height=wrap_content in a list view item. I'm okay with it being called multiple times - what I'm seeing is multiple getView(pos=0) EVERY second – Gishu Dec 09 '14 at 10:54
  • if you set to match parent there is no guarantee..match_parent will reduce the number of calls only – kalyan pvs Dec 09 '14 at 10:58
  • you need to do is check the position with 0 and if already loaded just skip it – kalyan pvs Dec 09 '14 at 11:00
  • Please post your adapter, it's easier to help you when we have the whole picture. – einschnaehkeee Dec 09 '14 at 11:04
  • @einschnaehkeee - added adapter snippet. I need to have a reference to the latest view so that it can be redrawn on a async data update. – Gishu Dec 09 '14 at 11:45

2 Answers2

2

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"/>
Gishu
  • 134,492
  • 47
  • 225
  • 308
0

Sorry to post that here because I cannot comment for the moment.

I have the same issue than you and what I've done is delete your adapter and recreate it.
Do it step by step like :

  • create your adapter extends BaseAdapter (better than ArrayAdapter, see why there )
  • implement unimplement methods
  • add a list in your adapter as your datalist
  • edit getCount(), getItem(), getItemId()
  • edit getView() step by step (create view with LayoutInflater)
  • try your app with a 2-3 data in the list

If it works, complete your adapter as you want

Community
  • 1
  • 1
Sigvent
  • 297
  • 4
  • 17