Duplicate items in GridView widgets

UPDATE: I discovered a problem, please run it if you have 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 elements to my widget, almost always I get the first elements shown twice (instead of displaying the first element and second element).

If I have the intention of updating the widget, the problem is fixed and never returns (it is assumed that I already have two elements in my gridview).

But this always happens when the first two elements are added.

Any ideas what this could be?

UPDATE: I just noticed that this always happens when a new item is added to the GridView. If I update the widget without adding a new element, then it works fine.

Another thing I saw is that the getViewAt method is always called twice for the first element (zero position). Maybe this is connected?

I watched the sample closely: http://developer.android.com/resources/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.html

Here is my RemoteViewsService, I think this is an important part, but I'm not really sure. What else could affect this?

package com.manor.TestApp;

public class TestAppRemoteViewsService extends RemoteViewsService {

@Override
public RemoteViewsFactory onGetViewFactory (intent intent) {
return a new TestAppViewsFactory (this.getApplicationContext (), intent); }

}

class TestAppViewsFactory implements RemoteViewsService.RemoteViewsFactory {

Closed Context mContext;

// private int mAppWidgetId;

private TestDb mDb = null;

private int mCount = 0;

private String [] mData;

public TestAppViewsFactory (context context, intent intention) {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; }

}

+6
source share
4 answers

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 problem with ListView by changing its height from wrap_content to match_parent . I could not reproduce the problem after the change (so far).

I found a video explaining why wrap_content is bad for ListView: http://www.youtube.com/watch?v=wDBM6wVEO70&t=40m45s . Perhaps this is similar to GridViews.

+3
source

Like @ Niko's comment, I had this problem until I changed the identifiers to be unique for each element.

For a basic array of strings, strongly binding them to longs, or instead of a pair (long id, String data) can help.

Here is sample code for hashing. I use Google Guava Hashing , but the concept is common.

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

After several tests and monthly searches on google today I found a solution. When using imageviews in listview, you must trigger every image in every getViewAt call. In each case, I set up the selection as an image, but forgot the initialization. In getViewAt, I assigned a transparent image with no content. The problem is resolved.

+1
source
 @Override public long getItemId(int pos) { return pos; } @Override public boolean hasStableIds() { return false; } 

Not sure if this has anything to do with the problem, but the example returns true for hasStableIds ()

0
source

Source: https://habr.com/ru/post/911383/


All Articles