Android实现可折叠的listview

最近在项目中遇到了一个问题,要求实现一个可点击扩展的列表,在网上找了很多代码资源,但是始终没有达到想要的效果,也许有人会说,已经有了一个现成的ExpendableList供我们使用了,但是细心的朋友也许会发现,通过这个view实现的扩展与隐藏,点击区域是有限的,也就是说,我们只能通过点击头部来显示隐藏底部,但是当底部显示的时候,我们对于占大片区域的底部的点击是没有任何效果的。你总不能找产品去说,我们安卓实现不了这样的功能,(太怂了吧)。人家产品一句话就可以把你怼的体无完肤(ios怎么可以?)最烦的就是这句话,为了证明咱们不比人家怂,于是开始证明,人家有的咱家都有。

经过研究,终于解决,废话不多说,直接上代码

package com.example.xuning.myexpendlistview.;


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 android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;


/**
 * Created by: xuning
 * Date: 2017/11/1 0001.
 * Description:可以折叠的listview,
 */


public class ExpandListAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<HashMap<String, String>> list;
    private int currentItem = -1; //用于记录点击的 Item 的 position,是控制 item 展开的核心
    public ExpandListAdapter(Context context,
                             ArrayList<HashMap<String, String>> list) {
        super();
        this.context = context;
        this.list = list;
    }


    @Override
    public int getCount() {
        return list.size();
    }


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


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


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(
                    R.layout.item2, parent, false);
            holder = new ViewHolder();
            holder.showArea = (LinearLayout) convertView.findViewById(R.id.layout_showArea);
            holder.tvPhoneType = (TextView) convertView
                    .findViewById(R.id.tv_phoneType);
            holder.tvDiscount = (TextView) convertView
                    .findViewById(R.id.tv_discount);
            holder.tvPrice = (TextView) convertView
                    .findViewById(R.id.tv_price);
            holder.tvTime = (TextView) convertView
                    .findViewById(R.id.tv_time);
            holder.tvNum = (TextView) convertView
                    .findViewById(R.id.tv_num);
            holder.btnBuy = (Button) convertView
                    .findViewById(R.id.btn_buy);
            holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.layout_hideArea);
            holder.wholeArea= (LinearLayout) convertView.findViewById(R.id.layout_wholeArea);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }


        HashMap<String, String> item = list.get(position);


        // 注意:我们在此给响应点击事件的区域(我的例子里是 showArea 的线性布局)添加Tag,为了记录点击的 position,我们正好用 position 设置 Tag
//        holder.showArea.setTag(position);
//        holder.hideArea.setTag(position);


        holder.tvPhoneType.setText(item.get("phoneType"));
        holder.tvDiscount.setText(item.get("discount"));
        holder.tvPrice.setText(item.get("price"));
        holder.tvTime.setText(item.get("time"));
        holder.tvNum.setText(item.get("num"));


/////////////////////////////////////////////////////////////////////////////////////
        //这种方式是根据点击的条目位置进行判断,点击哪一行,则显示哪一行,其余的行不显示
        //根据 currentItem 记录的点击位置来设置"对应Item"的可见性(在list依次加载列表数据时,每加载一个时都看一下是不是需改变可见性的那一条)
//        if (currentItem == position) {
//            holder.hideArea.setVisibility(View.VISIBLE);
//        } else {
//            holder.hideArea.setVisibility(View.GONE);
//        }
//        holder.hideArea.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                int myTag= (int) v.getTag();
//                if (myTag==currentItem){
//                    currentItem=-1;
//                }else {
//                    currentItem=myTag;
//                }
//                notifyDataSetChanged();
//            }
//        });
        /////////////////////////////////////////////////////////////////////////////


        ///////////////////////////////////////////////////////////////////////
        //下面这种方式是定义一个变量来控制当前条目隐藏内容的显示与隐藏,可以显示多个
        if (holder.isExpended){
            holder.hideArea.setVisibility(View.VISIBLE);
        }else {
            holder.hideArea.setVisibility(View.GONE);
        }
//整个item布局的点击事件
        final ViewHolder finalHolder = holder;
        holder.wholeArea.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finalHolder.isExpended=!finalHolder.isExpended;
                notifyDataSetChanged();
            }
        });
        holder.btnBuy.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View view) {
                Toast.makeText(context, "点击购买了", Toast.LENGTH_SHORT).show();
            }
        });

holder.tvPhoneType.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View view) {
                Toast.makeText(context, "你好", Toast.LENGTH_SHORT).show();
            }
        });

        return convertView;
    }


    private static class ViewHolder {
        private LinearLayout wholeArea;
        private LinearLayout showArea;


        private TextView tvPhoneType;
        private TextView tvDiscount;
        private TextView tvPrice;
        private TextView tvTime;
        private TextView tvNum;
        private Button btnBuy;


        private RelativeLayout hideArea;
        private boolean isExpended;
    }
}

我在代码中实现了两种方式,一种是点击哪个哪个展开,其余的关闭,另一种是点击哪项哪项展开,对别的项不产生影响,读者可以根据自己的需求进行使用。

其他的就不用我说了吧,就是一个listview,一个布局。

欢迎读者批评指正。

猜你喜欢

转载自blog.csdn.net/m0_37550680/article/details/78424158