Skip to content Skip to sidebar Skip to footer

How Attach A Onclick Listener To An Listview Item On An App Widget

I like to add a onClick Listener to every item of my listview, but nothing what I have tried work. Here is my RemoteViewsFactory: public class MyRemoteViewsFactory implements Remot

Solution 1:

The section of Adding behavior to individual items in the official doc say:

As described in Using the AppWidgetProvider Class, you normally use setOnClickPendingIntent() to set an object's click behavior—such as to cause a button to launch an Activity. But this approach is not allowed for child views in an individual collection item (to clarify, you could use setOnClickPendingIntent() to set up a global button in the Gmail app widget that launches the app, for example, but not on the individual list items). Instead, to add click behavior to individual items in a collection, you use setOnClickFillInIntent(). This entails setting up up a pending intent template for your collection view, and then setting a fill-in intent on each item in the collection via your RemoteViewsFactory.

Your RemoteViewsFactory must set a fill-in intent on each item in the collection. This makes it possible to distinguish the individual on-click action of a given item. The fill-in intent is then combined with the PendingIntent template in order to determine the final intent that will be executed when the item is clicked.

Your need to call setOnClickFillInIntent to differentiate the item on-click behavior. Something like this:

public RemoteViews getViewAt(int position) {

        finalRemoteViewsremoteView=newRemoteViews(
            context.getPackageName(), R.layout.widget_item);

        [...]

        // Next, set a fill-intent, which will be used to fill in the pending intent template// that is set on the collection view in StackWidgetProvider.Bundleextras=newBundle();
        extras.putInt(YouWidgetProvider.EXTRA_ITEM, position);
        IntentfillInIntent=newIntent();
        fillInIntent.putExtras(extras);
        // Make it possible to distinguish the individual on-click// action of a given item
        remoteView.setOnClickFillInIntent(R.id.item_frame, fillInIntent);


        return remoteView;
    }

Also setPendingIntentTemplate should be use instead of setOnClickPendingIntent to set a single PendingIntent template on the collection. Set the pending intent in onUpdate method corresponding to you subclass of AppWidgetProvider, something like this:

@OverridepublicvoidonUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // update each of the app widgets with the remote adapterfor (inti=0; i < appWidgetIds.length; ++i) {
            ...
            RemoteViewsremoteView=newRemoteViews(context.getPackageName(), 
                R.layout.widget_item);
            ...

            // This section makes it possible for items to have individualized behavior.// It does this by setting up a pending intent template. Individuals items of a collection// cannot set up their own pending intents. Instead, the collection as a whole sets// up a pending intent template, and the individual items set a fillInIntent// to create unique behavior on an item-by-item basis.IntentactivityIntent=newIntent(context, ListActivity.class);
            // Set the action for the intent.// When the user touches a particular view.
            activityIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
            activityIntent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
            PendingIntentpendingIntent= PendingIntent.getActivity(context, appWidgetIds[i], 
                activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteView.setPendingIntentTemplate(R.id.stack_view, pendingIntent);

            appWidgetManager.updateAppWidget(appWidgetIds[i], remoteView);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

Solution 2:

With this Code you can add onClick for every ListView item in Widget and can pass data from widget item to start new Activity with this data.

In the widgets, you can not create an individual Intent for every item in the list or stack. In order to do this, we have to create Intent with data in WidgetService for every list item that we create.

This is WidgetService.java. I created a new Intent with Extra data I want to send. Then I choose which UI element will be a trigger views.setOnClickFillInIntent in this function.

@Overridepublic RemoteViews getViewAt(int position) {
        finalRemoteViewsviews=newRemoteViews(context.getPackageName(), R.layout.widget_item);

        //Open PostIntentfillIntent=newIntent();
        fillIntent.putExtra(
                "keyData", position);
        views.setOnClickFillInIntent(R.id.tvTitle, fillIntent);

    .....
   }

This is ExampleWidgetProvider.java

publicstaticfinalStringACTION_POST="actionPost";

@OverridepublicvoidonUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // update each of the app widgets with the remote adapterfor (inti=0; i < appWidgetIds.length; ++i) {
        ...
        RemoteViewsremoteView=newRemoteViews(context.getPackageName(), 
            R.layout.listview);


        ...


        IntentpostIntent=newIntent(context, ExampleWidgetProvider.class);
        postIntent.setAction(ACTION_POST);
        PendingIntentpostPendingIntent= PendingIntent.getBroadcast(context,
                0, postIntent, 0);


        ...


            activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteView.setPendingIntentTemplate(R.id.listview, postPendingIntent );

        appWidgetManager.updateAppWidget(appWidgetIds[i], remoteView);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

We have already created OnClick for every ListView item which will send intent to itself to this ExampleWidgetProvider.java. Now we have to read the information that we send by Intent in WidgetService.java for every List Item.

To do this we have to create another function in ExampleWidgetProvider.java.

@OverridepublicvoidonReceive(Context context, Intent intent) {
        if(ACTION_POST.equals(intent.getAction())){

            //Passed info from WidgetService.javaString data= intent.getStringExtra("keyData");

            // If you want to open new activity with this data you can do itIntent intentPOST = newIntent(context,
                    MainActivity.class).putExtra(
                    "keyData", data);
            intentPOST.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity (intentPOST);


            //Show informationToast.makeText(context,
                    data,
                   Toast.LENGTH_LONG).show();
        }
        super.onReceive(context, intent);
    }

Solution 3:

You could try something like that, where position is the index of your item in the listview

ListViewlv= getListView();
setContentView(lv);
lv.setOnItemClickListener(newOnItemClickListener()
{
@OverridepublicvoidonItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)
{ 
    Toast.makeText(SuggestionActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});

Post a Comment for "How Attach A Onclick Listener To An Listview Item On An App Widget"