ListView子项中包含Button按钮监听混乱的解决办法

时间:2021-10-10 17:48:57

ListView子项中包含Button按钮,遇到监听混乱这种问题对于初学者来说,可谓是焦头烂额,加之网上的代码多是复制粘贴,质量不高,也可能未能从根本上解决自己的问题,这里我就简要记录下自己的一些尝试和体会,仅以此文献给广大初学者。

Goods(实体类)

package com.example.listviewandbutton;

public class Goods {
// 物品ID
private String id;
// 是否已读(假设为短信)
private boolean isRead;

// 有参构造
public Goods(String id, boolean isRead) {
super();
this.id = id;
this.isRead = isRead;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean isRead) {
this.isRead = isRead;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

@Override
public String toString() {
return "Goods [id=" + id + "]";
}

}

GlobalList(全局静态集合)

package com.example.listviewandbutton;

import java.util.ArrayList;
import java.util.List;

/**
* 全局静态集合(为了后面修改isRead状态方便)
*
* @author lambert
*
*/

public class GlobalList {
public static List<Goods> list = new ArrayList<Goods>();
}

MainActivity

package com.example.listviewandbutton;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

/**
* 主界面
*
* @author lambert
*
*/

public class MainActivity extends Activity {
ListView lv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initDatas();
// 获取ListView对象
lv = (ListView) findViewById(R.id.lv);
// 加载适配器
lv.setAdapter(new MyAdapter(MainActivity.this, GlobalList.list));
}

/*
* 初始化数据
*/

public void initDatas() {
// 模拟数据,并添加到全局静态集合
for (int i = 0; i < 30; i++) {
// true已读,false未读
Goods g = new Goods(String.valueOf(i + 1), false);
GlobalList.list.add(g);
}
}
}

MyAdapter(适配器)


import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
* 适配器
*
* @author lambert
*
*/

public class MyAdapter extends BaseAdapter {

Context context;
// 全局的ViewHolder引用
ViewHolder vh;

public MyAdapter(Context context, List<Goods> list) {
super();
this.context = context;
}

@Override
public int getCount() {
return GlobalList.list.size();
}

@Override
public Object getItem(int arg0) {
return null;
}

@Override
public long getItemId(int arg0) {
return 0;
}

@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
if (arg1 == null) {
vh = new ViewHolder();
arg1 = LayoutInflater.from(context).inflate(R.layout.items, null);
vh.tv = (TextView) arg1.findViewById(R.id.tv);
vh.btn = (Button) arg1.findViewById(R.id.btn);
arg1.setTag(vh);
} else {
vh = (ViewHolder) arg1.getTag();
}
Goods g = GlobalList.list.get(arg0);
vh.tv.setText("物品 " + g.getId());

/*
* 此处是重点,ListVeiw的Item里有Button,我在BaseAdapter里写了Button的监听,
* 但是我每次点击Button,都是最后一个Item的Button响应事件,网上查说是因为传进去
* 的arg0是最后一个所以响应的是最后一个item,然后我在getview()外面写了一个监听接口, 并把arg0传进去
*/

vh.btn.setOnClickListener(new MyListener(arg0));

if (g.isRead()) {
vh.btn.setText("已读");
vh.btn.setBackgroundColor(Color.parseColor("#ffff4444"));
vh.btn.setVisibility(View.GONE);
} else {
vh.btn.setText("未读");
vh.btn.setBackgroundColor(Color.parseColor("#ff99cc00"));
vh.btn.setVisibility(View.VISIBLE);
}
return arg1;
}

class ViewHolder {
TextView tv;
Button btn;
}

/*
* 外部监听接口
*/

class MyListener implements OnClickListener {
int pos;

public MyListener(int pos) {
this.pos = pos;
}

@Override
public void onClick(View arg0) {
Goods g = GlobalList.list.get(pos);
Toast.makeText(context, g.getId(), 0).show();
// 此处可以由arg0强转来取得Button按钮
Button btn = (Button) arg0;
if (g.isRead()) {
// 置为未读
btn.setText("未读");
btn.setVisibility(View.VISIBLE);
GlobalList.list.set(pos, new Goods(String.valueOf(pos + 1),
false));
// 浅绿色
arg0.setBackgroundColor(Color.parseColor("#ff99cc00"));
} else {
// 置为已读
btn.setText("已读");
btn.setVisibility(View.GONE);
GlobalList.list.set(pos, new Goods(
String.valueOf(pos + 1) + "", true));
arg0.setBackgroundColor(Color.parseColor("#ffff4444"));
}
}
}
}

运行后效果图
ListView子项中包含Button按钮监听混乱的解决办法
ListView子项中包含Button按钮监听混乱的解决办法