1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android中实现类似qq好友列表展开收起的效果

Android中实现类似qq好友列表展开收起的效果

时间:2023-05-18 12:29:12

相关推荐

Android中实现类似qq好友列表展开收起的效果

最近两天学习实现了一个功能,感觉很好,一定要记录下来。

在网上找了一些资料,林林总总,总是不那么齐全,有的代码做成小Demo还会报错,需要自己调试半天。也幸好如此,我将此功能涉及到的一些知识点理解的更加深刻一些。

功能需求:设计一个列表,类似qq好友列表,点击一级标题(对应:组名称),展开二级内容(对应:好友列表),再点击,则收起二级内容。一级标题下有一按钮,随着列表的展开收起自动的跟在一级列表下。

该功能使用了Android中的一个控件:ExpandableListView。

ExpandableListView是ListView的子类,它在普通的ListView的基础上进行了拓展,它把应用中的列表分为几组,每组又包含多个列表项。它的用法和ListView很像,只是其所显示的列表项应该由ExpandableListAdapter提供。下面提供该控件一些属性说明:

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

android:childIndicator ———————————— 显示在子列表旁边的Drawable对象

android:childDivider ———————————— 指定各组内子类表项之间的分割条:图片不会完全显示,分离子列表项的是一条直线。

android:childIndicatorLeft —————————— 子列表项指示符的左边约束位置:即从左边0位置开始计数,比如,假设指示符是一个图标,给定这个属性值为3dp,即表示从左端3dp位置开始显示此图标。

android:childIndicatorRight —————————— 子列表项指示符的右边约束位置:表示左端从什么位置开始。

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

注意:在XML文件中,如果ExpandableListView上一级视图的大小没有严格定义的话,则不能对ExpandableListView的android:layout_height属性使用wrap_content值。(例如,如果上一级视图是ScrollView的话,则不应该指定wrap_content的值,因为它可以是任意的长度。不过,如果ExpandableListView的上一级视图有特定的大小的话,比如100像素,则可以使用wrap_content)。

适用于ExpandableListView的Adapter要继承BaseExpandableListAdapter,且必须重载getGroupView和getChildView两个最重要的方法。使用BaseExpandableListAdapter时,需要重载一下方法。

/*** 取得分组数* * @return 组数*/@Overridepublic int getGroupCount() {// TODO Auto-generated method stubreturn 0;}/*** 取得指定分组的子元素数* * @param groupPosition* :要取得子元素个数的分组位置* @return:指定分组的子元素个数*/@Overridepublic int getChildrenCount(int groupPosition) {// TODO Auto-generated method stubreturn 0;}/*** 取得与给定分组关联的数据* * @param groupPosition* 分组的位置* @return 指定分组的数据*/@Overridepublic Object getGroup(int groupPosition) {// TODO Auto-generated method stubreturn null;}/*** 取得与指定分组、指定子项目关联的数据* * @param groupPosition* :包含子视图的分组的位置* @param childPosition* :指定的分组中的子视图的位置* @return 与子视图关联的数据*/@Overridepublic Object getChild(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn null;}/*** 取得指定分组的ID.该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID)* * @param groupPosition* 要取得ID的分组位置* @return 与分组关联的ID*/@Overridepublic long getGroupId(int groupPosition) {// TODO Auto-generated method stubreturn 0;}/*** 取得给定分组中给定子视图的ID.该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID)* * @param groupPosition* 包含子视图的分组的位置* @param childPosition* 要取得ID的指定的分组中的子视图的位置* @return 与子视图关联的ID* */@Overridepublic long getChildId(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn 0;}/*** 是否指定分组视图及其子视图的id对应的后台数据改变也会保持该id* * @return 是否相同的id总是指向同一个对象*/@Overridepublic boolean hasStableIds() {// TODO Auto-generated method stubreturn false;}/*** 去的用于显示给定分组的视图,该方法仅返回分组的视图对象。* * @param groupPosition* :决定返回哪个视图的组位置* @param isExpanded* :该分组是展开状态(true)还是收起状态(false)* @param convertView* :如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.* 如果该对象不能转换为可以正确显示数据的视图 ,该方法就创建新视图.不保证使用先前由getGroupView(int,* boolean,View, ViewGroup)创建的视图.* @param parent* :该视图最终从属的父视图* * @return 指定位置相应的组试图* */@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null;}/*** 取得显示给定分组给定子位置的数据用的视图* * @param groupPosition* :包含要取得子视图的分组位置。* @param childPosition* :分组中子视图(要返回的视图)的位置。* @param isLastChild* :该视图是否为组中的最后一个视图。* * @param convertView* : 如果可能,重用旧的视图对象,使用前应保证视图对象为非空,且是否是适合的类型。* 如果该对象不能转换为正确显示数据的视图,该方法就创建新视图。* 不保证使用先前由getChildView(int,int,boolean,View,ViewGroup)创建的视图。* @param parent* :该视图最终从属的父视图* * @return:指定位置相应的子视图。*/@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null;}/*** 指定位置的子视图是否可选择* * @param groupPosition* 包含要取得子视图的分组位置* @param childPosition* 分组中子视图的位置* @return 是否子视图可选择*/@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn false;}

基础知识已经总结的差不多了,话不多说,直接上代码!!!!!!

下面我将我的部分源代码附上。

我的这个列表是显示在一个fragment中的,如果显示在activity中将会更简单。

1. fragment_cars_list.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ExpandableListViewandroid:id="@+id/android_list"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/tv_load_more"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/android_list"android:layout_centerHorizontal="true"android:padding="20dp"android:text="@string/load_more" /></RelativeLayout>

2. group.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content" ><ImageViewandroid:id="@+id/iv_selector"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="5dp" /><TextViewandroid:id="@+id/tv_group"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingBottom="6dp"android:paddingLeft="10dp"android:paddingTop="6dp"android:text="@string/list"android:textSize="15sp" /></LinearLayout></LinearLayout>

3. child.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/tv_child"android:layout_width="fill_parent"android:layout_height="fill_parent"android:paddingBottom="10dp"android:paddingLeft="60dp"android:paddingTop="10dp"android:text="好友列表"android:textSize="20sp" /></LinearLayout>

4. BuddyAdapter.java

public class BuddyAdapter extends BaseExpandableListAdapter {private String[] group;private String[] buddy;private Context context;private LayoutInflater inflater;public BuddyAdapter(String[] group, String[] buddy, Context context) {super();this.group = group;this.buddy = buddy;this.context = context;inflater = LayoutInflater.from(context);}@Overridepublic int getGroupCount() {return group.length;}@Overridepublic int getChildrenCount(int groupPosition) {return buddy.length;}@Overridepublic Object getGroup(int groupPosition) {return group[groupPosition];}@Overridepublic Object getChild(int groupPosition, int childPosition) {return buddy[childPosition];}@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}@Overridepublic boolean hasStableIds() {return true;}@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {convertView = inflater.inflate(R.layout.group, null);TextView groupNameTextView = (TextView) convertView.findViewById(R.id.tv_group);ImageView ivSelector = (ImageView) convertView.findViewById(R.id.iv_selector);groupNameTextView.setText(getGroup(groupPosition).toString());ivSelector.setImageResource(R.drawable.selector_close);// 更换展开分组图片if (!isExpanded) {ivSelector.setImageResource(R.drawable.selector);}return convertView;}@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {convertView = inflater.inflate(R.layout.child, null);TextView nickTextView = (TextView) convertView.findViewById(R.id.tv_child);nickTextView.setText(getChild(groupPosition, childPosition).toString());return convertView;}// 子选项是否可以选择@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return true;}}

4. carListFragment.java

public class CarsListFragment extends Fragment {private ExpandableListView elvCompany;private TextView tvLoadMore;// 群组名称(一级条目内容)private String[] group = new String[] { "我的好友" };private String[] carsList = new String[] { "张三", "李四", "王五", "赵六","天气" };@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_cars_list, null);tvLoadMore = (TextView) view.findViewById(R.id.tv_load_more);elvCompany = (ExpandableListView) view.findViewById(R.id.android_list);BuddyAdapter adapter = new BuddyAdapter(group, carsList, getContext());elvCompany.setAdapter(adapter);setListeners();return view;}private void setListeners() {// 分组展开elvCompany.setOnGroupClickListener(new OnGroupClickListener() {@Overridepublic boolean onGroupClick(ExpandableListView parent, View v,int groupPosition, long id) {return false;}});// 分组关闭elvCompany.setOnGroupCollapseListener(new OnGroupCollapseListener() {@Overridepublic void onGroupCollapse(int groupPosition) {}});// 子项点击elvCompany.setOnChildClickListener(new OnChildClickListener() {@Overridepublic boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id) {Toast.makeText(getActivity(),group[groupPosition] + ":" + carsList[childPosition],Toast.LENGTH_SHORT).show();return false;}});tvLoadMore.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getActivity(), "没有更多数据了", Toast.LENGTH_SHORT).show();}});}}

运行之后,功能实现,但是会发现一个问题,在组列表左侧有一个默认的图标,如图所示:

那么我现在不要这个默认的图标使用我自己的图标,怎么设置呢?

其实很简单很简单,只需要设置一个属性值即可实现。我在fragment_cars_list.xml文件中的ExpandableListView控件设置属性android:groupIndicator="@null"即可实现效果。

该功能的实现特别感谢一篇文章的作者:

http://www.open-/lib/view/open1406014566679.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。