ListView的展开合并

这篇博客介绍了如何在ListView中实现多布局,并详细讲解了ListView的展开和合并功能。默认展开‘今天’,点击其他日期会切换展开状态,而再次点击‘今天’会改变所有项的状态。实现思路包括维护ListView的状态和记录上次及本次点击的项。代码实现部分涉及XML布局和Activity代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ListView的多布局
ListView的展开和收起是在上一篇ListView的多布局的基本上写,整体布局只有一个ListView。
今天、昨天、一周内、更早最多只有一个是展开的状态,默认展开的是今天。
当点击今天时,则今天合并,即此时所有的都是合并状态;再次点击今天时,则今天展开;
当点击其他图片时,今天合并,则被点击的展开。

实现效果:
这里写图片描述

一、实现思路
1、ListView的状态,ListView只有都合并和某一个打开2种状态。
2、当本次点击的上一次点击的是同一张图片时,若当前处于合并状态则展开,若当前处于展开状态则合并;
当本次点击的和上次点击的图片不同时,则本次点击的图片展开,上次点击的图片则要处于合并状态。
因此,我定义了3个变量boolean isopen用于记录当前的状态,展开还是合并,
int last_click上次点击的图片,int cur_click本次点击的图片。

二、代码实现
XML代码:

 <ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:divider="@null"
    android:listSelector="#0000"
    android:scrollbars="none" />

Activity代码:

public class ListViewActivity extends Activity {
    private List<List<Object>> list;
    private List<Object> data;
    private ListViewAdapter adapter;
    private ListView listView;
    private int last_click;
    private boolean isopen;
    private int[] image = {
        R.mipmap.ic_today_gaokao, 
        R.mipmap.ic_yesterday,
        R.mipmap.ic_week, 
        R.mipmap.ic_earlier
     };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_view);
        init();
        loadData();
    }

    private void loadData() {
        List<Object> list1 = new ArrayList<>();
        list1.add(image[0]);
        list1.add("Android高级1");
        list1.add("Android高级2");
        list1.add("Android高级3");
        list1.add("Android高级4");
        list.add(list1);

        list1 = new ArrayList<>();
        list1.add(image[1]);
        list1.add("Android基础2");
        list1.add("Android基础3");
        list1.add("Android基础4");
        list.add(list1);

        list1 = new ArrayList<>();
        list1.add(image[2]);
        list1.add("Android基础1");
        list.add(list1);

        list1 = new ArrayList<>();
        list1.add(image[3]);
        list1.add("Java基础1");
        list1.add("Java基础2");
        list1.add("Java基础3");
        list.add(list1);

        //设置默认第一个展开
        getData(0);
    }

    private void init() {
        listView = (ListView) findViewById(R.id.listView);
        list = new ArrayList<>();
        data = new ArrayList<>();

        adapter = new ListViewAdapter(this, data);
        listView.setAdapter(adapter);
        last_click = -1;
        isopen = true;

        /*
            为ListView Item中的ImageView和TextView设置点击事
            通过设置的tag,找到点击是某项
        */
        adapter.setOnItemClick(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Object tag = v.getTag();
                if (tag instanceof Integer) {
                    int img = (int) tag;
                    for (int i = 0; i < image.length; i++) {
                        if (img == image[i]) {
                            getData(i);
                            break;
                        }
                    }
                } else if (tag instanceof String) {
                    String ret = (String) tag;
                    Toast.makeText(ListViewActivity.this, "点击了  " + ret, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void getData(int index) {
        //清空数据
        data.clear();

        /*
          若当前处于展开状态,本次点击和上次点击相同,
          当前点击的状态展开变成合并,合并变成展开;
          本次点击和上次点击不同,则当前点击的状态时展开;
          若当前处于合并状态,则当前点击的处于展开状态。
        */
        if (isopen) {
            if (index == last_click) {
                isopen = !isopen;
            } else {
                isopen = true;
            }
        } else {
            isopen = true;
        }

        for (int i = 0; i < list.size(); i++) {
            /*
                通过修改数据的长度来设置当前的展开和合并状态。
                只要点击当前图片处于展开状态,数据长度为list.size(),
                否则长度为1。
            */
            int len = list.get(i).size();
            if (i != index || !isopen) {
                len = 1;
            }

            for (int j = 0; j < len; j++) {
                data.add(list.get(i).get(j));
            }
        }
        Log.i("info","数据=" + "cur_click=" + index + ",last_click=" + last_click + ",isopen=" + isopen);
        last_click = index;
        adapter.notifyDataSetChanged();
    }
}
Adapter代码:
public class ListViewAdapter extends BaseAdapter {
    private Context context;
    private List<Object> list;
    private View.OnClickListener onItemClick;

    public ListViewAdapter(Context context, List<Object> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        int ret = 0;
        if (list != null) {
            ret = list.size();
        }
        return ret;
    }

    @Override
    public int getItemViewType(int position) {
        int ret = 0;
        Object object = list.get(position);
        if (object instanceof String) {
            ret = 0;
        } else if (object instanceof Integer) {
            ret = 1;
        }
        return ret;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

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

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

    public void setOnItemClick(View.OnClickListener onItemClick) {
        this.onItemClick = onItemClick;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (getItemViewType(position) == 0) {
            convertView = bindTv(position, convertView, parent);
        } else if (getItemViewType(position) == 1) {
            convertView = bindImg(position, convertView, parent);
        }
        return convertView;
    }

    private View bindImg(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_recent_img, null);
            holder = new ViewHolder();
            holder.img = (ImageView) convertView.findViewById(R.id.img_recent);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Object object = list.get(position);
        if (object instanceof Integer) {
            int img = (int) object;
            holder.img.setImageResource(img);
        }
        holder.img.setTag(object);
        holder.img.setOnClickListener(onItemClick);
        return convertView;
    }

    private View bindTv(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_recent_tv, null);
            holder = new ViewHolder();
            holder.tv = (TextView) convertView.findViewById(R.id.tv_recent);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Object object = list.get(position);
        if (object instanceof String) {
            String ret = (String) object;
            holder.tv.setText(ret);
        }
        holder.tv.setTag(object);
        holder.tv.setOnClickListener(onItemClick);
        return convertView;
    }

    class ViewHolder {
        TextView tv;
        ImageView img;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值