目录
Android ExpandableListView 分组列表
Android 的 ExpandableListView(分组列表)是一个可以展开和收起的列表控件,通常用于显示具有层次结构的数据,类似于微信通讯录中的分组列表。
在 ExpandableListView 中,第一层是分组(Group),第二层是每个分组下的子项(Child)。用户可以点击分组来展开或收起相应的子项。这种设计能够更好地组织和展示有层次结构的数据,提供更好的用户体验。
对于 ExpandableListView 的适配器(Adapter),有三种常见的实现方式:
1、修改 activity_main.xml
- "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="vertical"
- android:gravity="center">
-
- <ExpandableListView
- android:id="@+id/expandableListView"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- LinearLayout>
2、修改 MainActivity.java
- package com.example.myapplication;
-
- import android.os.Bundle;
- import android.widget.ExpandableListView;
- import android.widget.Toast;
- import androidx.appcompat.app.AppCompatActivity;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
-
- public class MainActivity extends AppCompatActivity {
-
- ExpandableListView expandableListView;
- List
listGroup; - HashMap
> listItem; -
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- expandableListView = findViewById(R.id.expandableListView);
-
- // 准备数据
- prepareListData();
-
- // 创建并设置适配器
- MyAdapter adapter = new MyAdapter(this, listGroup, listItem);
- expandableListView.setAdapter(adapter);
-
- // 设置分组项点击监听器
- expandableListView.setOnGroupClickListener((parent, v, groupPosition, id) -> {
- Toast.makeText(MainActivity.this,
- "Group Clicked " + listGroup.get(groupPosition),
- Toast.LENGTH_SHORT).show();
- return false;
- });
-
- // 设置子项点击监听器
- expandableListView.setOnChildClickListener((parent, v, groupPosition, childPosition, id) -> {
- Toast.makeText(MainActivity.this,
- "单击的子项 " + listItem.get(listGroup.get(groupPosition)).get(childPosition),
- Toast.LENGTH_SHORT).show();
- return false;
- });
- }
-
- // 准备数据
- private void prepareListData() {
- listGroup = new ArrayList<>();
- listItem = new HashMap<>();
-
- listGroup.add("水果");
- listGroup.add("蔬菜");
- listGroup.add("动物");
-
- List
fruits = new ArrayList<>(); - fruits.add("苹果");
- fruits.add("香蕉");
- fruits.add("芒果");
-
- List
vegetables = new ArrayList<>(); - vegetables.add("胡萝卜");
- vegetables.add("菠菜");
- vegetables.add("番茄");
-
- List
animals = new ArrayList<>(); - animals.add("狗");
- animals.add("猫");
- animals.add("大象");
-
- listItem.put(listGroup.get(0), fruits);
- listItem.put(listGroup.get(1), vegetables);
- listItem.put(listGroup.get(2), animals);
- }
- }
3、创建适配器类 MyAdapter.java
- package com.example.myapplication;
-
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseExpandableListAdapter;
- import android.widget.TextView;
- import java.util.HashMap;
- import java.util.List;
-
- public class MyAdapter extends BaseExpandableListAdapter {
-
- private Context context;
- private List
listGroup; - private HashMap
> listItem; -
- public MyAdapter(Context context, List
listGroup, HashMap> listItem) { - this.context = context;
- this.listGroup = listGroup;
- this.listItem = listItem;
- }
-
- @Override
- public int getGroupCount() {
- return listGroup.size();
- }
-
- @Override
- public int getChildrenCount(int groupPosition) {
- return listItem.get(listGroup.get(groupPosition)).size();
- }
-
- @Override
- public Object getGroup(int groupPosition) {
- return listGroup.get(groupPosition);
- }
-
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- return listItem.get(listGroup.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) {
- String groupTitle = (String) getGroup(groupPosition);
- if (convertView == null) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- convertView = inflater.inflate(R.layout.list_group, null);
- }
- TextView textView = convertView.findViewById(R.id.listTitle);
- textView.setText(groupTitle);
- return convertView;
- }
-
- @Override
- public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
- String childTitle = (String) getChild(groupPosition, childPosition);
- if (convertView == null) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- convertView = inflater.inflate(R.layout.list_item, null);
- }
- TextView textView = convertView.findViewById(R.id.expandedListItem);
- textView.setText(childTitle);
- return convertView;
- }
-
- @Override
- public boolean isChildSelectable(int groupPosition, int childPosition) {
- return true;
- }
- }
4、创建布局文件 list_group.xml 和 list_item.xml 用于分组和子项的视图:
list_group.xml:
- "1.0" encoding="utf-8"?>
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/listTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="15dp"
- android:textColor="@android:color/black"
- android:textSize="20sp" />
list_item.xml:
- "1.0" encoding="utf-8"?>
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/expandedListItem"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="15dp"
- android:textColor="@android:color/darker_gray"
- android:textSize="18sp" />
ViewFlipper 是 Android 中的一个 View 容器,可以用来展示多个子 View,并且支持通过动画切换这些子 View。通常用于制作引导页、轮播图等功能。
ViewFlipper 的两个属性 android:autoStart 和 android:flipInterval 分别用于控制轮播的自动开始和轮播的时间间隔。
- "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="vertical"
- android:gravity="center">
- <ViewFlipper
- android:id="@+id/viewFlipper"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:autoStart="true"
- android:flipInterval="3000">
-
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/guide_1"
- android:scaleType="centerCrop"/>
-
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/guide_2"
- android:scaleType="centerCrop"/>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/guide_3"
- android:scaleType="centerCrop"/>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/guide_4"
- android:scaleType="centerCrop"/>
- ViewFlipper>
- LinearLayout>
1、activity_main.xml
- "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="vertical"
- android:gravity="center">
- <androidx.viewpager.widget.ViewPager
- android:id="@+id/viewPager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- LinearLayout>
2、MainActivity.java
- package com.example.myapplication;
-
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.viewpager.widget.ViewPager;
- import android.os.Bundle;
-
- public class MainActivity extends AppCompatActivity {
-
- private ViewPager viewPager;
- private int[] images = {R.drawable.guide_1, R.drawable.guide_2, R.drawable.guide_3, R.drawable.guide_4};
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- viewPager = findViewById(R.id.viewPager);
- ViewPagerAdapter adapter = new ViewPagerAdapter(this, images);
- viewPager.setAdapter(adapter);
- }
- }
3、ViewPagerAdapter.java
- package com.example.myapplication;
-
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ImageView;
- import androidx.annotation.NonNull;
- import androidx.viewpager.widget.PagerAdapter;
-
- public class ViewPagerAdapter extends PagerAdapter {
- private Context mContext;
- private int[] mImages;
-
- public ViewPagerAdapter(Context context, int[] images) {
- mContext = context;
- mImages = images;
- }
-
- @NonNull
- @Override
- public Object instantiateItem(@NonNull ViewGroup container, int position) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- View view = inflater.inflate(R.layout.item_guide, container, false);
- ImageView imageView = view.findViewById(R.id.imageView);
- imageView.setImageResource(mImages[position]);
- container.addView(view);
- return view;
- }
-
- @Override
- public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
- container.removeView((View) object);
- }
-
- @Override
- public int getCount() {
- return mImages.length;
- }
-
- @Override
- public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
- return view == object;
- }
- }
4、item_guide.xml
- "1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop" />
-
- RelativeLayout>