Android Arrayadapter与OnClick侦听器匹配
这是我的自定义arrayadapter类,我想在单击每行按钮时更改每行按钮的图像资源,它可以工作,但另一行中的另一个按钮也会更改。谢谢你的帮助Android Arrayadapter与OnClick侦听器匹配,android,eclipse,view,onclick,android-arrayadapter,Android,Eclipse,View,Onclick,Android Arrayadapter,这是我的自定义arrayadapter类,我想在单击每行按钮时更改每行按钮的图像资源,它可以工作,但另一行中的另一个按钮也会更改。谢谢你的帮助 public class Coursadapter extends ArrayAdapter<String> { Context context; int layoutResourceId; ArrayList<String> data = null; WeatherHolder holder;
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, null);
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;
}
}
公共类Coursadapter扩展了ArrayAdapter{
语境;
国际布局资源;
ArrayList数据=null;
风挡;
公共Coursadapter(上下文上下文、内部布局资源ID、,
ArrayList数据){
//超级(上下文、布局资源ID、数据、系数);
超级(上下文、布局资源ID、数据);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
这个数据=数据;
}
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行=转换视图;
if(行==null){
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(布局资源ID,空);
支架=新的密封支架();
holder.name=(TextView)row.findViewById(R.id.item\u cours\u name);
holder.b=(ImageButton)row.findViewById(R.id.button);
holder.b.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
WeatherHolder w=(WeatherHolder)v.getTag();
w、 b.setImageResource(R.drawable.butgreen);
}
});
row.setTag(支架);
}否则{
holder=(WeatherHolder)row.getTag();
}
holder.b.setTag(holder);
字符串名称1=data.get(位置);
holder.name.setText(name1);
返回行;
}
静态类风挡{
文本视图名称;
图像按钮b;
}
}
您可以声明变量int,该变量将保存所选项目的位置,并且
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
mSelectedItem = position;
mAdapter.notifyDataSetChanged();
}
听着,我试着用这段代码工作,在你的活动中实现OnClickListener
public class MainActivity extends Activity implements OnClickListener
在getView方法中
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, null);
holder = new WeatherHolder();
holder.name = (TextView) row.findViewById(R.id.item_cours_name);
holder.b = (ImageButton) row.findViewById(R.id.button);
holder.b.setOnClickListener(MainActivity.this);
并且实现Onclick方法来设置资源
@Override
public void onClick(View v) {
WeatherHolder w = (WeatherHolder) v.getTag();
w.b.setImageResource(android.R.drawable.star_big_on);
}
代码的问题是OnClickListener设置在错误的位置 考虑一下
getView()
中if/else语句的结果。如果传入该方法的convertView
为空,则可能是首次创建视图(以及包含该视图的ListView)——例如,您正在启动包含该ListView的活动。如果该值不为null,则意味着您正在循环一个以前在屏幕上但现在不再在屏幕上的视图
如果你仔细观察,你会发现你的OnClickListener只在第一种情况下被设置——一个全新的视图。一旦你滚动一点,你的听众将永远不会正确地连接到那些来自屏幕外的视图
更好的getView()
方法是:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, null);
holder = new WeatherHolder();
holder.name = (TextView) row.findViewById(R.id.item_cours_name);
holder.b = (ImageButton) row.findViewById(R.id.button);
row.setTag(holder);
} else {
holder = (WeatherHolder) row.getTag();
}
String name1 = data.get(position);
holder.name.setText(name1);
holder.b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
((ImageButton)v).setImageResource(R.drawable.butgreen);
}
});
return row;
}
编辑:添加到我下面评论的另一个修复中。发生这种情况的原因是适配器在滚动时回收视图 例如,假设一次屏幕上总共有15行和5行。if(row==null)部分仅对前5行执行。当您向下滚动到第6行时,它使用第一行的视图。这就是为什么应该在if-else子句之后设置视图的内容。现在,当第6行进入屏幕时,该行不为空。它可以看到第一排。当它执行holder.name.setText(name1);,它将第1行的名称替换为第6行的名称。类似地,第7行使用第2行的视图,依此类推 现在,假设您单击第一行的按钮。第一行的视图更改,w.b.setImageResource(R.drawable.butgreen);设置第一行按钮的图像资源。当您滚动到第6行时,它使用第一行的视图。但是您正在将only holder.name设置为第6行的名称。第一行按钮的图像资源将保留在那里,从而导致您的问题 解决方案:创建另一个ArrayList并在此列表中存储按钮的状态。在你的例子中,我假设按钮的颜色是“红色”或“绿色”。您可以在每个位置存储“红色”或“绿色”,表示每个按钮当前的颜色(您可以将此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;
}
}
公共类Coursadapter扩展了ArrayAdapter{
语境;
国际布局资源;
ArrayList数据=null;
风挡;
ArrayList colors;//存储每个按钮的颜色
公共Coursadapter(上下文上下文、int-layoutResourceId、ArrayList数据){
//超级(上下文、布局资源ID、数据、系数);
超级(上下文、布局资源ID、数据);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
这个数据=数据;
this.colors=newarraylist(Collections.nCopies(data.size(),“red”);//将所有按钮初始化为红色
}
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
视图行=转换视图;
if(行==null)
{
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(layoutResourceId,父级,false);
支架=新的密封支架();
holder.name=(TextView)row.findViewById(R.id.item\u cours\u name);
holder.b=(ImageButton)row.findViewById(R.id.button);
holder.b.setTag(holder);
row.setTag(支架);
}
其他的
{
holder=(WeatherHolder)row.getTag();
}
if(colors.get(position.equals)(“红色”)){
holder.b.setImageResource(R.drawable.butred);//将按钮的颜色设置为红色或您需要的任何颜色
}否则{
b.b.组
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;
}
}