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

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"));
            }
        }
    }
}

运行后效果图
这里写图片描述
这里写图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值