ListView的点击事件与子控件点击冲突的解决

转发自:http://m.blog.csdn.net/article/details?id=52040100

面试的时候被问到这个问题,只能说见识短啊,没遇到过这个问题,回来赶紧搜了一下解决方案。

如果列表中有一个按钮,那么点击列表时,列表的点击事件将不会被触发,因为点击事件被Button点击事件屏蔽了,因此无法点击。

解决方法

在ItemLayout的根部局加上属性android:descendantFocusability= “blocksDescendants”

在需要点击的控件上如Button加上属性 android:focusable=”false”

这样就可以都触发点击事件了。但是这样的话Button的点击事件的处理是写在Adapter里面的,那如何写在Activity里面呢?使用接口回调可以实现。

  1. 在Adapter里面定义一个接口叫CallBack,接口的抽象方法为click(View view)
  2. 然后在getView方法里面对button的点击事件进行注册,并重写onClick方法,方法体为mCallBack.click(view),也就是说点击Button按钮时就去调用CallBack的click方法
  3. 在getView里面给button setTag,Tag值为position,这样可以记录button所在的具体位置
  4. 在Adapter的抽象方法里面加上CallBack参数,这样当listView设置adapter时就必须new CallBack,然后重写click方法。

这样就利用接口回调实现了在Adapter之外对Button的按钮点击事件处理的功能了

这可能就是传说中的回调吧!!!

Adapter代码


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;

import java.util.List;

/** * Created by DELL on 2016/7/26. */
public class MyAdapter extends BaseAdapter implements View.OnClickListener{

    private Context mContext;
    private LayoutInflater mInflater;
    private List<String> mList;
    private int mItemLayoutId;
    private CallBack mCallBack;
    public MyAdapter(Context context,List<String> list,int itemLayoutId,CallBack callBack){
        mContext=context;
        mInflater=LayoutInflater.from(context);
        mList=list;
        mItemLayoutId=itemLayoutId;
        mCallBack=callBack;
    }

    public interface CallBack{
        public void click(View view);
    }
    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder=null;
        if(convertView==null){
            convertView=mInflater.inflate(mItemLayoutId,null);
            holder=new ViewHolder();
            holder.mButton= (Button) convertView.findViewById(R.id.item_Button);
            convertView.setTag(holder);
        }
        holder= (ViewHolder) convertView.getTag();
        holder.mButton.setText(mList.get(position));
        holder.mButton.setOnClickListener(this);
        holder.mButton.setTag(position);
        return convertView;
    }

    @Override
    public void onClick(View v) {
        mCallBack.click(v);
    }

    static class ViewHolder{
        Button mButton;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

Activity代码

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

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

public class Main2Activity extends AppCompatActivity implements AdapterView.OnItemClickListener,MyAdapter.CallBack{
    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main2);
        mListView= (ListView) findViewById(R.id.main2_listView);
        List<String> mList=new ArrayList<>();
        for (int i=0;i<=50;i++){
            mList.add("按钮 "+i);
        }
        mListView.setAdapter(new MyAdapter(Main2Activity.this, mList, R.layout.item_layout, this));
        mListView.setOnItemClickListener(this);

    }

    @Override
    public void click(View view) {
        Toast.makeText(Main2Activity.this,"按钮 "+view.getTag()+" 被点击了",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(Main2Activity.this,"列表 "+position+" 被点击了",Toast.LENGTH_SHORT).show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

item_layout布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="70dp" android:descendantFocusability= "blocksDescendants" android:background="@android:color/holo_green_dark" android:padding="10dp">

    <Button  android:id="@+id/item_Button" android:layout_width="100dp" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:layout_alignParentRight="true" android:focusable="false" />

</RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

如图

《ListView的点击事件与子控件点击冲突的解决》 
《ListView的点击事件与子控件点击冲突的解决》

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/bsmmaoshenbo/article/details/70169991
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞