2012-07-05 25 views
11

Mam appwidget, który używa ListView. Stworzyłem klasę, która rozciąga RemoteViewsService:onGetViewFactory wywoływane tylko raz dla wielu widżetów

public class AppWidgetService extends RemoteViewsService { 
    @Override 
    public RemoteViewsFactory onGetViewFactory(Intent intent) { 
     return (new AppWidgetListFactory(this.getApplicationContext(), intent)); 
    } 
} 

W moim AppWidgetProvider wzywam następującą metodę dla każdej instancji widgetu (dla każdego appWidgetId)

private static void fillInList(RemoteViews widget, Context context, int appWidgetId) { 
    Intent intent = new Intent(context, AppWidgetService.class); 
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 
    widget.setRemoteAdapter(R.id.appwidget_listview, intent); 
} 

konstruktora AppWidgetListFactory

public AppWidgetListFactory(Context context, Intent intent) { 
    this.context = context; 
    appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); 

    System.out.println("New TVAPWLF for: " + appWidgetId); 
    trains = WidgetData.getInstance().widgetMap.get(appWidgetId); 
} 

Teraz problem polega na tym, żeMetoda jest wywoływana tak często, jak są instancje widgetu, ale metoda onGetViewFactory jest wywoływana tylko raz. W rezultacie wszystkie widżety wyświetlają te same dane.

Jak mogę to naprawić?

+0

czy mógłbyś dodać więcej kodu? działa, jeśli uczynisz metodę 'fillInList' nie statyczną? – Ronnie

+0

W moim przypadku intent.putExtra działa. Każda instancja otrzymuję prawidłowy identyfikator widgetu. –

Odpowiedz

24

Nie testowałem tego samodzielnie, ale patrząc na kod źródłowy dla RemoteViewsService.onBind(), uważam, że nie można po prostu zmieniać dodatków w swoim zamiarze w celu wykrycia, że ​​potrzebne jest nowe połączenie z Twoją metodą onGetViewFactory(), ponieważ wykorzystuje metodę Intent.filterEquals() dla porównania:

ustalenia, czy dwa intencje są takie same dla celów zamiarem rozdzielczości (filtrowania). Oznacza to, że ich działanie, dane, typ, klasa i kategorie są takie same. Nie porównuje to żadnych dodatkowych danych zawartych w intencjach.

Proponuję minięciu że potrzeba informacji (widget id?) Przez dane zamiarem zamiast, może coś takiego:

private static void fillInList(RemoteViews widget, Context context, int appWidgetId) { 
    Intent intent = new Intent(context, AppWidgetService.class); 
    intent.setData(Uri.fromParts("content", String.valueOf(appWidgetId), null)); 
    widget.setRemoteAdapter(R.id.appwidget_listview, intent); 
} 

i odpowiednio po stronie odbiorczej:

public TreinVerkeerAppWidgetListFactory(Context context, Intent intent) { 
    this.context = context; 
    appWidgetId = Integer.valueOf(intent.getData().getSchemeSpecificPart()); 

    System.out.println("New TVAPWLF for: " + appWidgetId); 
    trains = WidgetData.getInstance().widgetMap.get(appWidgetId); 
} 
+1

To naprawdę się udało, wielkie dzięki! – nhaarman

+0

@Joe możesz u proszę sprawdzić, jak to zrobić w moim kodzie, faktycznie zrobiłem zmiany, jak powiedziałeś, ale teraz się zawiesza. To jest mój kod http://pastie.org/7063960 i jest to logcat http://pastie.org/7063968 – AndroidDev

+0

@Anshuman Widzę problem na linii 36 na twoim pierwszym pastie: 'String.valueOf (appWidgetIds)' . Tutaj 'appWidgetIds' jest tablicą zamiast pojedynczej liczby całkowitej i tworzy niepoprawny URI w intencji (coś w rodzaju" [I @ 424b7d58 "zamiast" 2 "]. Czy zamiast tego chciałeś napisać 'String.valueOf (appWidgetIds [0])'? – Joe