使用 Baseadapter 时列表视图中的联系人图像重复

Posted

技术标签:

【中文标题】使用 Baseadapter 时列表视图中的联系人图像重复【英文标题】:Contact Image in listview is repeating when use a Baseadapter 【发布时间】:2016-04-04 03:22:18 【问题描述】:

我正在构建一个应用程序,我将所有联系人数据存储在我的 sqlite 数据库中,并将该数据填充到列表视图中。

在此过程中,联系人图像会重复显示,并且没有任何排序。

适配器:

private class ContactAdapter extends SimpleCursorAdapter

    
        //Context context;
        ArrayList<HashMap<String, String>> data;
        private Cursor c;
        private Context context;
        LayoutInflater inflater;
        public ContactAdapter(Context context, int layout, Cursor c, String[] from, int[] to) 
            super(context, layout, c, from, to);
            this.c = c;
            this.context = context;
            inflater = LayoutInflater.from(this.context);
        


        @SuppressWarnings("deprecation")
        @SuppressLint("NewApi")
        @Override
        public View getView(int position, View convertView, ViewGroup parent) 
            // TODO Auto-generated method stub
            ViewHolderContact viewHolder;

            //viewHolder = new ViewHolderContact();


            if(convertView==null)
            
                viewHolder = new ViewHolderContact();

                convertView = inflater.inflate(R.layout.layout_contactlist, null);
                viewHolder.imageView = (ImageView) convertView.findViewById(R.id.ivimage);
                viewHolder.imgNext = (ImageView) convertView.findViewById(R.id.imgnext);
                viewHolder.textView_Name = (TextView)convertView .findViewById(R.id.txtname);

            //  view.imgad.setScaleType(ImageView.ScaleType.FIT_XY);
                /*view.imgad.setScaleType(ImageView.ScaleType.FIT_XY);
                //view.imgad.setPadding(0,10,0,0);
                //view.imgad.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,100));
                //LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,90);
                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,90);
                lp.setMargins(0,20,0,0);
                view.imgad.setLayoutParams(lp);
                 */
                convertView.setTag(viewHolder);
            
            else
            
                viewHolder = (ViewHolderContact)convertView.getTag();
            

            this.c.moveToPosition(position);     
            String contactid = this.c.getString(this.c.getColumnIndex("_id"));
            String contactname = this.c.getString(this.c.getColumnIndex("contactname"));
            String contactnumber = this.c.getString(this.c.getColumnIndex("contactnumber"));
            String contactimage= this.c.getString(this.c.getColumnIndex("contactimage"));
            String isInstalled= this.c.getString(this.c.getColumnIndex("isInstalled"));


            //System.out.println("Isinstalled--->"+isInstalled);

            if(isInstalled.equals("Y"))
            
                viewHolder.imgNext.setVisibility(View.GONE);
            


            if (contactimage == null || contactimage.equals("")) 
                if (Build.VERSION.SDK_INT >= 16) 
                    viewHolder.imageView.setBackground(getResources().getDrawable(R.drawable.ic_launcher));
                
                else 
                    viewHolder.imageView.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher));
                
                // If there is no image in the database "NA" is stored instead of a blob 
                // test if there more than 3 chars "NA" + a terminating char if more than
                // there is an image otherwise load the default
               //iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
            else   
                try 
                    Bitmap bmp=getContactBitmapFromURI(ContactList.this,Uri.parse(contactimage));
                    Bitmap round=getRoundedShape(bmp);
                    viewHolder.imageView.setImageBitmap(round);

                 catch (FileNotFoundException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                
            

            viewHolder.textView_Name.setText(contactname);

            return convertView;                 

        

        class ViewHolderContact 
            TextView textView_Name;
            ImageView imageView,imgNext;

        

    

c 是光标实例

getContactBitmapFromURI(Context context, Uri uri)方法

public static Bitmap getContactBitmapFromURI(Context context, Uri uri) throws FileNotFoundException 
    InputStream input = context.getContentResolver().openInputStream(uri);
    if (input == null) 
        return null;
    
    return BitmapFactory.decodeStream(input);

输出:

当我滚动时,输出变为:

如您所见,图像未正确显示。它们正在重复或/和消失。请帮助。

【问题讨论】:

您好,我没有接受,因为没有一个答案符合我的要求 【参考方案1】:

这可能是图像缓存的情况,将图像解码为Bitmap 后将其保存在缓存中。请通过网址了解如何缓存图片:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

【讨论】:

我猜你是对的,但是图像的缓存主要是在 url 上完成的,而不是在 uri 上完成的。我找不到任何样本【参考方案2】:

Listview 重用视图。我认为问题出在cursor。也许您可以尝试在方法getItem() 中先设置数据。您也可以尝试在到达某个位置时执行notifyDataChanged,如果图像发生变化,那么这将是一个很好的起点。

【讨论】:

【参考方案3】:

我认为那是因为你的 if else 部分。在第一种情况下,您正在设置图像的背景,在第二种情况下,您正在设置图像的 src 。 seImageBitmap() 方法将位图设置为 src 。换一种情况。在两种情况下都使用相同的。所以我建议使用Circle image view 来获得圆形图像并使用UILoader 或Picasso 加载图像。这样,您也将摆脱缓存和内存不足错误..

你可以像这样从 uri 获取图片 url

private String getPathFromUri(Uri uri) 
    String url = null;
    Cursor cursor = getContentResolver().query(uri, new String[]  android.provider.MediaStore.Images.Media.DATA , null, null, null);
    if (cursor.moveToFirst()) 
        url = cursor.getString(0);
    
    return url;

【讨论】:

Picasso 加载 url 和联系人图片是 uri,如:content://com.android.contacts/display_photo/7--->contactimage 所以从 uri 获取 Url。使用这个 cursor = getContentResolver().query(uri, new String[] android.provider.MediaStore.Images.Media.DATA , null, null, null ); if (cursor.moveToFirst()) String url= cursor.getString(0);

以上是关于使用 Baseadapter 时列表视图中的联系人图像重复的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 baseadapter 自定义列表视图

BaseAdapter 未更新列表视图中的数据

如何在android中使用baseadapter刷新自定义列表视图

滚动时的 BaseAdapter 列表视图位置

ListFragment(或 Fragment)中的 BaseAdapter 不起作用

我如何使用 baseadapter 过滤列表视图