Повторяющиеся элементы в виджете GridView - PullRequest
6 голосов
/ 22 марта 2012

ОБНОВЛЕНИЕ: Я открыл проблему, пожалуйста, отметьте ее, если у вас возникла та же проблема.http://code.google.com/p/android/issues/detail?id=28016

У меня есть приложение с видением сетки.

Когда я начинаю добавлять элементы в свой виджет, почти всегда первые элементы отображаются дважды (вместо отображения первого элемента).и второй элемент).

Если я выполню намерение обновления виджета, то проблема будет исправлена ​​и никогда не вернется (при условии, что у меня уже есть два элемента в моем виде сетки).

Но это всегда происходит, когдадобавлены первые два элемента.

Есть идеи, что это может быть?

ОБНОВЛЕНИЕ: Я только что заметил, что это всегда происходит, когда новый элемент добавляется вВид сетки.Если я обновляю виджет, не добавляя новый элемент, то он работает нормально.

Еще одна вещь, которую я видел, состоит в том, что метод getViewAt всегда вызывается дважды для первого элемента (нулевая позиция).Может быть, это связано?

Я очень внимательно следил за примером: http://developer.android.com/resources/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.html

Вот мой RemoteViewsService, я думаю, что это актуальная часть, но я не уверен на самом деле.Что еще может повлиять на это?

package com.manor.TestApp;

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

class TestAppViewsFactory implements RemoteViewsService.RemoteViewsFactory {

    private Context mContext;

    //private int mAppWidgetId;

    private TestDb mDb = null;

    private int mCount = 0;

    private String[] mData;

    public TestAppViewsFactory(Context context, Intent intent) {
        mContext = context;

        /*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
    public int getCount() {
        Log.d("TestApp", "getCount: " + Integer.toString(mCount));
        return mCount;
    }

    @Override
    public RemoteViews getViewAt(int position) {

        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
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public 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
    public int getViewTypeCount() {
        return 1;
    }

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

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

Ответы [ 4 ]

3 голосов
/ 18 апреля 2012

Для высоты или виджета вашего GridView или любого из его родительских контейнеров установлено значение wrap_content?

После многих дней проб и ошибок, я думаю, я исправил подобную проблему с ListView, изменив его высоту с wrap_content на match_parent . Я не смог воспроизвести проблему после изменения (пока).

Я нашел видео, объясняющее, почему wrap_content плохо подходит для ListView: http://www.youtube.com/watch?v=wDBM6wVEO70&t=40m45s. Возможно, оно аналогично и для GridViews.

1 голос
/ 09 июня 2013

После нескольких проб и месячного поиска в гугле, сегодня я нашел решение.При использовании изображений в режиме просмотра списка вы должны запускать каждый просмотр изображений при каждом вызове getViewAtЯ обусловил выбор изображения в каждом случае, но забыл инициализацию.На getViewAt я назначил прозрачное изображение без содержимого.Проблема решена.

1 голос
/ 03 июля 2012

Как и в комментарии @ Niko, у меня была эта проблема, пока я не изменил идентификаторы на уникальные для каждого элемента.

Для вспомогательного массива строк сильное хеширование их в long или сохранение вместо них пар (long id, String data) может помочь.

Вот пример кода для хеширования. Я использую Google Guava Hashing, но концепция общая.

@Override
public long getItemId(int position) {
    return Hashing.sha1().hashString(mData[position]).asLong();
}
0 голосов
/ 29 марта 2012
@Override public long getItemId(int pos) { return pos; }

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

Не уверен, что это как-то связано с проблемой, но в примере возвращено значение true для hasStableIds ()

...