关于expandablelistview中加左滑删除

参考:blog_Lei 的 android自定义侧滑LisitView(包含编辑、删除)

三个xml。分别是页面、ExpandableListView的Group、ExpandableListView的item:
1、activity_travel_list_create.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_travel_list_create"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ac2121"
    tools:context="com.foodie.mango.TravelListCreateActivity">



    <MyUI.SlideExpandableListView
        android:id="@+id/exlist_create"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:groupIndicator="@null"
        android:childDivider="#00ffffff"/>
</RelativeLayout>

2、item_exlist_addnum_group.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="horizontal">

    <TextView
        android:id="@+id/tv_group_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="10dp"
        android:paddingLeft="23dp"
        android:textSize="12sp"
        android:textColor="#FFBBBBBB"/>

</LinearLayout>

3、item_exlist_addnum_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="52dp"
    android:layout_marginLeft="0dp"
    android:orientation="horizontal" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="0dp"
        android:orientation="horizontal">

        <RelativeLayout
            android:id="@+id/rlTop"
            android:layout_width="match_parent"
            android:layout_marginLeft="0dp"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/tvName"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:layout_marginLeft="15dp"
                android:layout_centerVertical="true"
                android:gravity="left|center_vertical"
                android:textSize="14sp"
                android:textColor="#FFFFFF" />

            <ImageView
                android:id="@+id/btMinus"
                android:layout_toLeftOf="@+id/tvNum"
                android:layout_marginLeft="0dp"
                android:layout_width="44dp"
                android:layout_height="match_parent"
                android:background="#00000000"/>

            <TextView
                android:id="@+id/tvNum"
                android:layout_toLeftOf="@+id/btAdd"
                android:layout_width="44dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="0dp"
                android:gravity="center"
                android:text="1"
                android:textSize="14sp"
                android:textColor="#FFFFFF"
                android:background="#00000000"/>

            <ImageView
                android:id="@+id/btAdd"
                android:layout_width="44dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="0dp"
                android:layout_alignParentRight="true"
                android:background="#00000000"/>
        </RelativeLayout>

    </RelativeLayout>

    <!--delete-->
    <TextView
        android:id="@+id/delete"
        android:layout_width="80dp"
        android:layout_height="match_parent"
        android:background="#FFC20E23"
        android:gravity="center"
        android:paddingLeft="20dp"
        android:textColor="#FFFFFF"
        android:paddingRight="20dp"
        android:text="删除" />

</LinearLayout>

4、MyBaseExpandableListAdapter1.java

package HTTPUtil;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import com.foodie.mango.R;

import java.util.ArrayList;

import domain.ListItem;

import static com.foodie.mango.R.id.tvNum;

/**
 * Created by peng on 2018/4/18.
 */

public class MyBaseExpandableListAdapter1 extends BaseExpandableListAdapter {
    private ArrayList<String> gData;
    private ArrayList<ArrayList<ListItem>> iData;
    private Context mContext;
    private OnClickListenerEditOrDelete onClickListenerEditOrDelete;

    public MyBaseExpandableListAdapter1(ArrayList<String> gData, ArrayList<ArrayList<ListItem>> iData, Context mContext) {
        this.gData = gData;
        this.iData = iData;
        this.mContext = mContext;
    }

    @Override
    public int getGroupCount() {
        return gData.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return iData.get(groupPosition).size();
    }

    @Override
    public String getGroup(int groupPosition) {
        return gData.get(groupPosition);
    }

    @Override
    public ListItem getChild(int groupPosition, int childPosition) {
        return iData.get(groupPosition).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    //取得用于显示给定分组的视图. 这个方法仅返回分组的视图对象
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

        MyBaseExpandableListAdapter1.ViewHolderGroup groupHolder;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.item_exlist_addnum_group, parent, false);
            groupHolder = new MyBaseExpandableListAdapter1.ViewHolderGroup();
            groupHolder.tv_group_title = (TextView) convertView.findViewById(R.id.tv_group_title);
            convertView.setTag(groupHolder);
        }else{
            groupHolder = (MyBaseExpandableListAdapter1.ViewHolderGroup) convertView.getTag();
        }
        groupHolder.tv_group_title.setText(gData.get(groupPosition));
        return convertView;
    }

    //取得显示给定分组给定子位置的数据用的视图
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final ViewHolderItem itemHolder;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.item_exlist_addnum_item, parent, false);
            itemHolder = new MyBaseExpandableListAdapter1.ViewHolderItem();
            itemHolder.tvName=(TextView)convertView.findViewById(R.id.tvName);
            itemHolder.checkBox=(CheckBox) convertView.findViewById(R.id.imgLamp);
            itemHolder.tvNum = (TextView)convertView.findViewById(R.id.tvNum);
            itemHolder.btAdd = (ImageView) convertView.findViewById(R.id.btAdd);
            itemHolder.btMinus = (ImageView) convertView.findViewById(R.id.btMinus);
            itemHolder.tvDelete=(TextView)convertView.findViewById(R.id.delete);
            convertView.setTag(itemHolder);//store up viewHolder
        }else{
            itemHolder = (MyBaseExpandableListAdapter1.ViewHolderItem) convertView.getTag();
        }
        itemHolder.btMinus.setImageResource(R.mipmap.icon_minus);
        itemHolder.btAdd.setImageResource(R.mipmap.icon_add);
        itemHolder.tvName.setText(iData.get(groupPosition).get(childPosition).getiName());
        itemHolder.tvDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onClickListenerEditOrDelete!=null){
                    onClickListenerEditOrDelete.OnClickListenerDelete(groupPosition,childPosition);
                }
            }
        });
        itemHolder.btAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String numStr = itemHolder.tvNum.getText().toString();
                int Num = Integer.parseInt(numStr);
                if ((numStr!=null)&&(numStr!="0")){
                    Num =  Num + 1;
                    itemHolder.tvNum.setText(Num+"");
                }
            }
        });

        itemHolder.btMinus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String numStr = itemHolder.tvNum.getText().toString();
                int Num = Integer.parseInt(numStr);
                if ((numStr!=null)&&(Num>=1)){
                    Num =  Num - 1;
                    itemHolder.tvNum.setText(Num+"");
                }else{
                    itemHolder.tvNum.setText("0");
                }
            }
        });
        return convertView;
    }

    //设置子列表是否可选中
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }


    private static class ViewHolderGroup{
        TextView tv_group_title;
    }

    private static class ViewHolderItem{
        TextView tvName,tvDelete,tvNum;
        CheckBox checkBox;
        ImageView btMinus,btAdd;
    }

    public interface OnClickListenerEditOrDelete{
        void OnClickListenerDelete(int groupPosition,int position);
    }

    public void setOnClickListenerEditOrDelete(OnClickListenerEditOrDelete onClickListenerEditOrDelete1){
        this.onClickListenerEditOrDelete=onClickListenerEditOrDelete1;
    }
}

5、TravelListCreateActivity.java

package com.foodie.mango;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ExpandableListView;
import android.widget.Toast;

import java.util.ArrayList;

import HTTPUtil.MyBaseExpandableListAdapter1;
import domain.ListItem;

public class TravelListCreateActivity extends AppCompatActivity{

    private ArrayList<String> gData = new ArrayList<String>();
    private ArrayList<ArrayList<ListItem>> iData = new ArrayList<ArrayList<ListItem>>();
    private ArrayList<ListItem> lData = new ArrayList<ListItem>();
    private Context mContext;
    private ExpandableListView exlist_lol;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //设置状态栏为透明
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
        }

        setContentView(R.layout.activity_travel_list_create);
        mContext = TravelListCreateActivity.this;
        exlist_lol = (ExpandableListView) findViewById(R.id.exlist_create);


        //数据准备
//        gData = new ArrayList<String>();
//        iData = new ArrayList<ArrayList<ListItem>>();
        gData.add("分类1");
        gData.add("分类2");

//        lData = new ArrayList<ListItem>();

        //1组
        lData.add(new ListItem("羽绒服", "1"));
        lData.add(new ListItem("毛巾", "2"));
        iData.add(lData);
        //2组
        lData = new ArrayList<ListItem>();
        lData.add(new ListItem("洗面奶", "1"));
        lData.add(new ListItem("手机充电器", "2"));
        iData.add(lData);

        final MyBaseExpandableListAdapter1 myAdapter = new MyBaseExpandableListAdapter1(gData, iData, mContext);
        exlist_lol.setAdapter(myAdapter);
        myAdapter.setOnClickListenerEditOrDelete(new MyBaseExpandableListAdapter1.OnClickListenerEditOrDelete() {
            @Override
            public void OnClickListenerDelete(int groupPosition, int position) {
                Toast.makeText(mContext, "删除第" + groupPosition+"组的第"+position+"个值", Toast.LENGTH_SHORT).show();
                iData.get(groupPosition).remove(position);//删除选中的某列
                if (iData.get(groupPosition).size() <= 0){//如果删除后,该组下没成员,那么移除标题和该组的数据集合
                    iData.remove(groupPosition);
                    gData.remove(groupPosition);
                }
                myAdapter.notifyDataSetChanged();//通知Adapter更新数据
            }
        });
        for (int i = 0; i < iData.size(); i++) {//首次加载就全部打开
            exlist_lol.expandGroup(i);
        }

        //为列表设置点击事件
//        exlist_lol.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
//            @Override
//            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
//                Toast.makeText(mContext, "你点击了:" + iData.get(groupPosition).get(childPosition).getiName(), Toast.LENGTH_SHORT).show();
//                return true;
//            }
//        });
//        exlist_lol.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {//把ExpandableListView的组点击事件屏蔽,不能点击收缩
//            @Override
//            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
//                return true;
//            }
//        });
    }
}

6、实体类


public class ListItem {
    private String iName;
    private String iNum;

    public ListItem() {
    }

    public ListItem(String iName,String iNum) {
        this.iName = iName;
        this.iNum = iNum;
    }

    public String getiName() {
        return iName;
    }

    public String getiNum() {
        return iNum;
    }

    public void setiName(String iName) {
        this.iName = iName;
    }

    public void setiNum(String iNum) {
        this.iNum = iNum;
    }
}

7、自定义的SlideExpandableListView.java,在java下的MyUI文件夹下

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;

/**
 * Created by peng on 2018/4/18.
 */

public class SlideExpandableListView extends ExpandableListView {
    private int mScreenWidth;   // 屏幕宽度
    private int mDownX;         // 按下点的x值
    private int mDownY;         // 按下点的y值
    private int mDeleteBtnWidth;// 删除按钮的宽度

    private boolean isDeleteShown;  // 删除按钮是否正在显示

    private ViewGroup mPointChild;  // 当前处理的item
    private LinearLayout.LayoutParams mLayoutParams;    // 当前处理的item的LayoutParams

    public SlideExpandableListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlideExpandableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // 获取屏幕宽度
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenWidth = dm.widthPixels;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN://初次触摸
                performActionDown(ev);
                break;
            case MotionEvent.ACTION_MOVE://滑动
                super.onTouchEvent(ev);//调用父类方法,防止滑动时触发点击事件
                return performActionMove(ev);
            case MotionEvent.ACTION_UP://抬起
                performActionUp();
                break;
        }
        return super.onTouchEvent(ev);
    }

    // 处理action_down事件
    private void performActionDown(MotionEvent ev) {
        if(isDeleteShown) {
            turnToNormal();
        }

        mDownX = (int) ev.getX();
        mDownY = (int) ev.getY();
        // 获取当前点的item
        mPointChild = (ViewGroup) getChildAt(pointToPosition(mDownX, mDownY)
                - getFirstVisiblePosition());
        // 获取删除按钮的宽度
        mDeleteBtnWidth = mPointChild.getChildAt(1).getLayoutParams().width;
        mLayoutParams = (LinearLayout.LayoutParams) mPointChild.getChildAt(0)
                .getLayoutParams();
        mLayoutParams.width = mScreenWidth;
        mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
    }

    // 处理action_move事件
    private boolean performActionMove(MotionEvent ev) {
        int nowX = (int) ev.getX();
        int nowY = (int) ev.getY();
        if(Math.abs(nowX - mDownX) > Math.abs(nowY - mDownY)) {
            // 如果向左滑动
            if(nowX < mDownX) {
                // 计算要偏移的距离
                int scroll = (nowX - mDownX) / 2;
                // 如果大于了删除按钮的宽度, 则最大为删除按钮的宽度
                if(-scroll >= mDeleteBtnWidth) {
                    scroll = -mDeleteBtnWidth;
                }
                // 重新设置leftMargin
                mLayoutParams.leftMargin = scroll;
                mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

    // 处理action_up事件
    private void performActionUp() {
        // 偏移量大于button的一半,则显示button
        // 否则恢复默认
        if(-mLayoutParams.leftMargin >= mDeleteBtnWidth / 2) {
            mLayoutParams.leftMargin = -mDeleteBtnWidth;
            isDeleteShown = true;
        }else {
            turnToNormal();
        }

        mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
    }
    /**
     * 变为正常状态
     */
    public void turnToNormal() {
        mLayoutParams.leftMargin = 0;
        mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
        isDeleteShown = false;
    }
    /**
     * 当前是否可点击
     * @return 是否可点击
     */
    public boolean canClick() {
        return !isDeleteShown;
    }
}

图片:icon_minus和icon_add(上传不显示,可以网上下载下,就是加减好的图片)放在mipmap下即可:
+按钮的图片
—按钮的图片

问题:
这样的通过自定义组件的方式,对listview还好,对expandablelistview就有个问题,左滑显示删除按钮只能在点击了某个列后才能生效,即只有单击后才能滑动,否则会不响应或者直接退出APP;

猜你喜欢

转载自blog.csdn.net/qq_38969990/article/details/80022288
今日推荐