学习Android的第十九天

目录

Android ExpandableListView 分组列表

ExpandableListView 属性

ExpandableListView 事件

ExpandableListView 的 Adapter

范例

参考文档

Android ViewFlipper 翻转视图

ViewFlipper 属性

ViewFlipper 方法

为 ViewFlipper 加入 View

例子:全屏幕可以滑动的引导页

参考文档


Android ExpandableListView 分组列表

Android 的 ExpandableListView(分组列表)是一个可以展开和收起的列表控件,通常用于显示具有层次结构的数据,类似于微信通讯录中的分组列表。

在 ExpandableListView 中,第一层是分组(Group),第二层是每个分组下的子项(Child)。用户可以点击分组来展开或收起相应的子项。这种设计能够更好地组织和展示有层次结构的数据,提供更好的用户体验。

ExpandableListView 属性

  • android:childDivider:指定各组内子列表项之间的分隔条。默认情况下是一条直线,你可以设置该属性来改变分隔条的样式。
  • android:childIndicator:指定显示在子列表旁边的 Drawable 对象,可以是一个图像。这个指示器可以帮助用户识别哪些分组可以展开或收起。
  • android:childIndicatorEnd、android:childIndicatorLeft、android:childIndicatorRight、android:childIndicatorStart:这些属性用于指定子列表项指示符(child indicator)的位置和约束。你可以使用这些属性来调整子列表项指示符的位置。
  • android:groupIndicator:指定显示在组列表旁边的 Drawable 对象,可以是一个图像。这个指示器可以帮助用户识别组的位置和状态。
  • android:indicatorEnd、android:indicatorLeft、android:indicatorRight、android:indicatorStart:这些属性用于指定组列表项指示器(group indicator)的位置和约束。你可以使用这些属性来调整组列表项指示器的位置。

ExpandableListView 事件

  • OnChildClickListener:当用户点击分组列表的子项时触发。可以使用这个事件来处理子项被点击后的逻辑,例如显示详细信息或执行其他操作。
  • OnGroupClickListener:当用户点击分组列表的分组项时触发。可以使用这个事件来处理分组项被点击后的逻辑,例如展开或收起分组,或执行其他操作。
  • OnGroupCollapseListener:当分组列表的分组折叠时触发。可以使用这个事件来处理分组折叠后的逻辑,例如更新 UI 或执行其他操作。
  • OnGroupExpandListener:当分组列表的分组展开时触发。可以使用这个事件来处理分组展开后的逻辑,例如加载数据或执行其他操作。

ExpandableListView 的 Adapter

对于 ExpandableListView 的适配器(Adapter),有三种常见的实现方式:

  • 继承 BaseExpandableListAdapter 实现 ExpandableAdapter: 这是一种自定义适配器的方式,你需要创建一个类继承自 BaseExpandableListAdapter,并实现其中的方法,包括获取组数、获取指定组中的子项数、获取指定位置处的子项、获取指定位置处的组等。这种方式适用于自定义需求较复杂的情况,可以完全控制适配器的行为和样式。
  • 使用 SimpleExpandableListAdapter 将两个 List 集合包装成 ExpandableAdapter: SimpleExpandableListAdapter 是一个简单的适配器类,用于将两个 List 集合(一个用于存储组数据,另一个用于存储子项数据)包装成 ExpandableListView 所需的适配器。这种方式适用于数据比较简单的情况,不需要自定义适配器,只需要将数据进行简单的包装即可。
  • 使用 SimpleCursorTreeAdapter 将 Cursor 中的数据包装成 SimpleCursorTreeAdapter: SimpleCursorTreeAdapter 是专门用于将 Cursor 中的数据包装成 ExpandableListView 所需的适配器。如果你的数据存储在数据库中,并使用 Cursor 进行查询,那么你可以使用 SimpleCursorTreeAdapter 来将 Cursor 中的数据以树形结构展示在 ExpandableListView 中。

范例

1、修改 activity_main.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="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<String> listGroup;
    HashMap<String, List<String>> 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<String> fruits = new ArrayList<>();
        fruits.add("苹果");
        fruits.add("香蕉");
        fruits.add("芒果");

        List<String> vegetables = new ArrayList<>();
        vegetables.add("胡萝卜");
        vegetables.add("菠菜");
        vegetables.add("番茄");

        List<String> 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<String> listGroup;
    private HashMap<String, List<String>> listItem;

    public MyAdapter(Context context, List<String> listGroup, HashMap<String, List<String>> 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:

<?xml version="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:

<?xml version="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" />

参考文档

  1. Android ExpandableListView

Android ViewFlipper 翻转视图

ViewFlipper 是 Android 中的一个 View 容器,可以用来展示多个子 View,并且支持通过动画切换这些子 View。通常用于制作引导页、轮播图等功能。

ViewFlipper 属性

ViewFlipper 的两个属性 android:autoStart 和 android:flipInterval 分别用于控制轮播的自动开始和轮播的时间间隔。

  • android:autoStart: 这个属性用于设置是否自动开始轮播。如果将其设置为 true,则 ViewFlipper 将会自动开始轮播子 View;如果设置为 false,则需要手动调用 startFlipping() 方法来开始轮播,默认值为 true。
  • android:flipInterval: 这个属性用于设置轮播时的时间间隔,单位为毫秒。可以通过设置这个属性来调整轮播的速度,默认值为 3000 毫秒(即 3 秒)。

ViewFlipper 方法

  1. setInAnimation(Animation inAnimation): 设置 View 进入屏幕时使用的动画。通过传入一个 Animation 对象来设置进入动画效果。
  2. setOutAnimation(Animation outAnimation): 设置 View 退出屏幕时使用的动画。通过传入一个 Animation 对象来设置退出动画效果。
  3. showNext(): 调用该方法来显示 ViewFlipper 里的下一个 View。即切换到下一个子 View。
  4. showPrevious(): 调用该方法来显示 ViewFlipper 的上一个 View。即切换到上一个子 View。
  5. setFlipInterval(int milliseconds): 设置 View 之间切换的时间间隔,单位为毫秒。
  6. setAutoStart(boolean autoStart): 设置是否自动开始切换所有的 View。如果设为 true,ViewFlipper 会使用上面设置的时间间隔来开始切换所有的 View,切换会循环进行;如果设为 false,则需要手动调用 startFlipping() 方法来开始切换。
  7. startFlipping(): 使用上面设置的时间间隔来开始切换所有的 View,切换会循环进行。
  8. stopFlipping(): 停止 View 切换。调用该方法后,ViewFlipper 将不再自动切换 View。

为 ViewFlipper 加入 View

<?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="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

<?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="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

<?xml version="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>

参考文档

  1. Android ViewFlipper

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在奋斗的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值