UPDATE: I opened an issue, please star it if you are experiencing the same problem. http://code.google.com/p/android/issues/detail?id=28016
I have an appwidget with a gridview on it.
When I start adding items to my widget, almost always I get the first items shown twice (instead of showing the first item and second item).
If I do a widget update intent then the problem is fixed and never returns (assuming I already have two items on my gridview).
But it always happens when the first two items are added.
Any ideas what it could be?
UPDATE: I've just noticed that it always happens when a new item is added to the GridView. If I refresh the widget without adding a new item, then it works fine.
Another thing I saw is that the getViewAt method is always called twice for the first item (position zero). Maybe it's related?
I followed the sample here quite closely: http://developer.android.com/resources/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.html
Here is my RemoteViewsService, I think this is the relevant part but I'm not sure actually. What else can affect it?
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;
}
}
Is the height or widget of your GridView or any of its parent containers set to wrap_content?
After many days of trial and error, I think I fixed a similar issue with a ListView by changing its height from wrap_content to match_parent. I haven't been able to reproduce the problem after the change (so far).
I found a video explaining why wrap_content is bad for ListView's: http://www.youtube.com/watch?v=wDBM6wVEO70&t=40m45s. Maybe its similar for GridViews as well.
Similar to @Niko's comment, I had this problem until I changed the IDs to be unique per item.
For a backing array of strings, hashing them strongly to longs, or keeping (long id, String data)
pairs instead may help.
Here's example code for hashing. I'm using Google Guava's Hashing
, but the concept is general.
@Override
public long getItemId(int position) {
return Hashing.sha1().hashString(mData[position]).asLong();
}
After several trials and a month search on google, today I found the solution. When using imageviews in listview, you should initiate every imageview at each getViewAt call. I've conditioned imageview selection in each case, but forgot initialization. At getViewAt I assigned a transparent image with no content. Problem solved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With