ViewFlipper in app widgets
Asked Answered
R

1

6

I'm playing around building a new widget and was looking at the Android app widget documentation, in particular the section on which widget classes were supported. I noticed that ViewFlipper is supported, but I'm struggling to find any examples on how to use one in a home screen widget. In particular, I'm wondering if its possible to manually trigger swapping views. In an activity this looks relatively straightforward, one example being hooking up the onclick listener of a button to call the showNext() of the flipper.

The RemoteViews object has showNext and showPrevious methods but I'm not sure I understand how to hook them up to an event fired from the user interacting with the widget. Can anyone provide examples of when these methods might be called?

It looks like buttons in widgets can only be wired up to intents rather than code to exercise the flipper. If this restriction is true, then is the only use of a view flipper in an app widget for auto flipping of views?

Reduplication answered 26/11, 2011 at 23:33 Comment(0)
L
8

Say you have 2 buttons: LEFT and RIGHT. First you would attach pending intent to each (here it's triggered from Service#onStart:

@Override
public void onStart(Intent intent, int startId) {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
    int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
    // add listeners for every widget registered
    for (int widgetId : allWidgetIds) {
        addClickListeners(appWidgetManager, widgetId, root);
    }
    stopSelf();
}

protected void addClickListeners(AppWidgetManager appWidgetManager, int widgetId, RemoteViews root) {
    root.setOnClickPendingIntent(R.id.left, getNavigationIntent(widgetId, R.id.left));
    root.setOnClickPendingIntent(R.id.right, getNavigationIntent(widgetId, R.id.right));
}

protected PendingIntent getNavigationIntent(int widgetId, final int id) {
    Intent clickIntent = new Intent(this, WidgetProvider.class);
    clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
    clickIntent.putExtra(TRIGGER, id);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    return pendingIntent;
}

Then, in AppWidgetProvider do

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Bundle extras = intent.getExtras();
    Integer id = (Integer) (extras == null ? null : extras.get(TRIGGER));
    if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) && id != null) {
        int widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
        onNavigate(context, widgetId, id); 
    } else {
        super.onReceive(context, intent);
    }
}


protected void onNavigate(Context context, Integer widgetId, Integer id) {  
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews root = new RemoteViews(context.getPackageName(), R.layout.app_widget);
    if (id == R.id.left) {
        root.showPrevious(R.id.scroll);
    } else {
        root.showNext(R.id.scroll);            
    }
    appWidgetManager.updateAppWidget(widgetId, root);
}

This should do it. Now the problem is - this will only work in API 11+ and I just found the hard way that root.setInt(R.id.scroll, "setDisplayedChild", pos) will not work in API 7.

Latimore answered 28/12, 2011 at 20:27 Comment(4)
Fantastic answer, thank you very much. Unfortunately my app is API 7+, so I'll have to wait some time before I can try the above, but it opens up some really interesting possibilities with my widgets. Thanks for sharing.Reduplication
I had to deal with the same issue and I ended up just having single LinearLayout with TextView and ImageView and then when you detect the navigation event simply change values. No fancy sliding effects but good enoughLatimore
When I add animation on it, my app widget doesn't work. Is there a way to make an home app widget flip work with animations? <AdapterViewFlipper android:id="@+id/adapter_view_flipper" android:layout_width="fill_parent" android:layout_height="100dp" android:inAnimation="@android:anim/fade_in" android:outAnimation="@android:anim/fade_out" />Dives
@Latimore Do you known how i can add dynamically add ImageView in side ViewFlipper that use in my Widget Layout?Wicklow

© 2022 - 2024 — McMap. All rights reserved.