RemoteViewsFactory called getViewAt when empty dataset
Asked Answered
K

1

11

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?

Kerouac answered 15/10, 2013 at 15:2 Comment(4)
I know this is pretty old, but I happen to run on the same issue. The data set is updated, but somehow the RemoteViewsFactory uses an old value of "getCount". Did you find something else out?Extravagant
@Extravagant Unfortunately I didn't find solution for this issue and reworked my widget to display single item and navigate through items using < and > buttons.Kerouac
The answer below solved this issue for me. It's a workaround but, a nice one :)Tyr
@BojanIlievski I don't mind to accept khose's answer and his solution really should work, but, generally my question was about explanation of source of this bug and behavior of AdapterViewAnimator.Kerouac
D
13

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

Dense answered 22/10, 2014 at 15:21 Comment(1)
This worked for me. It doesnt crash anymore (so far), and it seems to skip right over this case and show the "empty" widget view, which is what I wanted anyway. Though, I wonder if this is an issue with just StackViews?Lyckman

© 2022 - 2024 — McMap. All rights reserved.