2017-02-14 14 views
1

Мне нравится добавлять onClick Listener в каждый элемент моего списка, но ничто из того, что я пробовал, не работает.как подключить прослушиватель onClick к элементу списка в виджетах приложения

Вот мой 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> 

Если я нажимаю элемент, ничего не произойдет.

Умышленное намерение работает правильно, если я вися его в провайдере непосредственно в списке, но тогда я больше не могу прокручивать и не отвечать на отдельные элементы.

ответ

1

Раздел Добавление поведения к отдельным пунктам в 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); 
    } 
0

Вы могли бы попробовать что-то подобное, где позиция является индексом вашего элемента в ListView

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(); 
} 
}); 
+0

Hi; где я должен это делать? RemoteViewsFactory не имеет метода getListView(). https://developer.android.com/reference/android/widget/RemoteViewsService.RemoteViewsFactory.html – Wookiee

+0

Вы можете сделать: 'ListView l = (ListView) findViewById (R.layout.file_that_you_inflate);' и затем 'l.setOnItemClickListener (новый OnItemClickListener() { @Override общественные недействительный onItemClick (AdapterView arg0, Вид arg1, внутр позиция, длинная arg3) { Toast.makeText (SuggestionActivity.this, "" + позиция, Toast.LENGTH_SHORT) .show(); } }); ' – mychemicalro

+0

Для listView у вас также есть адаптер. – mychemicalro