Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RemoteViewsFactory called getViewAt when empty dataset

I'm working on widget for my application which based on StackView and should display some items. Count of items can vary due to user actions - lets say it is some kind of favorites menu. I have implemented RemoteViewsFactory descendant to generate views for StackView:

public class StackRemoteViewsFactory implements RemoteViewsFactory {

    private List<Item> data;
    private Context context;

    public StackRemoteViewsFactory(Context context) {
        this.context = context;
        data = new DAO(context).getFavouriteCards();
    }

    @Override
    public void onDataSetChanged() {
        data = new DAO(context).getWidgetItems(); // refresh widget dataset
    }

    @Override
    public int getCount() {
            return data.size();
    }

    @Override
    public RemoteViews getViewAt(int position) {
        Item item = data.get(position);
        // this is my problem and will be explained below - 
        // here I'm getting IndexOutOfBoundsException, position = 0

            ...
    }
    // I have omitted other methods to avoid verbosity
}

All works well at first widget start - widget successfully displays empty view and all goes well. After I added some new element to favourites I notify AppWidgetManager immediately:

AppWidgetManager widgetManager = AppWidgetManager.getInstance(getActivity());
ComponentName component = new ComponentName(getActivity(), MyWidgetProvider.class);
int[] widgetIds = widgetManager.getAppWidgetIds(component);
widgetManager.notifyAppWidgetViewDataChanged(widgetIds, R.id.widgets_stack);  

All is well at this point - dataset successfully changed and I see my favorite item on widget. But when I remove my single element from favorites and favorites become empty (AppWidgetManager notified of course) I receive IndexOutOfBoundsException in my getViewAtMethod:

10-15 17:26:36.810: E/AndroidRuntime(30964): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0  

First of all I've checked what getCount() returns after onDataSetChanged() fires - it was 0. So I don't understand why RemoteViewsFactory calls getViewAt() when getCount() returns 0. As far as I understanding, RemoteViewFactory is like a usual adapter so this behavior is completely confusing me. So maybe my suggestions about it are incorrect and I doing something wrong?

UPDATE
Today I've changed my widget layout to use ListView instead of StackView while trying to fix some gui bug. And all works well at now. Further experiment shows that AdapterViewFlipper have same issue as StackView. As far as I understood there are some aspects working with AdapterViewAnimator descendants - can anyone confirm/refute my assumption?

like image 284
Viacheslav Avatar asked Oct 15 '13 15:10

Viacheslav


1 Answers

Same problem here. Since the solution is not yet coming (Android 4.4 here and it still happens), I think the best solution for now is basically a workaround to avoid the crash. Some devs will call it "hack"...

For now:

public RemoteViews getViewAt(int position) {

    if (position >= getCount())
            return getLoadingView();
    }
    //.... Rest of your normal configuration
}

Make sure you return a view properly on getLoadingView()

like image 130
khose Avatar answered Sep 21 '22 22:09

khose