Android Listview项目在单击通知时重复
如果我在后台播放歌曲并单击通知图标返回应用程序,则会复制listView项目。首次打开应用程序时,项目不会重复。有什么不对劲吗?在我的适配器类下面发布 适配器:Android Listview项目在单击通知时重复,android,listview,Android,Listview,如果我在后台播放歌曲并单击通知图标返回应用程序,则会复制listView项目。首次打开应用程序时,项目不会重复。有什么不对劲吗?在我的适配器类下面发布 适配器: @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; ViewHolder holder = null; final int pos = positio
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
final int pos = position;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = (RelativeLayout) inflater.inflate(R.layout.song, parent,
false);
holder = new ViewHolder();
holder.tvTitle = (TextView) view.findViewById(R.id.tv_song_title);
holder.tvArtist = (TextView) view.findViewById(R.id.tv_song_artist);
holder.imgAlbumArt = (ImageView) view
.findViewById(R.id.img_lv_album_art);
holder.tvArtist.setText(songs.get(position).getArtist());
holder.tvTitle.setText(songs.get(position).getTitle());
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
int id = (int) songs.get(position).getId();
if (bitmaps == null) {
Bitmap bm = MainActivity.getCachedArtwork(mContext,
id, MainActivity.getDefaultArtwork(mContext));
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside null", "key=" + id + "bm=" + bm + "pos" + position);
} else if (bitmaps.containsKey(id)) {
Bitmap bm = bitmaps.get(id);
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside contains key", "key=" + id + "bm=" + bm + "pos"
+ position);
} else {
Bitmap bm = MainActivity.getCachedArtwork(mContext,
id, MainActivity.getDefaultArtwork(mContext));
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside else", "key=" + id + "bm=" + bm + "pos" + position);
}
return view;
}
主要活动:
public static Bitmap getCachedArtwork(Context context, int artIndex,
Bitmap defaultArtwork) {
Bitmap d = null;
synchronized (sArtCache) {
d = sArtCache.get(artIndex);
}
if (d == null) {
d = defaultArtwork;
final Bitmap icon = defaultArtwork;
int w = icon.getWidth();
int h = icon.getHeight();
Bitmap b = getArtworkQuick(context, artIndex, w, h);
if (b != null) {
d = b;// new FastBitmapDrawable(b);
synchronized (sArtCache) {
// the cache may have changed since we checked
Bitmap value = sArtCache.get(artIndex);
if (value == null) {
sArtCache.put(artIndex, d);
} else {
d = value;
}
}
}
}
return d;
}
// Get album art for specified album. This method will not try to
// fall back to getting artwork directly from the file, nor will
// it attempt to repair the database.
private static Bitmap getArtworkQuick(Context context, int album_id, int w, int h) {
// NOTE: There is in fact a 1 pixel frame in the ImageView used to
// display this drawable. Take it into account now, so we don't have to
// scale later.
w -= 2;
h -= 2;
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
if (uri != null) {
ParcelFileDescriptor fd = null;
try {
fd = res.openFileDescriptor(uri, "r");
int sampleSize = 1;
// Compute the closest power-of-two scale factor
// and pass that to sBitmapOptionsCache.inSampleSize, which will
// result in faster decoding and better quality
sBitmapOptionsCache.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, sBitmapOptionsCache);
int nextWidth = sBitmapOptionsCache.outWidth >> 1;
int nextHeight = sBitmapOptionsCache.outHeight >> 1;
while (nextWidth>w && nextHeight>h) {
sampleSize <<= 1;
nextWidth >>= 1;
nextHeight >>= 1;
}
sBitmapOptionsCache.inSampleSize = sampleSize;
sBitmapOptionsCache.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, sBitmapOptionsCache);
if (b != null) {
// finally rescale to exactly the size we need
if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) {
Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true);
b.recycle();
b = tmp;
}
}
return b;
} catch (FileNotFoundException e) {
} finally {
try {
if (fd != null)
fd.close();
} catch (IOException e) {
}
}
}
return null;
}
public静态位图getCachedArtwork(上下文,int-artIndex,
位图(默认图形){
位图d=null;
同步(sArtCache){
d=sArtCache.get(artIndex);
}
如果(d==null){
d=默认图形;
最终位图图标=defaultArtwork;
int w=icon.getWidth();
inth=icon.getHeight();
位图b=getArtworkQuick(上下文、artIndex、w、h);
如果(b!=null){
d=b;//新的FastBitmapDrawable(b);
同步(sArtCache){
//自我们检查后,缓存可能已更改
位图值=sArtCache.get(artIndex);
如果(值==null){
sArtCache.put(artIndex,d);
}否则{
d=数值;
}
}
}
}
返回d;
}
//获取指定相册的相册艺术。此方法不会尝试
//退回到直接从文件中获取艺术品,也不会
//它试图修复数据库。
私有静态位图getArtworkQuick(上下文上下文、int相册\u id、int w、int h){
//注意:事实上,ImageView中有一个1像素的帧用于
//显示此绘图。现在将其考虑在内,这样我们就不必
//以后再缩放。
w-=2;
h-=2;
ContentResolver res=context.getContentResolver();
Uri=ContentUris.withAppendedId(sArtworkUri,唱片集id);
if(uri!=null){
ParcelFileDescriptor fd=null;
试一试{
fd=res.openFileDescriptor(uri,“r”);
int sampleSize=1;
//计算两个比例因子的最近幂
//然后将其传递给sBitmapOptionsCache.inSampleSize,它将
//导致更快的解码和更好的质量
sBitmapOptionsCache.inJustDecodeBounds=true;
BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(),null,sBitmapOptionsCache);
int nextWidth=sBitmapOptionsCache.outWidth>>1;
int nextHeight=sBitmapOptionsCache.outHeight>>1;
while(nextWidth>w&&nextHeight>h){
样本大小=1;
nextHeight>>=1;
}
sBitmapOptionsCache.inSampleSize=sampleSize;
sBitmapOptionsCache.inJustDecodeBounds=false;
位图b=BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(),null,sBitmapOptionsCache);
如果(b!=null){
//最后重新缩放到我们需要的大小
如果(sBitmapOptionsCache.outWidth!=w | | sBitmapOptionsCache.outHeight!=h){
位图tmp=Bitmap.createScaledBitmap(b,w,h,true);
b、 回收();
b=tmp;
}
}
返回b;
}catch(filenotfounde异常){
}最后{
试一试{
如果(fd!=null)
fd.close();
}捕获(IOE异常){
}
}
}
返回null;
}
在哪里设置适配器数据?可能您添加了两次项?我在Activity的onCreate方法中只设置了一次。同时,listview高度设置为仅与父项匹配。这几乎是唯一的可能性。不仅是listview,还有包含重复条目的底层数据(可以是列表或光标)。在代码中添加一些日志,这些日志会准确地显示数据中有多少项以及要添加的内容。您是对的。每次我再次使用该应用程序时,列表大小都会增加一倍。无法确定其再次添加到何处。找到错误。我已经声明列表是静态的。我的错误。谢谢你的回复。