ExpandableListView基本使用(创建一个歌单二级列表),属性,适配器,指示器修改设置

ExpandableListView基本使用(创建一个歌单二级列表),属性,适配器,指示器修改设置

效果图:

在这里插入图片描述

ExpandableListView基本属性介绍:

XML属性(来自官网) 作用
android:childIndicator 子项的指示器
android:childDivider 为子项设置分割线(Drawable/Color),默认大概是1dp
android:childIndicatorEnd 类比属性childIndicatorStart
android:childIndicatorLeft 类比属性childIndicatorStart
android:childIndicatorRight 类比属性childIndicatorStart
android:childIndicatorStart 箭头或者自己设置的图片的左边框距离手机左边边缘的距离,类似于marginLeft
android:groupIndicator 设置gruop的小箭头,不要的话设为@null
android:indicatorEnd
android:indicatorLeft 箭头或者自己设置的图片的右边框距离手机左边边缘的距离,类似于marginLeft
android:indicatorRight
android:indicatorStart
其他的是继承自View\ListView等的属性 dividerHeight (间距)、 divider (分割线样式)

使用ExpandableListView详细步骤:

步骤Ⅰ:在需要二级列表的地方写上<ExpandableListView .... />

<ExpandableListView
    android:id="@+id/elv_list"
    android:layout_width="match_parent"
    android:layout_height="500dp"
    android:divider="@null"
    android:groupIndicator="@null"
    android:dividerHeight="2dp"/>

步骤Ⅱ:编写gruop布局xml文件(类似RecyclerView需要编写item布局一样):

layout_elv_group.xml:

<?xml version="1.0" encoding="utf-8"?>
<!--ELV列表的父布局-->
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="43dp"
    android:background="#222327"
    android:elevation="2dp">
    <TextView
        android:id="@+id/group_name"
        android:textColor="#a6a6a8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="默认歌单"
        android:layout_marginTop="11dp"
        android:layout_marginBottom="11dp"
        android:layout_marginLeft="20dp"
        android:textStyle="bold"
        android:textSize="13sp"/>

    <ImageView
        android:id="@+id/img_open_or_close"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/group_name"
        android:layout_marginLeft="10dp"
        android:background="@drawable/icon_floder"/>

    <ImageView
        android:id="@+id/group_img_add"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:src="@mipmap/icon_add_gedan"
        android:layout_alignParentRight="true"
        android:layout_marginRight="21dp"
        android:layout_marginTop="11dp"/>
</RelativeLayout>

预览:

在这里插入图片描述

步骤Ⅲ:编写group中的item布局xml文件:

layout_elv_group_item.xml:

<?xml version="1.0" encoding="utf-8"?>

<!--子歌单布局-->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_item"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:background="@drawable/ripple_elv_item"
    android:elevation="1dp">
    <ImageView
        android:id="@+id/elv_img_songlist"
        android:layout_width="49dp"
        android:layout_height="49dp"
        android:layout_marginLeft="20dp"
        android:background="@drawable/bac"
        android:layout_centerVertical="true"/>

    <TextView
        android:id="@+id/elv_tv_songlist"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/elv_img_songlist"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="10dp"
        android:text="迷失的风筝"
        android:textSize="15sp"
        android:textStyle="bold"
        android:textColor="@color/vx_text_color"/>
    <TextView
        android:id="@+id/elv_tv_song_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="520首"
        android:layout_below="@id/elv_tv_songlist"
        android:layout_toRightOf="@id/elv_img_songlist"
        android:layout_marginLeft="15dp"
        android:textSize="13sp"
        android:layout_marginTop="5dp"
        android:textColor="@color/vx_text_color"/>

</RelativeLayout>

预览:

在这里插入图片描述

步骤Ⅳ:(★)编写自定义适配器ElvLoveAdapter继承自BaseExpandableListAdapter,并实现里面的方法(最重要的是重写getGroupView()getChildView()方法):

/**
 * <p>
 *      ExpandableListView适配器
 * </p>
 */
public class ElvLoveAdapter extends BaseExpandableListAdapter {
    
    
    private static final String TAG = "ElvLoveAdapter";

    /**
     * group的数据源
     */
    private ArrayList<String> mGroup;

    /**
     * item的数据源,ElvItem是子项数据Bean
     */
    private ArrayList<ArrayList<ElvItem>> mItemList;
    private Context mContext;
    private final LayoutInflater mInflater;

    /**
     * 构造器
     *
     * @param mGroup    父项列表
     * @param mItemList 子项列表
     * @param mContext  上下文
     */
    public ElvLoveAdapter(ArrayList<String> mGroup, ArrayList<ArrayList<ElvItem>> mItemList, Context mContext, LayoutInflater mInflater) {
    
    
        this.mGroup = mGroup;
        this.mItemList = mItemList;
        this.mContext = mContext;
        this.mInflater = LayoutInflater.from(mContext);
    }

    /**
     * 获取父项个数
     *
     * @return
     */
    @Override
    public int getGroupCount() {
    
    
        return mGroup.size();
    }

    /**
     * 获取某个父项的子项个数
     *
     * @param groupPosition
     * @return
     */
    @Override
    public int getChildrenCount(int groupPosition) {
    
    
        return mItemList.get(groupPosition).size();
    }

    /**
     * 获取某个父项
     *
     * @param groupPosition
     * @return
     */
    @Override
    public Object getGroup(int groupPosition) {
    
    
        return mGroup.get(groupPosition);
    }

    /**
     * 获取某个子项
     *
     * @param groupPosition
     * @param childPosition
     * @return
     */
    @Override
    public Object getChild(int groupPosition, int childPosition) {
    
    
        return mItemList.get(groupPosition).get(childPosition);
    }

    /**
     * 获取父项的Id
     *
     * @param groupPosition
     * @return
     */
    @Override
    public long getGroupId(int groupPosition) {
    
    
        return groupPosition;
    }

    /**
     * 获取子项的Id
     *
     * @param groupPosition
     * @param childPosition
     * @return
     */
    @Override
    public long getChildId(int groupPosition, int childPosition) {
    
    
        return childPosition;
    }

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

    /**
     * 获取父项的View
     *
     * @param groupPosition     group所在位置
     * @param isExpanded        group是否打开
     * @param convertView       容器View
     * @param parent            父布局
     * @return
     */
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    
    
        GroupViewHolder groupViewHolder = null;
        if (convertView == null) {
    
    
            convertView = mInflater.inflate(R.layout.layout_elv_group, parent, false);
        }
        groupViewHolder = new GroupViewHolder(convertView);

        // group的名字
        String group = mGroup.get(groupPosition);

        // 设置默认歌单的名字
        groupViewHolder.groupName.setText(group);

        // 判断group是否打开来设置指示器的方向
        if(isExpanded){
    
    
            groupViewHolder.indicator.setBackgroundResource(R.drawable.icon_open);
        }else {
    
    
            groupViewHolder.indicator.setBackgroundResource(R.drawable.icon_floder);
        }

        // 添加子歌单点击事件
        groupViewHolder.addSongList.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                // TODO 处理添加子歌单
                Toast.makeText(v.getContext(), "添加功能待做", Toast.LENGTH_SHORT).show();
            }
        });
        return convertView;
    }


    /**
     * 获取子项的View
     *
     * @param groupPosition     所在group位置
     * @param childPosition     在group中的位置
     * @param isLastChild       是否为最后一个子项
     * @param convertView       容器view
     * @param parent            父布局
     * @return
     */
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
    
        ItemViewHolder itemViewHolder = null;
        if (convertView == null) {
    
    
            convertView = mInflater.inflate(R.layout.layout_elv_group_item, parent, false);
        }

        // 歌单进入动画,动画文件在后面有
        convertView.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.anim_rcv_item_1));

        itemViewHolder = new ItemViewHolder(convertView);

        // 拿到子项Bean
        ElvItem itemBean = mItemList.get(groupPosition).get(childPosition);
        // 歌单名
        String  songListName = itemBean.getSongListName();
        // 歌单封面资源id
        int imgRes = itemBean.getImgRes();
        // 歌单包含歌曲数目
        String songCount = itemBean.getSongCount();
        
        // 设置歌单封面
        itemViewHolder.listCover.setImageResource(imgRes);

        // 设置歌单名
        itemViewHolder.songListName.setText(songListName);

        // 设置歌单包含歌曲数目
        itemViewHolder.songCount.setText(songCount);

        // 添加子项点击时的水波纹效果,已经在设给布局的background属性了
        //itemViewHolder.rl_item.setBackgroundResource(R.drawable.ripple_elv_item);

        // 点击事件:跳转到对应歌单的详细页面
        itemViewHolder.rl_item.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Toast.makeText(v.getContext(), "在[" + groupPosition + "]组中的第[" + childPosition + "]子项", Toast.LENGTH_SHORT).show();
            }
        });

        return convertView;
    }

    /**
     * 子项是否被选中,如果要为子项设置点击事件需要返回true
     *
     * @param groupPosition
     * @param childPosition
     * @return
     */
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
    
    
        return true;
    }

    /**
     * 父项的view搭载器
     */
    static class GroupViewHolder {
    
    
        private TextView groupName;
        private ImageView addSongList, indicator;

        public GroupViewHolder(View view) {
    
    
            groupName = view.findViewById(R.id.group_name);
            addSongList = view.findViewById(R.id.group_img_add);
            indicator = view.findViewById(R.id.img_open_or_close);
        }
    }

    /**
     * 子项的搭载器
     */
    static class ItemViewHolder {
    
    
        // 布局
        private RelativeLayout rl_item;
        // 歌单名,歌单包含的歌曲数目
        private TextView songListName;
        private TextView songCount;

        // 歌单的封面
        private ImageView listCover;

        public ItemViewHolder(View view) {
    
    
            songListName = view.findViewById(R.id.elv_tv_songlist);
            songCount = view.findViewById(R.id.elv_tv_song_count);
            listCover = view.findViewById(R.id.elv_img_songlist);
            rl_item = view.findViewById(R.id.rl_item);
        }
    }
}

ElvItem.java

/**
 * 二级列表 ExpandableListView 中 group 的子项的Bean类
 */
public class ElvItem {
    
    
    // 封面图片资源id
    private int mImgRes;
    // 歌单名字
    private String mSongListName;
    // 包含歌曲的数目
    private String mSongCount;

    public ElvItem(){
    
    

    }

    public ElvItem(int mImgRes, String mSongListName, String mSongCount) {
    
    
        this.mImgRes = mImgRes;
        this.mSongListName = mSongListName;
        this.mSongCount = mSongCount;
    }

    public int getImgRes() {
    
    
        return mImgRes;
    }

    public void setImgRes(int mImgRes) {
    
    
        this.mImgRes = mImgRes;
    }

    public String getSongListName() {
    
    
        return mSongListName;
    }

    public void setSongListName(String mSongListName) {
    
    
        this.mSongListName = mSongListName;
    }

    public String getSongCount() {
    
    
        return mSongCount;
    }

    public void setSongCount(String mSongCount) {
    
    
        this.mSongCount = mSongCount;
    }
}

步骤Ⅴ:创建ExpandableListView、适配器实例,初始化数据源,显示出来:

public class FavoriteFragment extends BaseFragment{
    
    

    private ExpandableListView mExpandableListView;
    private ElvLoveAdapter mAdapter;
    private LayoutInflater mInflater;
    
    private ArrayList<String> mGroupList = new ArrayList<>();
    private ArrayList<ArrayList<ElvItem>> mItemList = new ArrayList<>();

    public FavoriteFragment() {
    
    

    }

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

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

    @Override
    public void init(View view) {
    
    
        mExpandableListView = view.findViewById(R.id.elv_list);
        mAdapter= new ElvLoveAdapter(mGroupList, mItemList, view.getContext(), mInflater);
        mExpandableListView.setAdapter(mAdapter);
        // 这里去掉group点击时的水波纹,将其设置成透明
        mExpandableListView.setSelector(new ColorDrawable(Color.TRANSPARENT));
    }

    public void initData(){
    
    
        // 添加group数据
        mGroupList.add("默认歌单");

        // 添加子项数据
        ArrayList<ElvItem> items = new ArrayList<>();
        items.add(new ElvItem(R.drawable.img_1, "人生若只如初见", "10首"));
        items.add(new ElvItem(R.drawable.img_2, "一枝红杏出墙来", "1024首"));
        items.add(new ElvItem(R.drawable.img_3, "落霞与孤鹜齐飞", "521首"));
        items.add(new ElvItem(R.drawable.img_4, "游戏战歌", "66首"));
        mItemList.add(items);
    }
}

去掉ExpandableListView点击group时的水波纹效果:

// 设置为透明,或者资源id
mExpandableListView.setSelector(new ColorDrawable(Color.TRANSPARENT));

去掉ExpandableListView默认的箭头(可以自定义直接属性赋予资源id[不推荐]):

代码设置:

settingLists.setGroupIndicator(null);

直接属性设置:

<ExpandableListView
    android:groupIndicator="@null"
    />

去掉ExpandableListView的分割线:

<ExpandableListView
    android:divider="@null"
    />

设置ExpandableListView子项之间的间距:

<ExpandableListView
   android:dividerHeight="8dp"
    />

设置ExpandableListView默认是展开的:

// 需要先实例化ExpandabListView,数据源不为null,不然会报错
mExpandableListView.setAdapter(adapter);

// 获取group数目并遍历,设为默认展开
int groupCount = exListView.getCount();   

for (inti=0; i<groupCount; i++)  {
    
       
       mExpandableListView.expandGroup(i);  
 };

判断group是否被打开:

// groupPosition:gruop的位置
expandableListView.isGroupExpanded(groupPosition)

关闭group

// groupPosition:gruop的位置
expandableListView.collapseGroup(groupPosition);

group的点击事件setOnGroupClickListener(OnGroupClickListener listener)

mExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
    
    
    @Override
    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
    
    
        
        return false;
    }
});

设置group里的item进入动画:

在适配器中的getChildView()方法里面设置:

// 使用layoutAniamtion动画会报错
convertView.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.anim_rcv_item_1));

用到的动画资源anim_rcv_item_1.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillAfter="true"
    >
<!--    先上升自身的20%的高度,然后再降下来-->
    <translate
        android:fromYDelta="-20%"
        android:toYDelta="0"
        android:interpolator="@android:anim/decelerate_interpolator"
        />

<!--    可见度0-1-->
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:interpolator="@android:anim/decelerate_interpolator"
        />

<!--    先在XY放大到105%,再还原-->
    <scale
        android:fromXScale="105%"
        android:toXScale="100%"
        android:fromYScale="105%"
        android:toYScale="100%"
        android:pivotY="50%"
        android:pivotX="50%"
        android:interpolator="@android:anim/decelerate_interpolator"
        />
</set>

猜你喜欢

转载自blog.csdn.net/C_biubiubiu/article/details/110138754
今日推荐