2
votes

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

2
Its a default behaviour we cant judge how many times will calledkalyan pvs
@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 secondGishu
if you set to match parent there is no guarantee..match_parent will reduce the number of calls onlykalyan pvs
you need to do is check the position with 0 and if already loaded just skip itkalyan pvs

2 Answers

2
votes

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

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