android 二级列表 二级目录

Posted 张学涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 二级列表 二级目录相关的知识,希望对你有一定的参考价值。

新建主界面 xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ExpandableListView
        android:id="@+id/expandablelistview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ExpandableListView>

</LinearLayout>

新建一级目录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">
    <TextView
        android:layout_width="48dp"
        android:layout_height="16dp"
        android:text="第一关"
        android:textColor="#ff777777"
        android:textSize="16dp"
        />
</LinearLayout>

新建二级目录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:gravity="center_vertical">
    <ImageView
        android:layout_width="29.2dp"
        android:layout_height="25.4dp"
        android:src="@mipmap/z_dialog1_dianshi"/>
    <TextView
        android:layout_marginLeft="10dp"
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="内容"
        android:textSize="14dp"
        android:gravity="center_vertical"
        android:textColor="#ff777777"
        />

</LinearLayout>

编写适配器

package com.rhkj.zhihuixue.activity.zhijizhiyi.adapter;


import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import com.rhkj.zhihuixue.R;

import java.util.List;

/**
 * @ClassName HotelEntityAdapter
 * @Description TODO
 * @Author ZhangXueTao
 * @Date 2020/10/27 14:44
 * @Version 1.0 模板
 */
public class HotelEntityAdapter  extends BaseExpandableListAdapter {
    List<String> mGroupList;//一级List
    List<List<String>> mChildList;//二级List 注意!这里是List里面套了一个List<String>,实际项目你可以写一个pojo类来管理2层数据


    public HotelEntityAdapter(List<String> groupList, List<List<String>> childList){
        mGroupList = groupList;
        mChildList = childList;

    }

    @Override
    public int getGroupCount() {//返回第一级List长度
        return mGroupList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {//返回指定groupPosition的第二级List长度
        return mChildList.get(groupPosition).size();
    }

    @Override
    public Object getGroup(int groupPosition) {//返回一级List里的内容
        return mGroupList.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {//返回二级List的内容
        return mChildList.get(groupPosition).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {//返回一级View的id 保证id唯一
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {//返回二级View的id 保证id唯一
        return groupPosition + childPosition;
    }

    /**
     * 指示在对基础数据进行更改时子ID和组ID是否稳定
     * @return
     */
    @Override
    public boolean hasStableIds() {
        return true;
    }

    /**
     *  返回一级父View
     */
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.z_exlist_one_item, parent,false);
//        ((TextView)convertView).setText((String)getGroup(groupPosition));
        return convertView;
    }

    /**
     *  返回二级子View
     */
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_item, parent,false);
//        ((TextView)convertView).setText((String)getChild(groupPosition,childPosition));
        return convertView;
    }

    /**
     *  指定位置的子项是否可选
     */
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

}

Activity

package com.rhkj.zhihuixue.activity.zhijizhiyi;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;

import com.rhkj.zhihuixue.R;
import com.rhkj.zhihuixue.activity.zhijizhiyi.adapter.HotelEntityAdapter;
import com.rhkj.zhihuixue.base.app.ZBaseLandscapeActivity;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;

public class MainActivity2 extends ZBaseLandscapeActivity {

    @BindView(R.id.expandablelistview)
     ExpandableListView expandablelistview;
    private HotelEntityAdapter mAdapter;



    @Override
    public int getLayoutId() {
        return R.layout.activity_main2;
    }

    @Override
    public void initPresenter() {

    }

    @Override
    public void initView() {
        List<String> groupList = new ArrayList<>();
        groupList.add("一");
        groupList.add("二");
        groupList.add("三");

        List<List<String>> childList = new ArrayList<>();
        List<String> childList1 = new ArrayList<>();
        childList1.add("1");
        childList1.add("1");
        childList1.add("1");
        List<String> childList2 = new ArrayList<>();
        childList2.add("2");
        childList2.add("2");
        childList2.add("2");
        List<String> childList3 = new ArrayList<>();
        childList3.add("3");
        childList3.add("3");
        childList3.add("3");

        childList.add(childList1);
        childList.add(childList2);
        childList.add(childList3);

        mAdapter = new HotelEntityAdapter(groupList, childList);
        expandablelistview.setAdapter(mAdapter);

        expandablelistview.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {//一级点击监听
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {

                //如果你处理了并且消费了点击返回true,这是一个基本的防止onTouch事件向下或者向上传递的返回机制
                return false;
            }
        });

        expandablelistview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {//二级点击监听
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {

                //如果你处理了并且消费了点击返回true
                return false;
            }
        });
    }


}

其他Xml属性

android:dividerHeight="20dp" 设置item间距高度,注意设置这个间距包括了一级和二级

android:divider="@color/colorRed1" 设置一级间距颜色

android:childDivider="@color/colorGreen" 设置二级间距颜色

 

android:childIndicator:显示在子列表旁边的Drawable对象,可以是一个图像

android:childIndicatorEnd:子列表项指示符的结束约束位置

android:childIndicatorLeft:子列表项指示符的左边约束位置

android:childIndicatorRight:子列表项指示符的右边约束位置

android:childIndicatorStart:子列表项指示符的开始约束位置

 

android:groupIndicator:显示在组列表旁边的Drawable对象,可以是一个图像

android:indicatorEnd:组列表项指示器的结束约束位置

android:indicatorLeft:组列表项指示器的左边约束位置

android:indicatorRight:组列表项指示器的右边约束位置

android:indicatorStart:组列表项指示器的开始约束位置

可以实现的ExpandableListView3种Adapter

1. 扩展BaseExpandableListAdpter实现ExpandableAdapter。

2. 使用SimpleExpandableListAdpater将两个List集合包装成ExpandableAdapter

3. 使用simpleCursorTreeAdapter

 

ExpandableListView的一些API详解

mExpandableListView.collapseGroup(position);   收起指定位置组的二级列表

mExpandableListView.expandGroup(position);  展开指定位置组的二级列表

mExpandableListView.isGroupExpanded(position);  指定位置的组是否展开

mExpandableListView.setSelectedGroup(position);  将指定位置的组设置为置顶

改变方向图标的位置

 

int width = getResources().getDisplayMetrics().widthPixels;
mExpandableListView.setIndicatorBounds(width - UnitConversionUtil.dip2px(this,40)
                , width - UnitConversionUtil.dip2px(this,15));//设置图标位置

 

关于点击事件的一些坑

  如果你在适配器里去实现了Group的点击事件想用回调方法回调出去(如下代码),这个时候你就会碰到一个Group无法展开和收起的坑,原因很简单因为这里已经把点击事件消费了,点击不在继续向下传递,所以底层实现的展开和收起不执行了

技术图片
  /**
     *  返回一级父View
     */
    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, final ViewGroup parent) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
            convertView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });
        return convertView;
    }
技术图片

那么如何解决呢?

方法一

  不用setOnClickListener(),因为这个会消费事件,我们改用setOnTouchListener,如下代码:

技术图片
      convertView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN){
                  //实现你自己的接口回调
                    }
                    return false;
                }
            });        
技术图片

  这里有一点需要注意ACTION_DOWN 需要返回false,因为底层是消费ACTION_DOWN的来展开和收起的....

方式二

将groupPosition回调到外面后使用collapseGroup() 或者 expandGroup()方法实现.

以上是关于android 二级列表 二级目录的主要内容,如果未能解决你的问题,请参考以下文章

ExpandableListView二级列表

Kotlin ExpandableListView可扩展二级列表

如何在Django Admin后台添加一个省市二级联动下拉列表

Android 仿美团下拉(PopupWindow)列表(ListView)一二级分类菜单的功能

ExpandableListView控件实现二级列表

Axure中继器实现二级导航栏