学习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
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:
list_item.xml:
参考文档
- 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 方法
- setInAnimation(Animation inAnimation): 设置 View 进入屏幕时使用的动画。通过传入一个 Animation 对象来设置进入动画效果。
- setOutAnimation(Animation outAnimation): 设置 View 退出屏幕时使用的动画。通过传入一个 Animation 对象来设置退出动画效果。
- showNext(): 调用该方法来显示 ViewFlipper 里的下一个 View。即切换到下一个子 View。
- showPrevious(): 调用该方法来显示 ViewFlipper 的上一个 View。即切换到上一个子 View。
- setFlipInterval(int milliseconds): 设置 View 之间切换的时间间隔,单位为毫秒。
- setAutoStart(boolean autoStart): 设置是否自动开始切换所有的 View。如果设为 true,ViewFlipper 会使用上面设置的时间间隔来开始切换所有的 View,切换会循环进行;如果设为 false,则需要手动调用 startFlipping() 方法来开始切换。
- startFlipping(): 使用上面设置的时间间隔来开始切换所有的 View,切换会循环进行。
- stopFlipping(): 停止 View 切换。调用该方法后,ViewFlipper 将不再自动切换 View。
为 ViewFlipper 加入 View
例子:全屏幕可以滑动的引导页
1、activity_main.xml
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
参考文档
- Android ViewFlipper