1. 程式人生 > >ListView中嵌入佈局的Button或多個點選事件

ListView中嵌入佈局的Button或多個點選事件

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

這裡寫圖片描述

基本已經實現了,案例比較簡單,適合初學者。