2012-03-22 15 views
6

AKTUALIZACJA: Otworzyłem problem, proszę gwiazdkę, jeśli masz ten sam problem. http://code.google.com/p/android/issues/detail?id=28016Zduplikowane elementy w widgecie GridView

Mam appwidget z gridview na nim.

Kiedy zaczynam dodawać elementy do mojego widżetu, prawie zawsze otrzymuję pierwsze elementy pokazane dwa razy (zamiast pokazywania pierwszego przedmiotu i drugiego przedmiotu).

Jeśli zrobię intencję aktualizacji widgetu, problem zostanie naprawiony i nigdy się nie zwróci (zakładając, że mam już dwa elementy w moim widoku siatki).

Ale zawsze tak się stanie, gdy pierwsze dwa elementy zostaną dodane.

Wszelkie pomysły, jakie mogą być?

AKTUALIZACJA: Właśnie zauważyłem, że zawsze dzieje się, gdy nowy element zostanie dodany do GridView. Jeśli odświeżę widget bez dodawania nowego elementu, to działa poprawnie.

Inną rzeczą, którą zobaczyłem, jest to, że metoda getViewAt jest zawsze wywoływana dwukrotnie dla pierwszego przedmiotu (pozycja zero). Może jest to powiązane?

Śledziłem próbkę tutaj dość ściśle: http://developer.android.com/resources/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.html

Oto moja RemoteViewsService, myślę, że jest to istotny element, ale nie jestem pewien, rzeczywiście. Co jeszcze może na to wpłynąć?

pakiet com.manor.TestApp;

klasy publicznej TestAppRemoteViewsService rozciąga RemoteViewsService {

@Override
publicznego RemoteViewsFactory onGetViewFactory (intent zamiaru) {
zwrotnego nowy TestAppViewsFactory (this.getApplicationContext(), konwersji); }

}

klasy TestAppViewsFactory realizuje RemoteViewsService.RemoteViewsFactory {

prywatny kontekst mContext;

// private int mAppWidgetId;

prywatny TestDb mDb = null;

int prywatna mCount = 0;

prywatny ciąg [] mData;

public TestAppViewsFactory (Kontekst kontekstowy, intencja) { mContext = kontekst;

/*mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
      AppWidgetManager.INVALID_APPWIDGET_ID);*/ 

}

@Override public void onCreate() {

mDb = new TestDb(mContext); 

    mDb.open(false); 

}

@Override public void onDestroy() {

if (mDb != null) 

     mDb.close(); 

}

@Override publicznego Int getCount() {

Log.d("TestApp", "getCount: " + Integer.toString(mCount)); 

    return mCount; 

}

@Override publicznego RemoteViews getViewAt (int pozycja) {

Log.d("TestApp", "pos: " + Integer.toString(position)); 
    if (position >= mData.length) 
     return null; 

    Log.d("TestApp", "p: " + mData[position]); 

    /*if (position > 0) { 
     Log.d("TestApp", "here"); 
    }*/ 


    SharedPreferences sharedPreferences = 
     >mContext.getSharedPreferences(TestAppPreferenceActivity.SHARED_PREFS_NAME, 0); 

    RemoteViews rv = new RemoteViews(mContext.getPackageName(), >R.layout.widget_item); 

    // --- set text and image to remoteviews --- 

    return rv; 

}

@Override publiczny widok zdalny getLoadingView() { return null; }

@Override void onDataSetChanged() { SharedPreferences sharedPreferences =

mContext.getSharedPreferences (TestAppPreferenceActivity.SHARED_PREFS_NAME, 0);

String[] strs = mDb.getData(); 

    if (strs == null) { 
     mCount = 0; 
     return; 
    } 

    // -- fills mData from mDb -- 

    mCount = mData.length; 

}

@Override publicznego Int getViewTypeCount() { zwrotną 1; }

@Override public long getItemId (int pos) { return pos; }

@Override public boolean hasStableIds() { return false; }

}

+0

umieścić klasę źródłowy, który zwany getViewAt() – Rudy

+0

@Rudy - ramy dzwoni getViewAt – Ran

+0

i dawca, że ​​jego błąd – Sameer

Odpowiedz

0
@Override public long getItemId(int pos) { return pos; } 

@Override public boolean hasStableIds() { return false; } 

Nie wiem, czy to ma coś wspólnego z tym problemem, ale przykład jest return true dla hasStableIds()

+1

próbowałem go z prawdą, a także z unikalnym identyfikatorem. no go ... – Ran

3

jest wysokość lub widżet Twojego GridView lub którykolwiek z jego kontenerów nadrzędnych ustawiony na wrap_content?

Po wielu dniach prób i błędów, myślę, że ustalone podobny problem z ListView zmieniając jego wysokość od wrap_content do match_parent. Nie udało mi się odtworzyć problemu po zmianie (do tej pory).

Znalazłem film wyjaśniający, dlaczego wrap_content jest szkodliwe dla ListView: http://www.youtube.com/watch?v=wDBM6wVEO70&t=40m45s. Być może jest podobny do GridViews.

+0

Miałem nadzieję na to, ale nie ... wszystko jest match_parent lub określony rozmiar, no wrap_content. – Ran

1

Podobny do komentarza @ Niko, miałem ten problem, dopóki nie zmieniłem identyfikatorów na unikatowe dla każdego przedmiotu.

Zamiast tego może pomóc pomocna tablica tekstowa, spopielająca mocno do długich lub utrzymywanie par (long id, String data).

Oto przykład kodu dla mieszania. Używam Google Guava 's Hashing, ale koncepcja jest ogólna.

@Override 
public long getItemId(int position) { 
    return Hashing.sha1().hashString(mData[position]).asLong(); 
} 
1

Po kilku próbach i poszukiwania miesięcy w Google, dziś znalazłem rozwiązanie. Korzystając z widoków obrazu w widoku listy, należy inicjować każdy widok obrazu przy każdym wywołaniu getViewAt. W każdym przypadku wybrałem podgląd obrazu, ale zapomniałem o inicjalizacji. W getViewAt przypisałem przezroczysty obraz bez zawartości. Problem rozwiązany.

Powiązane problemy