Android实战简易教程-第五十一枪(ListView实现子控件的动态显示和隐藏、checkbox全选和反选)

时间:2022-03-08 09:45:28

前段时间写过一篇文章:Android实战简易教程-第四十七枪(ListView多选-实现点餐系统)有的同学留言建议,可不可以动态控制checkbox的显示和全选反选功能,我研究了一下,发现实现也比较容易,特写下此篇文章。学习就是要有发散思维,要举一反三,大家也可以根据我的实例进行改编,添加和删除一些功能,这样可以提高你对知识的认知!下面我们看一下代码:

1.main.xml:

<?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="match_parent"
android:orientation="vertical"
>

<ListView
android:id="@+id/drink_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/ll_btns"
>
</ListView>

<LinearLayout
android:id="@+id/ll_btns"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >

<Button
android:id="@+id/btn_commit"
android:layout_width="wrap_content"
android:layout_height="58dp"
android:text="确定" />

<Button
android:id="@+id/btn_select"
android:layout_width="wrap_content"
android:layout_height="58dp"
android:text="点餐" />
<Button
android:id="@+id/btn_select_all"
android:layout_width="wrap_content"
android:layout_height="58dp"
android:text="全选" />
<Button
android:id="@+id/btn_select_cancel"
android:layout_width="wrap_content"
android:layout_height="58dp"
android:text="反选" />
</LinearLayout>

</RelativeLayout>
2.item.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:background="#ffffff"    android:orientation="horizontal" >    <CheckBox        android:id="@+id/check_box"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:clickable="false"        android:focusable="false"        android:focusableInTouchMode="true" />    <ImageView        android:id="@+id/food_imager"        android:layout_width="50dp"        android:layout_height="50dp"        android:background="#ffffff" />    <TextView        android:id="@+id/food_name"        android:layout_width="100dp"        android:layout_height="50dp"        android:text="咖啡"        android:gravity="center_vertical"        android:layout_marginLeft="10dp"        android:textSize="18sp" />    <TextView        android:layout_width="wrap_content"        android:layout_height="50dp"        android:text="单价:RMB  "        android:paddingLeft="20dp"        android:textSize="12sp" />    <TextView        android:id="@+id/price"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:paddingRight="10dp"        android:text="18"        android:layout_marginLeft="20dp"        android:textSize="18sp" /></LinearLayout>
3.javabean:

package com.example.info;public class Food {public int food_img;public String food_name;public String food_price;public String text;public int getFood_img() {return food_img;}public void setFood_img(int food_img) {this.food_img = food_img;}public String getFood_name() {return food_name;}public void setFood_name(String food_name) {this.food_name = food_name;}public String getFood_price() {return food_price;}public void setFood_price(String food_price) {this.food_price = food_price;}public Food(int food_img, String food_name, String food_price) {super();this.food_img = food_img;this.food_name = food_name;this.food_price = food_price;}public Food() {super();}@Overridepublic String toString() {return super.toString();}}

4.MyListViewAdapter.java:

package com.example.adapter;import java.util.ArrayList;import java.util.HashMap;import com.example.info.Food;import com.example.listviewselectitem.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.ImageView;import android.widget.TextView;public class MyListViewAdapter extends BaseAdapter {// 填充数据的listprivate ArrayList<Food> foodlist;// 用来控制CheckBox的选中状况private static HashMap<Integer, Boolean> isSelected;// 上下文private Context context;// 用来导入布局private LayoutInflater inflater = null;private Boolean isShow=false;// 构造器public MyListViewAdapter(ArrayList<Food> list, Context context,Boolean isShow) {this.context = context;this.foodlist = list;inflater = LayoutInflater.from(context);isSelected = new HashMap<Integer, Boolean>();this.isShow=isShow;// 初始化数据initDate();}// 初始化isSelected的数据private void initDate() {for (int i = 0; i < foodlist.size(); i++) {getIsSelected().put(i, false);}}@Overridepublic int getCount() {return foodlist.size();}@Overridepublic Object getItem(int position) {return foodlist.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {// 获得ViewHolder对象holder = new ViewHolder();// 导入布局并赋值给convertviewconvertView = inflater.inflate(R.layout.item, null);holder.imageView = (ImageView) convertView.findViewById(R.id.food_imager);holder.txt1 = (TextView) convertView.findViewById(R.id.food_name);holder.txt2 = (TextView) convertView.findViewById(R.id.price);holder.cb = (CheckBox) convertView.findViewById(R.id.check_box);// 为view设置标签convertView.setTag(holder);} else {// 取出holderholder = (ViewHolder) convertView.getTag();}// 获取数据Food food = foodlist.get(position);// 将数据填充到当前convertView的对应控件中if(isShow){holder.cb.setVisibility(View.VISIBLE);}else {holder.cb.setVisibility(View.GONE);}holder.imageView.setImageResource(food.food_img);holder.txt1.setText(food.food_name);holder.txt2.setText(food.food_price);// 设置list中TextView的显示// 根据isSelected来设置checkbox的选中状况holder.cb.setChecked(getIsSelected().get(position));return convertView;}public static HashMap<Integer, Boolean> getIsSelected() {return isSelected;}public static void setIsSelected(HashMap<Integer, Boolean> isSelected) {MyListViewAdapter.isSelected = isSelected;}public static class ViewHolder {public TextView txt1;public TextView txt2;public ImageView imageView;public CheckBox cb;}}

5.MainActivity.java:

package com.example.listviewselectitem;import java.util.ArrayList;import java.util.HashMap;import com.example.adapter.MyListViewAdapter;import com.example.adapter.MyListViewAdapter.ViewHolder;import com.example.info.Food;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.Button;import android.widget.CheckBox;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener, OnItemClickListener {private ListView listView;private Button ok, mSelectButton, mSelectAllButton, mCancelAllButton;private ArrayList<Food> foods = new ArrayList<Food>();private MyListViewAdapter adapter;private CheckBox checkBox;private int checkNum; // 记录选中的条目数量private ArrayList<String> list;private Boolean isShow = false;private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 1) {adapter = new MyListViewAdapter(foods, getApplicationContext(), true);listView.setAdapter(adapter);isShow = true;mCancelAllButton.setVisibility(View.VISIBLE);mSelectAllButton.setVisibility(View.VISIBLE);} else if (msg.what == 0) {adapter = new MyListViewAdapter(foods, getApplicationContext(), false);listView.setAdapter(adapter);isShow = false;mCancelAllButton.setVisibility(View.GONE);mSelectAllButton.setVisibility(View.GONE);}};};protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);initView();// 初始化控件View view = LayoutInflater.from(this).inflate(R.layout.item, null);checkBox = (CheckBox) view.findViewById(R.id.check_box);initData();// 初始化虚拟数据adapter = new MyListViewAdapter(foods, getApplicationContext(), false);isShow = false;listView.setAdapter(adapter);}/** * 初始化控件 */public void initView() {listView = (ListView) findViewById(R.id.drink_list);// listview列表控件ok = (Button) findViewById(R.id.btn_commit);// 确定按钮list = new ArrayList<String>();mSelectButton = (Button) findViewById(R.id.btn_select);mSelectAllButton = (Button) findViewById(R.id.btn_select_all);mCancelAllButton = (Button) findViewById(R.id.btn_select_cancel);mSelectAllButton.setOnClickListener(this);mCancelAllButton.setOnClickListener(this);if (isShow) {mSelectButton.setText("取消");mCancelAllButton.setVisibility(View.VISIBLE);mSelectAllButton.setVisibility(View.VISIBLE);} else {mSelectButton.setText("点餐");mCancelAllButton.setVisibility(View.GONE);mSelectAllButton.setVisibility(View.GONE);}mSelectButton.setOnClickListener(this);ok.setOnClickListener(this);listView.setOnItemClickListener(this);}/** * 初始化虚拟数据 */public void initData() {Class cls = R.drawable.class;// 反射try {foods.add(new Food(cls.getDeclaredField("d1").getInt(null), "猕猴桃汁", "10"));foods.add(new Food(cls.getDeclaredField("d2").getInt(null), "橙汁", "12"));foods.add(new Food(cls.getDeclaredField("d3").getInt(null), "啤酒", "15"));foods.add(new Food(cls.getDeclaredField("d4").getInt(null), "葡萄汁", "10"));foods.add(new Food(cls.getDeclaredField("d5").getInt(null), "纯麦奶茶", "8"));foods.add(new Food(cls.getDeclaredField("d6").getInt(null), "薄荷汁", "10"));foods.add(new Food(cls.getDeclaredField("d7").getInt(null), "柠檬薄荷", "12"));foods.add(new Food(cls.getDeclaredField("d8").getInt(null), "椰子汁", "10"));foods.add(new Food(cls.getDeclaredField("d9").getInt(null), "珍珠奶茶", "9"));foods.add(new Food(cls.getDeclaredField("d10").getInt(null), "石榴汁", "10"));for (int i = 0; i < foods.size(); i++) {list.add("data" + " " + i);};} catch (Exception e) {e.printStackTrace();}}/** * 按钮的点击事件处理 */@Overridepublic void onClick(View v) {int mID = v.getId();switch (mID) {case R.id.btn_commit:myPrice();// 计算总价并输出break;case R.id.btn_select:if (isShow) {Message message = Message.obtain();message.what = 0;handler.sendMessage(message);mSelectButton.setText("点餐");} else {Message message = Message.obtain();message.what = 1;handler.sendMessage(message);mSelectButton.setText("取消");}break;case R.id.btn_select_all:// 遍历list的长度,将MyAdapter中的map值全部设为truefor (int i = 0; i < list.size(); i++) {MyListViewAdapter.getIsSelected().put(i, true);}// 数量设为list的长度checkNum = list.size();// 刷新listview和TextView的显示adapter.notifyDataSetChanged();break;case R.id.btn_select_cancel:// 遍历list的长度,将MyAdapter中的map值全部设为truefor (int i = 0; i < list.size(); i++) {MyListViewAdapter.getIsSelected().put(i, false);}// 数量设为list的长度checkNum = list.size();// 刷新listview和TextView的显示adapter.notifyDataSetChanged();break;}}/** * 计算总价格的方法 */public void myPrice() {HashMap<Integer, Boolean> map = MyListViewAdapter.getIsSelected();String str = "";int money = 0;for (int i = 0; i < map.size(); i++) {if (map.get(i)) {str += (i + " ");money += Integer.parseInt(foods.get(i).food_price);}}MyListViewAdapter.getIsSelected().get("");Toast.makeText(getApplicationContext(), "已选中了" + str + "项,总价钱为:" + money, Toast.LENGTH_SHORT).show();}/** * listview的item的选择的方法 */@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {// 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤ViewHolder holder = (ViewHolder) view.getTag();// 改变CheckBox的状态holder.cb.toggle();// 将CheckBox的选中状况记录下来MyListViewAdapter.getIsSelected().put(position, holder.cb.isChecked());}}
动态控制checkbox显示的原理通过初始化Adapter传入参数,具体可以看代码,比较容易理解的。
看一下动态图效果:

Android实战简易教程-第五十一枪(ListView实现子控件的动态显示和隐藏、checkbox全选和反选)

样子较为丑陋,海涵

喜欢的朋友可以关注我和我的公众号,谢谢!