ListView

ListView中嵌入布局的多个点击事件

有时候在ListView嵌入的布局中有多个事件需要点击,比如一个item中有TextView和Button两个布局,当我们需要获取这两个点击事件时,我们应该如何去获取呢,通常来说,我们都是已经固定好了TextView和Button的id的,,所以,这两个点击事件的id肯定是不会变的,假如我们有10个item,我们需要获取第5个item中的布局的button和TextView的点击事件该如何获取呢?下面将依依介绍。(适合初学者)

首先先看初次布局界面:

activity_main.xml布局:ListView的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.qianfeng.listviewbutton.MainActivity">
    <ListView
        android:id="@+id/mList"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</RelativeLayout>

list_item.xml布局:ListView item的每个布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/mTv"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="234"
        />
    <Button
        android:id="@+id/mBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        />
</RelativeLayout>
  • 先看我们的初始代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {
    //ListView控件
    private ListView mList;
    //ListView数据源
    private List<String> data;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        data = new ArrayList<>();
        mList = (ListView)findViewById(R.id.mList);
        for(int i = 0; i < 20; i ++){
            data.add("今天好手气" + i);
        }
        MyAdapter adapter = new MyAdapter(data);
        mList.setAdapter(adapter);
        //ListView item点击事件
        mList.setOnItemClickListener(new ListView.OnItemClickListener(){

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(MainActivity.this,"我是item点击事件 i = " + i + "l = " + l,Toast.LENGTH_SHORT).show();
            }
        });
    }
}

MyAdapter.java

public class MyAdapter extends BaseAdapter implements View.OnClickListener {
    //上下文
    private Context context;
    //数据项
    private List<String> data;
    public MyAdapter(List<String> data){
        this.data = data;
    }
    @Override
    public int getCount() {
        return data == null ? 0 : data.size();
    }

    @Override
    public Object getItem(int i) {
        return data.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if(context == null)
            context = viewGroup.getContext();
        if(view == null){
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item,null);
            viewHolder = new ViewHolder();
            viewHolder.mTv = (TextView)view.findViewById(R.id.mTv);
            viewHolder.mBtn = (Button)view.findViewById(R.id.mBtn);
            view.setTag(viewHolder);
        }
        //获取viewHolder实例
        viewHolder = (ViewHolder)view.getTag();
        //设置数据
        viewHolder.mTv.setText(data.get(i));
        //设置监听事件
        viewHolder.mTv.setOnClickListener(this);
        //设置数据
        viewHolder.mBtn.setText("点我点我"+ i);
        viewHolder.mBtn.setOnClickListener(this);
        return view;
}

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.mBtn:
                Log.d("tag", "Btn_onClick: " + "view = " + view);
                Toast.makeText(context,"我是按钮",Toast.LENGTH_SHORT).show();
                break;
            case R.id.mTv:
                Log.d("tag", "Tv_onClick: " + "view = " + view);
                Toast.makeText(context,"我是文本",Toast.LENGTH_SHORT).show();
                break;
        }
    }

    static class ViewHolder{
        TextView mTv;
        Button mBtn;
    }

}

这里写图片描述

通过上图我们可以看到,当鼠标第一次停留的地方,我点击item项时,没有任何反应,当点击按钮和文本的时候就会弹出吐司,那么为什么点击item会没有触发事件呢?怎样才能让item也有触发事件呢?

因为一个item布局中有按钮控件的话,按钮会获得焦点,而此时item就获取不到焦点,所以点击Item时不能触发其点击事件,如果想让item也有点击事件的话,则设置Button的焦点默认为false,则我们只需要在list_item.xml中的Button控件中加入android:focusable="false"这样item就有了焦点,可以点击了

如下是改变焦点后的运行效果: 
这里写图片描述

但是随之又有一个问题了,我们如何判断我们点击的是哪个item中的TextView和Button呢,因为目前的点击时间只能判断是TextView点击了,还是Button,或者item被点击了,除了item能知道是哪一项被点击了,其他两个却不知道是在哪个item中被点击了,所以我们需要将代码进行在此修改。只需要在MyAdapter中修改代码即可。基本思路是,我们可以将每个被点击的控件中设置一个标记,通过View中的setTag(int key, Object tag)方法设置即可,第一个key必须是一个资源id

资源id的添加 
这里写图片描述

ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="btn" type="id"></item>
    <item name="tv" type="id"></item>
</resources>
  • MyAdapter.java
public class MyAdapter extends BaseAdapter implements View.OnClickListener {
    private Context context;
    private List<String> data;
    public MyAdapter(List<String> data){
        this.data = data;
    }
    @Override
    public int getCount() {
        return data == null ? 0 : data.size();
    }
    @Override
    public Object getItem(int i) {
        return data.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if(context == null)
            context = viewGroup.getContext();
        if(view == null){
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item,null);
            viewHolder = new ViewHolder();
            viewHolder.mTv = (TextView)view.findViewById(R.id.mTv);
            viewHolder.mBtn = (Button)view.findViewById(R.id.mBtn);
            view.setTag(viewHolder);
        }
        viewHolder = (ViewHolder)view.getTag();
        //设置tag标记
        viewHolder.mBtn.setTag(R.id.btn,i);//添加此代码
        viewHolder.mBtn.setText("点我点我"+ i);
        viewHolder.mBtn.setOnClickListener(this);
        viewHolder.mTv.setText(data.get(i));
        //设置tag标记
        viewHolder.mTv.setTag(R.id.tv,i);//添加此代码
        viewHolder.mTv.setOnClickListener(this);
        return view;
}
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.mBtn:
                int b = (int) view.getTag(R.id.btn);
                Toast.makeText(context,"我是按钮 " + b,Toast.LENGTH_SHORT).show();
                break;
            case R.id.mTv:
                int t = (int)view.getTag(R.id.tv);
                Toast.makeText(context,"我是文本" + t,Toast.LENGTH_SHORT).show();
                break;
        }
    }
    static class ViewHolder{
        TextView mTv;
        Button mBtn;
    }
}

这里写图片描述

转载自https://blog.csdn.net/qq_27630169/article/details/52180990

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值