1

我有一个自定义arrayadapter,我想为其每行中的按钮添加一个onclicklistener,当我单击按钮我想要更改图像资源时,所有内容除了当我点击一个按钮时,图像会改变,但另一行中另一个按钮的图像也会改变。谢谢你的帮助 ! 这里是我的代码:自定义arrayadapter和onclicklistener为一行中的按钮

public class Coursadapter extends ArrayAdapter<String>{ 

    Context context; 
    int layoutResourceId;  
    ArrayList<String> data = null; 
    WeatherHolder holder; 

    public Coursadapter(Context context, int layoutResourceId, ArrayList<String> data) { 
     // super(context, layoutResourceId, data, coeff); 
     super(context, layoutResourceId, data); 
     this.layoutResourceId = layoutResourceId; 
     this.context = context; 
     this.data = data; 

    } 

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


     if(row == null) 
     { 
      LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      holder = new WeatherHolder(); 
      holder.name = (TextView)row.findViewById(R.id.item_cours_name); 
      holder.b=(ImageButton) row.findViewById(R.id.button); 
      holder.b.setTag(holder); 
      row.setTag(holder); 
     } 
     else 
     { 
      holder = (WeatherHolder)row.getTag(); 
     } 

     holder.b.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       WeatherHolder w = (WeatherHolder) v.getTag(); 
       w.b.setImageResource(R.drawable.butgreen); 


      } 
     }); 
     String name1 = data.get(position); 
     holder.name.setText(name1); 


     return row; 
    } 

    static class WeatherHolder 
    { 

     TextView name; 
     ImageButton b; 
    } 
} 
+1

尝试移动'holder.b.setTag(holder);'在else部分下面。你的问题是因为lsitview回收视图。 – Raghunandan

+0

您是否得到了解决方案。由于 – Vinay

回答

0
public View getView(int position, View convertView, ViewGroup parent) { 
    if(convertView == null) 
    { 
     LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
     convertView = inflater.inflate(layoutResourceId, parent, false); 

    } 
    TextView name = (TextView)convertView.findViewById(R.id.item_cours_name); 
    ImageButton b=(ImageButton) convertView.findViewById(R.id.button); 
    b.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      b.setImageResource(R.drawable.butgreen); 
     } 
    }); 
    String name1 = data.get(position); 
    name.setText(name1); 
    return convertView; 
} 
+0

没有工作,我按照您的要求做了,但仍然遇到同样的问题 –

+0

只需将getView方法替换为我编辑的方法即可。尝试一次 – user543

+0

我复制/粘贴了你的getview,它不工作,同样的问题,当我点击一个按钮时,另一行中的另一个按钮也被改变了 –

0

一些变化做哪些检查出代码

包com.example.dontpanic;

public class Coursadapter extends ArrayAdapter<String> { 

    Context context; 
    int layoutResourceId; 
    ArrayList<String> data = null; 
    WeatherHolder holder; 

    public Coursadapter(Context context, int layoutResourceId, 
      ArrayList<String> data) { 
     // super(context, layoutResourceId, data, coeff); 
     super(context, layoutResourceId, data); 
     this.layoutResourceId = layoutResourceId; 
     this.context = context; 
     this.data = data; 

    } 

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

     if (row == null) { 
      LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      holder = new WeatherHolder(); 
      holder.name = (TextView) row.findViewById(R.id.item_cours_name); 
      holder.b = (ImageButton) row.findViewById(R.id.button); 
      holder.b.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // TODO Auto-generated method stub 
        WeatherHolder w = (WeatherHolder) v.getTag(); 
        w.b.setImageResource(R.drawable.butgreen); 
       } 
      }); 
      row.setTag(holder); 

     } else { 
      holder = (WeatherHolder) row.getTag(); 
     } 

     holder.b.setTag(holder); 
     String name1 = data.get(position); 
     holder.name.setText(name1); 

     return row; 
    } 

    static class WeatherHolder { 

     TextView name; 
     ImageButton b; 
    } 
} 

把你的点击监听器里,如果条件以及其他是否条件

+0

对不起,我更新了我的getview,我仍然有完全相同的问题! –

+0

尝试调试您的点击事件并检查您的获得情况。这可以是不同的东西 –

+0

一切似乎很好,当我调试,只有一个点击事件,当我点击按钮,但不知何故另一个按钮也改变 –

0

之外设置标签有一个共同的误解你的问题,两个答案份额。

首先,确保您了解ListView的回收工作方式。例如,this post稍微解释了这个问题。

关于这个特殊情况,我们先来了解一下这个问题。当你点击一个按钮时,图像被改变,一切看起来都很好。但是如果你滚动,你会在另一个位置得到相同的视图(带有更改图像的按钮)。由于回收。

要解决这个问题,你必须保持你的按钮的图像选择。这不会奇迹般地发生。你必须添加一些逻辑来告诉这个方法哪个图像资源应该显示在一个特定的位置。

例如,在你的getView()方法,添加以下(伪)代码:

public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    if(row == null) { 
     // omitted.. 
    } 
    else { 
     holder = (WeatherHolder)row.getTag(); 

     // BUTTON's IMAGE MAINTAINING 
     if(condition) { 
      w.b.setImageResource(R.drawable.butgreen); 
     } else { 
      w.b.setImageResource(some-other-image-resource); 
     } 
    } 

    // omitted.. 

    return row; 
} 
0

之所以出现这种情况是因为适配器回收上滚动的意见。

例如,假设您一次总共有15行和5行适合屏幕。 if(row == null)部分仅对前5行执行。当您向下滚动到第6行时,它将使用第1行的视图。这就是为什么你应该在if-else子句之后设置View的内容。所以现在,当第六行进入屏幕时,行不是null。它包含第一行的视图。当它执行holder.name.setText(name1);时,它将用第6行的名称替换第1行的名称。同样,第7行使用第2行的视图,依此类推。

现在,假设您单击第一行中的按钮。第1行的视图发生变化,w.b.setImageResource(R.drawable.butgreen);设置第1行按钮的图像资源。当您滚动到第6行时,它将使用第1行的视图。但是,您只将第012行的名称设置为holder.name。第一行按钮的图像资源将保留在那里,因此导致您的问题。

解决方案:创建另一个ArrayList<String>并在此存储按钮的状态。所以在你的情况下,我假设按钮的颜色是“红色”或“绿色”。您可以在每个位置存储“红色”或“绿色”,表示每个按钮当前的颜色(您可以将此ArrayList初始化为红色)。然后,当每行加载时,您可以设置图像资源以及该行的名称。看看下面的代码。我已经对我添加的内容发表了评论。

public class Coursadapter extends ArrayAdapter<String> { 

Context context; 
int layoutResourceId; 
ArrayList<String> data = null; 
WeatherHolder holder; 
ArrayList<String> colors; // Stores the color of each button 

public Coursadapter(Context context, int layoutResourceId, ArrayList<String> data) { 
    // super(context, layoutResourceId, data, coeff); 
    super(context, layoutResourceId, data); 
    this.layoutResourceId = layoutResourceId; 
    this.context = context; 
    this.data = data; 
    this.colors = new ArrayList<>(Collections.nCopies(data.size(), "red")); // initialize all the buttons to red color 
} 

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


    if(row == null) 
    { 
     LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 
     row = inflater.inflate(layoutResourceId, parent, false); 

     holder = new WeatherHolder(); 
     holder.name = (TextView)row.findViewById(R.id.item_cours_name); 
     holder.b=(ImageButton) row.findViewById(R.id.button); 
     holder.b.setTag(holder); 
     row.setTag(holder); 
    } 
    else 
    { 
     holder = (WeatherHolder)row.getTag(); 
    } 

    if(colors.get(position).equals("red")) { 
     holder.b.setImageResource(R.drawable.butred); // set the colors of the button to red or whatever you need 
    } else { 
     holder.b.setImageResource(R.drawable.butgreen); // set the colors of the button to green 
    } 

    holder.b.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // TODO Auto-generated method stub 
      WeatherHolder w = (WeatherHolder) v.getTag(); 
      //w.b.setImageResource(R.drawable.butgreen); 
      colors.set(position, "green"); // update the ArrayList colors 
     } 
    }); 
    String name1 = data.get(position); 
    holder.name.setText(name1); 


    return row; 
} 

static class WeatherHolder 
{ 

    TextView name; 
    ImageButton b; 
} 
} 
相关问题