I hope I understand your problem well, so I will try to explain in detail what is happening and how to handle clicking on the list items in the widget.
I assume that you already know that you must implement a class that:
extends BroadcastReceiver implements RemoteViewsService.RemoteViewsFactory
This will serve as an โadapterโ for your ListView widget (let's call it MyListRemoteViewFactory). If you want to handle clicks of items in a listView widget, you do the following things:
1) set setPendingIntentTemplate in your AppWidgetProvider class
2) set setOnClickFillInIntent to MyListRemoteViewFactory override getViewAt(int position)
NOW: By doing step 1), you can do something like:
final Intent serviceIntent = new Intent(context, MyListRemoteViewFactory.class); serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { views.setRemoteAdapter(R.id.widget_list_view, serviceIntent); } else { views.setRemoteAdapter(widgetId, R.id.widget_list_view, serviceIntent); }
You can put the code snippet above after each initialization of the RemoteViews object:
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.layout_widget);)
So now you have the ready pendingIntentTemplate. Another thing that needs to be done is to implement the onReceive method of the class so that you can decide what to do when the action occurred for the above case. So you will do something like:
@Override public void onReceive(Context context, Intent intent) {
[Damn, this will be a long time]
TAKING STEP 2) (from now on we are talking about implementations in the MyListRemoteViewFactory class)
If you need 3 different elements in the list, you must first add this method to MyListRemoteViewFactory (you still have to override it, the key should return the number of views):
@Override public int getViewTypeCount() { return 3; }
In getViewAt() you add your own logic based on what, you decide what to display depending on your position. Sort of:
@Override public RemoteViews getViewAt(int position) { if (position >= mItems.size()) { return null; } RemoteViews views; if (mItems.get(position).getViewType() == 0) { views = new RemoteViews(mContext.getPackageName(), R.layout.list_item_first); setUpItem(views, mItems.get(position), 1);
And the setUpItem method might look something like this:
private void setUpItem(RemoteViews views, MyObject object, int viewTypeKey) {
You might want to make sure that you also declare everything in the manifest file. You must declare your widgetprovider, your recipient for the list, and the service processing your Factoryclass. You should have something like:
<receiver android:name=".MyWidgetProvider" android:enabled="true" android:label="My awesome widget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_ENABLED" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_DELETED" /> <action android:name="android.appwidget.action.APPWIDGET_DISABLED" /> <action android:name="com.example.list.item.click"/> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider_info"/> </receiver> <service android:name=".WidgetRemoteViewsService" android:exported="false" android:permission="android.permission.BIND_REMOTEVIEWS"/> <receiver android:name=".ui.widget.MyListRemoteViewFactory" android:enabled="true" android:exported="false"> <intent-filter> <category android:name="android.intent.category.DEFAULT"/> <action android:name="com.example.refresh.remote.views"/> </intent-filter> </receiver>
By the way, the WidgetRemoteViewsService class should look like this:
public class WidgetNewsRemoteViewsService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new MyListRemoteViewFactory(); } }
I guess this is pretty much it. I hope I havenโt missed anything.