2012-03-17 54 views
4

我有一个自定义ListViewAdapter,我正在为列表创建行。我的问题是,它似乎并没有区分对方。这似乎是随机挑选ImageViews当我上下滚动时卡入到位。文本信息(从这段代码中省略)不会中断。它按照人们的预期工作。自定义ListView适配器,奇怪的ImageView行为

这里是我的Adapter的相关方法:

public View getView(int position, View convertView, ViewGroup parent) 
    { 
    View v = convertView; 

    if(v == null) 
    { 
     LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.generic_row, null); 
    } 

    // find the image 
    ImageView favImage = (ImageView)v.findViewById(R.id.toggle_favorite); 

    // when clicked... 
    favImage.setOnClickListener(new OnClickListener() { 

    @Override 
    public void onClick(View v) 
    { 
     // make the gray star a yellow one 
     int newImage = R.drawable.ic_star_yellow_embossed; 
     ((ImageView)v).setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(), newImage)); 
    } 

    }); 

    return v; 
    } 
+0

** ** getView2 ........? – waqaslam 2012-03-17 21:52:57

+0

@Waqas:忽略这一点,那是我在课堂上复制,粘贴和剥离的东西。它在代码中正确命名。 – Josh 2012-03-17 21:53:41

回答

3

出现这种行为,因为ListView回收行的意见,您滚动列表上下,正因为如此你行由用户(图像发生了变化)所采取行动的图像应该是未修改的。为避免这种情况,您必须以某种方式为列表中的每一行保存ImageView的状态,并使用此状态在getView()方法中设置正确的图像。因为你没有说明你是如何实现你的适配器的,我将向你展示一个简单的例子。

首先你应该存储你的状态ImageView。我使用ArrayList<Boolean>作为自定义适配器的成员,如果该列表中的位置(对应于列表中的行的位置)为false则图像为默认图像,否则如果是true,则用户单击它,我们应该把新形象:

private ArrayList<Boolean> imageStatus = new ArrayList<Boolean>(); 

在您的自定义适配器的构造函数初始化这个名单。在getView()方法

//... initialize the imageStatus, objects is the list on which your adapter is based 
for (int i = 0; i < objects.size(); i++) { 
    imageStatus.add(false); 
} 

然后:例如,如果你把你的适配器的东西名单,那么你应该让你的imageStatus那样大名单,并充满false(默认/启动状态)

View v = convertView; 

      if (v == null) { 
       LayoutInflater vi = (LayoutInflater) getContext() 
         .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = vi.inflate(R.layout.adapters_adapter_with_images, null); 
      } 

      // find the image 
      ImageView favImage = (ImageView) v 
        .findViewById(R.id.toggle_favorite); 
      // Set the image bitmap. If the imageStatus flag for this position is TRUE then we 
      // show the new image because it was previously clicked by the user 
      if (imageStatus.get(position)) { 
       int newImage = R.drawable.ic_star_yellow_embossed; 
       favImage.setImageBitmap(BitmapFactory.decodeResource(
         getContext().getResources(), newImage)); 
      } else { 
       // If the imageStatus is FALSE then we explicitly set the image 
       // back to the default because we could be dealing with a 
       // recycled ImageView that has the new image set(there is no need to set a default drawable in the xml layout)          
       int newImage = R.drawable.basket_empty; //the default image 
       favImage.setImageBitmap(BitmapFactory.decodeResource(
         getContext().getResources(), newImage)); 
      } 
      // when clicked... we get the real position of the row and set to TRUE 
      // that position in the imageStatus flags list. We also call notifyDataSetChanged 
      //on the adapter object to let it know that something has changed and to update! 
      favImage.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        Integer realPosition = (Integer) v.getTag(); //get the position from the view's tag 
        imageStatus.set(realPosition, true); //this position has been clicked be the user 
        adapter.notifyDataSetChanged(); //notify the adapter 
       } 

      }); 
      // set the position to the favImage as a tag, we later retrieve it 
      // in the onClick method 
      favImage.setTag(new Integer(position)); 
      return v; 

     } 

如果您不打算动态修改列表(删除/添加行),这应该很好,否则您还必须照顾修改该列表imageStatus以反映更改。你没有说什么是你的行数据,另一种方法(如果用户点击那个图像(除了改变它),如果你打算做点什么)的另一种方法是将图像的状态合并到行的数据模型中。对此这里有一些教程:

Android ListView Advanced InteractiveCommonsware-Android Excerpt(交互式行)

2

你需要找到它的引用后立即定义默认的图像:

// find the image 
ImageView favImage = (ImageView)v.findViewById(R.id.toggle_favorite); 
//setting to default 
favImage.setImageResource(R.drawable.default_image); 
// when clicked... 
favImage.setOnClickListener.... 

你需要这样做,因为一旦图像更改,并且您滚动ListView,它会重新出现,因为ListView可以回收项目视图。因此,你需要在getView来定义它使用的默认图像当列表滚动

+0

我不明白。我试图在点击图片时执行此操作。我已经在.xml文件中设置了它的默认图像。 – Josh 2012-03-17 22:01:18

+0

设置它在xml中是一次,这是在'if(v == null)'中实现的,但之后当ListView回收视图时,它不会从xml读取,它只是回收视图,在这种情况下,您的ImageView包含点击时定义的旧图像。只需在代码中设置默认图像,我相信它会起作用 – waqaslam 2012-03-17 22:04:12

相关问题