如何将onClick侦听器附加到应用程序窗口小部件上的列表视图项

时间:2017-02-14 19:15:41

标签: android listview android-appwidget

我想在listview的每个项目中添加一个onClick Listener,但我没有尝试过任何工作。

这是我的RemoteViewsFactory:

public class MyRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

    [...]

    public RemoteViews getViewAt(int position) {

        final RemoteViews remoteView = new RemoteViews(
            context.getPackageName(), R.layout.widget_item);

        [...]

        final Intent activityIntent = new Intent(context, ListActivity.class);
        activityIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        activityIntent.putExtra(AppWidgetManager.ACTION_APPWIDGET_PICK, position);
        PendingIntent pI = PendingIntent.getActivity(
            context, appWidgetId, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        remoteView.setOnClickPendingIntent(R.id.item_frame, pI);

        return remoteView;
    }
}

列表widget.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_frame"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical" >

    <include layout="@layout/picture_frame" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@+id/picframe"
        android:layout_margin="5dp"
        android:gravity="center"
        android:loopViews="true" />

</RelativeLayout>

列表item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_frame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_horizontal"
    android:layout_centerVertical="true" >

    <TextView
        android:id="@+id/date"
        style="@style/WidgetItemText" />

    <TextView
        android:id="@+id/name"
        style="@style/WidgetItemText" />

</LinearLayout>

如果我点击某个项目,则不会发生任何事情。

如果我将它直接挂在提供者列表视图中,那么意图就可以正常工作,但是我不能再滚动而不回复单个项目了。

3 个答案:

答案 0 :(得分:0)

official doc向个别项目添加行为部分说:

  

如使用AppWidgetProvider类中所述,通常使用setOnClickPendingIntent()来设置对象的单击行为 - 例如使按钮启动Activity。但是,单个集合项中的子视图不允许使用此方法(为了澄清,您可以使用setOnClickPendingIntent()在启动应用程序的Gmail应用程序窗口小部件中设置全局按钮,但不能在单个列表项上设置)。相反,要将单击行为添加到集合中的各个项目,请使用setOnClickFillInIntent()。这需要为您的集合视图设置待定的意图模板,然后通过RemoteViewsFactory为集合中的每个项目设置填充意图。

     

您的RemoteViewsFactory必须为集合中的每个项目设置填充意图。这使得可以区分给定项目的单独点击动作。然后将填充意图与PendingIntent模板结合使用,以确定单击该项目时将执行的最终意图。

您需要致电setOnClickFillInIntent以区分项目点击行为。像这样:

public RemoteViews getViewAt(int position) {

        final RemoteViews remoteView = new RemoteViews(
            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.
        Bundle extras = new Bundle();
        extras.putInt(YouWidgetProvider.EXTRA_ITEM, position);
        Intent fillInIntent = new Intent();
        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;
    }

同样应使用setPendingIntentTemplate代替setOnClickPendingIntent在集合上设置单个PendingIntent模板。在与onUpdate的子类相对应的AppWidgetProvider方法中设置待定意图,如下所示:

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // update each of the app widgets with the remote adapter
        for (int i = 0; i < appWidgetIds.length; ++i) {
            ...
            RemoteViews remoteView = new RemoteViews(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.
            Intent activityIntent = new Intent(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)));
            PendingIntent pendingIntent = 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);
    }

答案 1 :(得分:0)

使用此library(tibble) library(tidyr) enframe(summary(rt1$state)) %>% unnest(c(value)) ,您可以为窗口小部件中的每个ListView项目添加onClick,并可以传递窗口小部件项目中的数据,以使用该数据开始新的Code

在窗口小部件中,无法为列表或堆栈中的每个项目创建单独的Activity。为此,我们必须为创建的每个列表项在Intent中使用数据创建Intent

这是WidgetService。我使用要发送的其他数据创建了WidgetService.java。 然后,选择该功能中的哪个UI元素将触发new Intent

views.setOnClickFillInIntent

这是 @Override public RemoteViews getViewAt(int position) { final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_item); //Open Post Intent fillIntent = new Intent(); fillIntent.putExtra( "keyData", position); views.setOnClickFillInIntent(R.id.tvTitle, fillIntent); ..... }

ExampleWidgetProvider.java

我们已经为每个public static final String ACTION_POST = "actionPost"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // update each of the app widgets with the remote adapter for (int i = 0; i < appWidgetIds.length; ++i) { ... RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.listview); ... Intent postIntent = new Intent(context, ExampleWidgetProvider.class); postIntent.setAction(ACTION_POST); PendingIntent postPendingIntent = 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); } 项目创建了OnClick,它将把意图发送给该ListView。现在,我们必须读取ExampleWidgetProvider.javaIntent发送给每个列表项的信息。

为此,我们必须在WidgetService.java中创建另一个函数。

ExampleWidgetProvider.java

答案 2 :(得分:-2)

您可以尝试类似的东西,其中position是列表视图中项目的索引

ListView lv = getListView();
setContentView(lv);
lv.setOnItemClickListener(new OnItemClickListener()
{
@Override 
public void onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)
{ 
    Toast.makeText(SuggestionActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});