Android开发之ExpandableListView可拓展列表和子item左滑结合

Hello!各位大神好,这是我的第一篇博客,大二学生初学安卓还不到几个月,所以希望不足之处能够多多指教。
在Android开发中,我们经常会遇到点击,展开,可拓展列表的使用,同时可恶的产品经理还要求你在可拓展列表下增加左滑按钮的功能。那这两个功能如何具体相互结合实现呢?接下来先看一下结果效果图。可拓展列表+左滑Item
怎么样?是不是你想要的呢?
接下来我们分两步来看一下这个功能。
首先是可拓展列表ExpandableListView的功能实现。
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.easeplan.com.view.SwipeExpandableListView
            android:id="@+id/exlist_lol"
            android:childIndicator="@null"
            android:groupIndicator="@null"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:childDivider="#ffffff"/>
</LinearLayout>

有注意到,我调用的SwipeExpandableListView是一个用java自定义的布局,由于代码太长我就不发出来了,有需要的小伙伴可在下面留言。
item_exlist_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"
	android:padding="5dp">
	<ImageView
	    android:id="@+id/img_icon1"
	    android:layout_width="64dp"
	    android:layout_height="58dp"
	    android:src="@mipmap/ic_launcher"
	    android:focusable="false"
	    android:paddingLeft="6dp"
	    />
	<TextView
	    android:id="@+id/tv_group_name"
	    android:layout_width="match_parent"
	    android:layout_height="56dp"
	    android:gravity="center_vertical"
	    android:paddingLeft="12dp"
	    android:text="AP"
	    android:textStyle="bold"
	    android:textSize="20sp" />
 </LinearLayout>

可以看到,在这个布局中,我是设置了一个图片作为头像,还有文字作为标题。而图片可以换成你想要的,但是也可以在java代码中设置。而我是选择了在java代码中设置。
接着是左滑按钮的实现。
item_exlist_item.xml

<?xml version="1.0" encoding="utf-8"?>
<com.easeplan.com.view.SwipeItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!--子列表布局-->
	<FrameLayout
	    android:layout_width="match_parent"
	    android:layout_height="match_parent">
		<LinearLayout
		    android:layout_width="270dp"
		    android:layout_height="59dp"
		    android:orientation="horizontal"
		    android:layout_gravity="right"
		    android:id="@+id/linear">
		    <!--垂直布局-->
		   <LinearLayout
		        android:layout_width="270dp"
		        android:layout_height="59dp"
		        android:orientation="vertical"
		        android:background="@drawable/shape2"
		        android:id="@+id/id_front">
		    <TextView
		        android:id="@+id/tv_name"
		        android:layout_width="270dp"
		        android:layout_height="wrap_content"
		        android:layout_weight="1"
		        android:focusable="true"
		        android:text="提莫"
		        android:textSize="18sp"
		        android:gravity="left"
		        android:paddingTop="6dp"
		        android:paddingLeft="9dp"
		        android:textColor="#ffffff"/>
		        <TextView
		            android:layout_width="270dp"
		            android:layout_height="wrap_content"
		            android:focusable="true"
		            android:textSize="10sp"
		            android:text="提莫"
		            android:gravity="left"
		            android:paddingBottom="10dp"
		            android:paddingLeft="12dp"
		            android:id="@+id/tv_msg"
		            android:textColor="#ffffff"/>
		    </LinearLayout>
	</LinearLayout>
</FrameLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent">
	    <Button
	        android:id="@+id/stick"
	        android:text="添加到日程"
	        android:textColor="#ffffff"
	        android:textSize="16sp"
	        android:background="#ff8000"
	        android:layout_width="100dp"
	        android:layout_height="match_parent"/>
	    <Button
	        android:id="@+id/delete"
	        android:text="删除"
	        android:textColor="#ffffff"
	        android:textSize="16sp"
	        android:background="#ff0000"
	        android:layout_width="80dp"
	        android:layout_height="match_parent"/>
    </LinearLayout>
</com.easeplan.com.view.SwipeItemLayout>

分析代码可知,我是在子item里面设置了垂直方向上的两行文字,接着在线性布局中设置了两个按钮。需要注意是,左滑布局我仍然用的是一个自定义的布局,需要的可以在下方留言。
好啦,布局文件就这么多,至于drawable、values文件还有注册文件就自己写吧。
接下来看一下java代码吧。。。
实体类GroupBean.java

public class GroupBean extends LitePalSupport {
    private int gId;
    private String gName;//主标题名字
 
    public GroupBean(int gId, String gName) {
        this.gName = gName;
        this.gId=gId;
    }
    public int getgId() {
        return gId;
    }
    public void setgId(int gId) {
        this.gId = gId;
    }
    public String getgName() {
        return gName;
    }
    public void setgName(String gName) {
        this.gName = gName;
    }

}

实体类Item.java

public class Item {
    private String iName;//文字名字
    private String iMsg;//文字信息

    public Item() {
    }

    public Item(String iName,String iMsg) {
        this.iName = iName;
        this.iMsg=iMsg;

    }
    public String getiName() {
        return iName;
    }

    public String getiMsg(){return iMsg;}

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

    public void setiMsg(String iMsg){this.iMsg=iMsg;}
}

适配器MyBaseExpandableListViewAdapter.java

public class MyBaseExpandableListViewAdapter extends BaseExpandableListAdapter {

    private ArrayList<GroupBean> gData;
    private ArrayList<ArrayList<Item>> iData;
    private Context mContext;
    private OnClickListenerEditOrDelete onClickListenerEditOrDelete;
    private boolean text_add=false;

    public MyBaseExpandableListViewAdapter(ArrayList<GroupBean> gData, 				     ArrayList<ArrayList<Item>> 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 GroupBean getGroup(int groupPosition) {
        return gData.get(groupPosition);
    }
    @Override
    public Item 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) {

        ViewHolderGroup groupHolder;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.item_exlist_group, parent, false);
            groupHolder = new ViewHolderGroup();
            groupHolder.tv_group_name = (TextView) convertView.findViewById(R.id.tv_group_name);//文字
            groupHolder.img_group = (ImageView) convertView.findViewById(R.id.img_icon1);//图片
            convertView.setTag(groupHolder);
        }else{
            groupHolder = (ViewHolderGroup) convertView.getTag();
        }
        //文字与图片显示
        groupHolder.img_group.setImageResource(gData.get(groupPosition).getgId());
        groupHolder.tv_group_name.setText(gData.get(groupPosition).getgName());
        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_item, parent, false);
            itemHolder = new ViewHolderItem();
            itemHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);//子列表中上标题
            itemHolder.tv_msg = (TextView) convertView.findViewById(R.id.tv_msg);//子列表中下标题
            itemHolder.linear=convertView.findViewById(R.id.linear);//整个子列表
            itemHolder.delete=(Button)convertView.findViewById(R.id.delete);//删除按钮
            itemHolder.add=(Button)convertView.findViewById(R.id.stick);//添加到日程按钮
            convertView.setTag(itemHolder);
            itemHolder.linear.setOnClickListener(new View.OnClickListener() {//子列表按钮
                @Override
                public void onClick(View v) {
                    Intent intent=new Intent(mContext,EventInfoActivity.class);//点击Item可跳转的界面
                    mContext.startActivity(intent);
                }
            });
            itemHolder.delete.setOnClickListener(new View.OnClickListener() {//删除按钮
                @Override
                public void onClick(View v) {//删除对话框
                    AlertDialog alert=new AlertDialog.Builder(mContext).create();
                    alert.setIcon(R.drawable.ic_notifications_black_24dp);
                    alert.setTitle("请问您确定要删除吗?");
                    alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {//点击确定删除后
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (onClickListenerEditOrDelete!=null){
                                onClickListenerEditOrDelete.OnClickListenerDelete(groupPosition,childPosition);
                            }
                        }
                    });
                    alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });
                   alert.show();
                }
            });
            itemHolder.add.setOnClickListener(new View.OnClickListener() {//添加到日程按钮
                @Override
                public void onClick(View v) {
                        Toast.makeText(mContext,"添加成功!",Toast.LENGTH_SHORT).show();
                }
            });
        }else{
            itemHolder = (ViewHolderItem) convertView.getTag();
        }
        //子列表文字显示
        itemHolder.tv_name.setText(iData.get(groupPosition).get(childPosition).getiName());
        itemHolder.tv_msg.setText(iData.get(groupPosition).get(childPosition).getiMsg());
        return convertView;
    }

    //设置子列表是否可选中
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
    //自定义Group类
    private static class ViewHolderGroup{
        private TextView tv_group_name;
        private ImageView img_group;
    }
    //自定义Item类
    private static class ViewHolderItem{
        private TextView tv_name;
        private TextView tv_msg;
        private View linear;
        private Button delete;
        private Button add;
    }
    //删除接口
    public interface OnClickListenerEditOrDelete{
        void OnClickListenerDelete(int groupPosition, int position);
    }
    public void setOnClickListenerEditOrDelete(OnClickListenerEditOrDelete onClickListenerEditOrDelete1){
        this.onClickListenerEditOrDelete=onClickListenerEditOrDelete1;
    }

}

碎片Fragment中的代码,具体需要的同学可以改成activity
Fragment_people.java

public class Fragment_people extends Fragment {
  
    private ArrayList<GroupBean> gData = null;//group
    private ArrayList<ArrayList<Item>> iData = null;//item列表
    private ArrayList<Item> lData = null;//item
    
    private Context mContext;//相当于fragment_people.this
    private SwipeExpandableListView exlist_lol;//group
    private MyBaseExpandableListViewAdapter myAdapter = null;//item适配器
  
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.mfragment_people, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mContext = getActivity();
        exlist_lol = (SwipeExpandableListView) getActivity().findViewById(R.id.exlist_lol);
        linear = (View) getActivity().findViewById(R.id.linear);//最近的组织获得实例
        delete = (Button) getActivity().findViewById(R.id.delete);//最近的好友获得实例
        //TODO:这数据是初始化的,动态到时候需要后台连接
        //可拓展列表头部图片和文字定义
        gData = new ArrayList<GroupBean>();
        iData = new ArrayList<ArrayList<Item>>();
        gData.add(new GroupBean(R.mipmap.xiaokui, "学生会秘书处"));
        gData.add(new GroupBean(R.mipmap.yingyu, "大学英语—34班"));
        gData.add(new GroupBean(R.mipmap.chengxuyuan, "鸣黄柳"));
        gData.add(new GroupBean(R.mipmap.xiaohuangren, "bami"));
        //学生会秘书处
        lData = new ArrayList<Item>();
        lData.add(new Item("写策划案", "10月12日-11月05日"));
        lData.add(new Item("社团聚会", "10月20日"));
        iData.add(lData);//因为子列表有多个,所以需要lData.
        //大学英语34班
        lData = new ArrayList<Item>();
        lData.add(new Item("提交作文", "10月18日"));
        lData.add(new Item("阅读第三单元", "10月19日12:00"));
        lData.add(new Item("完成PPT", "11月01日-11月05日"));
        iData.add(lData);
          //鸣黄柳
        lData = new ArrayList<Item>();
        lData.add(new Item("完成数构作业", "12月21日"));
        lData.add(new Item("购买书籍", "12月18日-12月20日"));
        iData.add(lData);
        //bami
        lData = new ArrayList<Item>();
        lData.add(new Item("上吉他课", "11月11日"));
        lData.add(new Item("去兼职", "11月12日12:00"));
        lData.add(new Item("去西门拿快递", "11月11日17:30"));
        iData.add(lData);

        //添加适配器
        myAdapter = new MyBaseExpandableListViewAdapter(gData, iData, mContext);
        exlist_lol.setAdapter(myAdapter);
        //删除操作
        myAdapter.setOnClickListenerEditOrDelete(new MyBaseExpandableListViewAdapter.OnClickListenerEditOrDelete() {
            @Override
            public void OnClickListenerDelete(int groupPosition, int position) {
                Toast.makeText(mContext, "删除成功!", 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);
        }
}

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        super.onCreateOptionsMenu(menu, inflater);
        getActivity().getMenuInflater().inflate(R.menu.people_toolbar,menu);
    }
    /**标题栏监听事件*/
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                break;
            case R.id.people_add:
                Intent intent1=new Intent(getActivity(), Contacts_addActivity.class);
                startActivity(intent1);
                break;
            default:
        }
        return super.onOptionsItemSelected(item);
    }

}

注意:以上的图片是自己要添加进drawable文件夹的哦,标题栏的构造也是需要在menu文件夹下定义的哦。
好啦,大概的代码就是这些。代码里面有参考别人的博客,也有自己思考出来,做出来的东西,希望不足之处可以大方指出来呦。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值