zoukankan      html  css  js  c++  java
  • 一手遮天 Android

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

    一手遮天 Android - view(ListView): ListView 的单选和多选

    示例如下:

    /view/listview/ListViewDemo5.java

    /**
     * ListView 的单选和多选
     *     boolean isItemChecked(int position) - 判断指定索引位置的 item 是否为选中状态
     *     int getCheckedItemPosition() - 单选状态下,获取选中状态的 item 的索引位置
     *     SparseBooleanArray getCheckedItemPositions() - 多选状态下,获取选中状态的 item 的索引位置集合
     *     long[] getCheckedItemIds() - 获取选中状态的 item 的 id 集合(此 id 就是在 BaseAdapter 中通过 getItemId() 返回的 id)
     *     int getCheckedItemCount() - 获取选中状态的 item 的总数
     *     setItemChecked(int position, boolean value) - 设置指定索引位置的 item 的选中状态
     *     clearChoices() - 清除全部 item 的选中状态
     *
     * 实现多选的话,很简单,只要在 xml 中设置 ListView 的 choiceMode 为 multipleChoice 即可,至于如何获取和设置 item 的选中状态只要参考上面那些 api 就好
     * 但是要实现选中状态和未选中状态样式不同的话,则要稍微麻烦一点,因为在 selector 中指定 state_selected="true 的话没有效果
     * 需要在 getView() 的时候,根据当前 item 的选中状态来决定使用哪个 selector
     */
    
    package com.webabcd.androiddemo.view.listview;
    
    import android.content.Context;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.webabcd.androiddemo.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ListViewDemo5 extends AppCompatActivity {
    
        private final String LOG_TAG = "ListViewDemo5";
    
        private ListView _listView1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_view_listview_listviewdemo5);
    
            _listView1 = (ListView) findViewById(R.id.listView1);
    
            sample();
        }
    
        private void sample() {
            // 构造数据
            List<MyData> myDataList = new ArrayList<MyData>();
            for (int i = 0; i < 100; i++) {
                myDataList.add(new MyData(R.drawable.img_sample_son, "name " + i, "comment " + i));
            }
            final MyAdapter myAdapter = new MyAdapter(myDataList, this);
            _listView1.setAdapter(myAdapter);
    
            // item 被选中时触发的事件,但是实测无效
            // _listView1.setOnItemSelectedListener(...);
    
            // item 的点击事件
            _listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // 每次点击 item 后,刷新 ListView 以便绘制当前可见 item 的选中状态
                    myAdapter.notifyDataSetChanged();
                }
            });
        }
    
        // 自定义实体类
        class MyData {
            private int _logoId;
            private String _name;
            private String _comment;
    
            public MyData() {
            }
    
            public MyData(int logoId, String name, String comment) {
                this._logoId = logoId;
                this._name = name;
                this._comment = comment;
            }
    
            public int getLogoId() {
                return _logoId;
            }
    
            public String getName() {
                return _name;
            }
    
            public String getComment() {
                return _comment;
            }
    
            public void setLogoId(int logoId) {
                this._logoId = logoId;
            }
    
            public void setName(String name) {
                this._name = name;
            }
    
            public void setComment(String comment) {
                this._comment = comment;
            }
        }
    
        // 自定义 BaseAdapter
        class MyAdapter extends BaseAdapter {
    
            private List<MyData> _myDataList;
            private Context _context;
    
            public MyAdapter(List<MyData> myDataList, Context context) {
                this._myDataList = myDataList;
                this._context = context;
            }
    
            // 需要呈现的 item 的总数
            @Override
            public int getCount() {
                return _myDataList.size();
            }
    
            // 返回指定索引位置的 item 的对象
            @Override
            public Object getItem(int position) {
                return _myDataList.get(position);
            }
    
            // 返回指定索引位置的 item 的 id
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            // 每构造一个 item 就会调用一次 getView() 来获取这个 item 的 view
            // 每次绘制 item 都会调用 getView()
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder = null;
                if (convertView == null) {
                    convertView = LayoutInflater.from(_context).inflate(R.layout.item_view_listview_listviewdemo5, parent, false);
    
                    holder = new ViewHolder();
                    holder.imgLogo = (ImageView) convertView.findViewById(R.id.imgLogo);
                    holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
                    holder.txtComment = (TextView) convertView.findViewById(R.id.txtComment);
                    holder.button1 = (Button) convertView.findViewById(R.id.button1);
                    convertView.setTag(holder); // 将 holder 保存到 convertView 中
    
                    // 如果 ListView 的 item 中有 button 的话,默认情况下只能响应 button 的点击事件,而 item 的点击事件将被屏蔽
                    // 如果需要既响应 button 的点击事件,又响应 item 的点击事件的话,则需要将 item 的 descendantFocusability 设置为 blocksDescendants(详见:item_view_listview_listviewdemo5.xml)
                    holder.button1.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(ListViewDemo5.this, "button1 clicked: " + v.getTag(), Toast.LENGTH_SHORT).show();
                        }
                    });
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
    
                holder.imgLogo.setBackgroundResource(_myDataList.get(position).getLogoId());
                holder.txtName.setText(_myDataList.get(position).getName());
                holder.txtComment.setText(_myDataList.get(position).getComment());
                holder.button1.setTag(position);
    
                // 如果当前 item 是选中状态则使用选中状态下的样式和点击样式,否则使用正常(未选中)状态下的样式和点击样式
                // 经测试,在 selector 中指定 state_selected="true 的话没有效果,所以就这么写了
                if (_listView1.isItemChecked(position)) {
                    convertView.setBackgroundResource(R.drawable.selector_listview_item_background_selected);
                } else {
                    convertView.setBackgroundResource(R.drawable.selector_listview_item_background_normal);
                }
    
                return convertView;
            }
    
            class ViewHolder {
                ImageView imgLogo;
                TextView txtName;
                TextView txtComment;
                Button button1;
            }
        }
    }
    

    /layout/activity_view_listview_listviewdemo5.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <!--
            choiceMode - 选中模式
                none - 不允许选中
                    对应 java 端的 setChoiceMode(ListView.CHOICE_MODE_NONE)
                singleChoice - 单选模式
                    对应 java 端的 setChoiceMode(ListView.CHOICE_MODE_SINGLE)
                multipleChoice - 多选模式
                    对应 java 端的 setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)
                multipleChoiceModal - 多选模式(需要和 ActionBar ActionMode 配合)
                    对应 java 端的 setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL)
        -->
    
        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:choiceMode="multipleChoice"/>
    
    </LinearLayout>
    
    

    /layout/item_view_listview_listviewdemo5.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!--
        注:
        如果 ListView 的 item 中有 button 的话,默认情况下只能响应 button 的点击事件,而 item 的点击事件将被屏蔽
        如果需要既响应 button 的点击事件,又响应 item 的点击事件的话,则需要将 item 的 descendantFocusability 设置为 blocksDescendants
    -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="10dp"
        android:orientation="horizontal"
        android:descendantFocusability="blocksDescendants">
    
        <ImageView
            android:id="@+id/imgLogo"
            android:layout_width="64dp"
            android:layout_height="64dp" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="1">
    
            <TextView
                android:id="@+id/txtName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#1D1D1D"
                android:textSize="24sp" />
    
            <TextView
                android:id="@+id/txtComment"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#B4B4B4"
                android:textSize="14sp" />
    
        </LinearLayout>
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按钮 1"/>
    
    </LinearLayout>
    
    

    /drawable/selector_listview_item_background_selected.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!--
            注意:
            1、selector 是按照顺序匹配状态的,先匹配到哪个就用哪个。比如一个控件既是 state_enabled="false" 又是 state_pressed="false",那么就看哪个状态的定义靠前就用哪个状态的样式
            2、一个 item 是可以有多个 state 的
        -->
    
        <!--
            本例用于指定 ListView 的 item 在选中状态下的样式和点击样式
        -->
    
        <!--点击样式-->
        <item android:state_pressed="true">
            <shape>
                <solid android:color="@color/green" />
                <stroke android:width="1dp" android:color="@color/blue" />
                <corners android:radius="1dp" />
            </shape>
        </item>
        <!--默认样式-->
        <item>
            <shape>
                <solid android:color="@color/orange" />
            </shape>
        </item>
    </selector>
    

    /drawable/selector_listview_item_background_normal.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!--
            注意:
            1、selector 是按照顺序匹配状态的,先匹配到哪个就用哪个。比如一个控件既是 state_enabled="false" 又是 state_pressed="false",那么就看哪个状态的定义靠前就用哪个状态的样式
            2、一个 item 是可以有多个 state 的
        -->
    
        <!--
            本例用于指定 ListView 的 item 在正常(未选中)状态下的样式和点击样式
        -->
    
        <!--点击样式-->
        <item android:state_pressed="true">
            <shape>
                <solid android:color="@color/green" />
                <stroke android:width="1dp" android:color="@color/blue" />
                <corners android:radius="1dp" />
            </shape>
        </item>
        <!--默认样式-->
        <item>
            <shape>
                <solid android:color="@color/wheat" />
            </shape>
        </item>
    </selector>
    

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

  • 相关阅读:
    HDU 5213 分块 容斥
    HDU 2298 三分
    HDU 5144 三分
    HDU 5145 分块 莫队
    HDU 3938 并查集
    HDU 3926 并查集 图同构简单判断 STL
    POJ 2431 优先队列
    HDU 1811 拓扑排序 并查集
    HDU 2685 GCD推导
    HDU 4496 并查集 逆向思维
  • 原文地址:https://www.cnblogs.com/webabcd/p/android_view_listview_ListViewDemo5.html
Copyright © 2011-2022 走看看