2012-03-22 5 views
6

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

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

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

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

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

Любые идеи, что это может быть?

UPDATE: Я только что заметил, что это всегда происходит, когда новый элемент добавляется в GridView. Если я обновляю виджет без добавления нового элемента, то он отлично работает.

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

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

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

упаковка com.manor.TestApp;

общественного класса TestAppRemoteViewsService расширяет RemoteViewsService {

@Override
общественного RemoteViewsFactory onGetViewFactory (Intent намерения) {
возвратный новый TestAppViewsFactory (this.getApplicationContext(), намерения); }

}

класс TestAppViewsFactory реализует RemoteViewsService.RemoteViewsFactory {

частный Контекст mContext;

// private int mAppWidgetId;

приватное TestDb mDb = null;

частный int mCount = 0;

приватная строка [] mData;

public TestAppViewsFactory (контекстный контекст, намерение намерения) { mContext = context;

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

}

@Override общественного недействительными OnCreate() {

mDb = new TestDb(mContext); 

    mDb.open(false); 

}

@Override общественного недействительными OnDestroy() {

if (mDb != null) 

     mDb.close(); 

}

@Override общественного INT GetCount() {

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

    return mCount; 

}

@Override общественных RemoteViews getViewAt (промежуточное положение) {

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 общественных недействительный 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 общественного INT getViewTypeCount() { возвращение 1; }

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

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

}

+0

введите класс источника, который называется getViewAt() – Rudy

+0

@Rudy - фреймворк вызывает getViewAt – Ran

+0

Я не считаю его ошибкой – Sameer

ответ

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

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

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

+1

Я пробовал его с истинным, а также с уникальным идентификатором. no go ... – Ran

3

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

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

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

+0

Я надеялся на это, но нет .. все соответствует match_parent или конкретному размеру, без wrap_content. – Ran

1

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

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

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

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

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

Смежные вопросы