Android中使用Expandablelistview实现微信通讯录界面

之前的博文《Android 中使用ExpandableListView 实现分组的实例》我简单介绍了使用ExpandableListView实现简单的好友分组功能,今天我们针对之前的所做的仿微信APP来对ExpandableListView做一个扩展介绍,实现效果如下(通讯里使用ExpandableListView实现):

相关知识点博文链接:

Android 中使用ExpandableListView 实现分组的实例

详解Android中fragment和viewpager的那点事儿

详解Android中ListView实现图文并列并且自定义分割线(完善仿微信APP)

正常使用ExpandableListView的思路如下:

(1)要给ExpandableListView 设置适配器,那么必须先设置数据源。

(2)数据源,就是此处的适配器类ExpandableAdapter,此方法继承了BaseExpandableListAdapter ,它是ExpandableListView的一个子类。需要重写里面的多个方法。方法的意思,代码中都有详细的注释。数据源中,用到了自定义的View布局,此时根据自己的需求,来设置组和子项的布局样式。getChildView()和getGroupView()方法设置自定义布局。
(3)数据源设置好,直接给 ExpandableListView.setAdapter()即可实现此收缩功能。

但本次实现除以上实现步骤之外,还需要注意的有以下几点:

(1)首次加载ExpandableListView需要默认全部展开,使用以下方法:

在给ExpandableListView 设置适配器后,添加以下代码:

//Group.size()为组名个数,如果为数组存储则为group、length for (int i = 0; i < Group.size(); i++) { expandableListView.expandGroup(i); }

提醒:加载前别忘了判断adapter是否为空和有没有Group数据哦

(2)保持ExpandableListView始终展开无法收缩

expandableListView.setOnGroupClickListener(new OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { return true;//返回true则表示无法收缩 } });

(3)取消通讯录上方的groupName空间

微信通讯录中“新的朋友”,“群聊”,“标签”,“公众号”,作为一个整体自定义布局添加到ExpandableListView中,详情见以下代码实现

(4)修改ExpandableListView的分割线

大概思路就是这样,现在开始整体实现代码的演示:

第一步:layout中通讯录整体布局contactfragment.xml:

其实就是一个ExpandableListView,添加android:divider ="#FFFFFF"取消自带分割线

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/fragmentback"> <ExpandableListView android:id="@+id/contact_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:divider ="#FFFFFF"/> </LinearLayout>

第二步:layout中组名(groupName)的布局文件contact_list_group_item.xml:

注意设置间距,保证美观且尽量与微信一致

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/fragmentback"> <TextView android:text="TextView" android:textSize="20sp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:gravity="center_vertical" android:id="@+id/group_tv" /> </LinearLayout>

第三步:layout中ExpandableListView中每个item的布局文件contact_list_item.xml:

这里添加了自定义分割线

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:background="@color/colorwhite" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:paddingLeft="10dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/contact_item_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/default_fmessage" android:adjustViewBounds="true" android:maxWidth="35dp"/> <TextView android:id="@+id/contact_item_tv" android:layout_margin="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="新的朋友"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/fragmentback"/> </LinearLayout> </LinearLayout>

第四步:layout中ExpandableListView中的头布局contact_list_title.xml(不需要groupName)

我们观察微信通讯录布局中“新的朋友”,“群聊”,“标签”,“公众号”上方直接为微信的顶部导航,不存在ExpandableListView一贯的组名布局,这里我们将“新的朋友”,“群聊”,“标签”的布局单独实现:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:background="@color/colorwhite" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:paddingLeft="10dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/default_fmessage" android:adjustViewBounds="true" android:maxWidth="35dp"/> <TextView android:layout_margin="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="新的朋友"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/fragmentback"/> <LinearLayout android:paddingLeft="10dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/default_chatroom" android:adjustViewBounds="true" android:maxWidth="35dp"/> <TextView android:layout_margin="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="群聊"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/fragmentback"/> <LinearLayout android:paddingLeft="10dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/default_contactlabel" android:adjustViewBounds="true" android:maxWidth="35dp"/> <TextView android:layout_margin="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="标签"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/fragmentback"/> <LinearLayout android:paddingLeft="10dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/default_servicebrand_contact" android:adjustViewBounds="true" android:maxWidth="35dp"/> <TextView android:layout_margin="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="公众号"/> </LinearLayout> </LinearLayout> </LinearLayout>

第五步:java中定义继承BaseExpandableListAdapter类(自定义适配器)

(1)这里模仿实际项目,将自定义适配器定义定义在外部同意管理,所以需要设置相关构造方法供expandableListView调用

(2)为了实现头文件的布局,需要在getGroupView与getChildView方法中判断头文件的位置,从而调整布局,这里我们将头文件定义在数据首位

import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; import com.mly.panhouye.wechat.R; /** * Created by panchengjia on 2016/12/28 0028. */ public class MyExpandableListAdapter extends BaseExpandableListAdapter { Context context; String[] group; String[][] itemName; int[][] itemIcon; public MyExpandableListAdapter(Context context, String[] group, String[][] itemName, int[][] itemIcon) { this.context = context; this.group = group; this.itemName = itemName; this.itemIcon = itemIcon; } @Override public int getGroupCount() { return group.length; } @Override public int getChildrenCount(int groupPosition) { return itemName[groupPosition].length; } @Override public Object getGroup(int groupPosition) { return group[groupPosition]; } @Override public Object getChild(int groupPosition, int childPosition) { return itemName[groupPosition][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) { ViewHolder vh; //ExpandableList的第一个分组没有组名,这里需要自定义布局 if(groupPosition==0){ convertView =LayoutInflater.from(context).inflate(R.layout.contact_list_title,null); }else{ if(convertView==null){ convertView= LayoutInflater.from(context).inflate(R.layout.contact_list_group_item,null); vh = new ViewHolder(); vh.tv = (TextView) convertView.findViewById(R.id.group_tv); convertView.setTag(vh); } vh = (ViewHolder) convertView.getTag(); vh.tv.setText(group[groupPosition]); } return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ViewHolder vh; //ExpandableList的第一个分组没有组名,这里需要自定义布局 if (groupPosition==0){ convertView =LayoutInflater.from(context).inflate(R.layout.contact_list_title,null); }else{ if(convertView==null){ convertView= LayoutInflater.from(context).inflate(R.layout.contact_list_item,null); vh = new ViewHolder(); vh.tv = (TextView) convertView.findViewById(R.id.contact_item_tv); vh.iv= (ImageView) convertView.findViewById(R.id.contact_item_iv); convertView.setTag(vh); } vh = (ViewHolder) convertView.getTag(); vh.tv.setText(itemName[groupPosition][childPosition]); vh.iv.setImageResource(itemIcon[groupPosition][childPosition]); } return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } class ViewHolder{ TextView tv; ImageView iv; } }

第六步:java中重写之前的与contactfragment.xml布局对应的ContactFragment.java类

import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ExpandableListView; import com.mly.panhouye.wechat.R; import com.mly.panhouye.wechat.adapter.MyExpandableListAdapter; /** * Created by panchengjia on 2016/12/28 0028. */ public class ContactFragment extends Fragment { private ExpandableListView contact_list; //定义分组以及组内成员(设置头文件位置为空) String[] group ={"","好友列表"}; String[][] itemName={{},{"郭嘉", "黄月英", "华佗", "刘备", "陆逊", "吕布", "吕蒙", "马超", "司马懿", "孙权", "孙尚香", "夏侯惇", "许褚", "杨修", "张飞", "赵云", "甄姬", "周瑜", "诸葛亮"}}; int[][] itemIcon={{},{R.mipmap.guojia, R.mipmap.huangyueying, R.mipmap.huatuo, R.mipmap.liubei, R.mipmap.luxun, R.mipmap.lvbu, R.mipmap.lvmeng, R.mipmap.machao, R.mipmap.simayi, R.mipmap.sunquan, R.mipmap.sunshangxiang, R.mipmap.xiahoudun, R.mipmap.xuchu, R.mipmap.yangxiu, R.mipmap.zhangfei, R.mipmap.zhaoyun, R.mipmap.zhenji, R.mipmap.zhouyu, R.mipmap.zhugeliang}}; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.contact_fragment,container,false); contact_list = (ExpandableListView) view.findViewById(R.id.contact_list); //实例化适配器 MyExpandableListAdapter myExpandableListAdapter=new MyExpandableListAdapter(getContext(),group,itemName,itemIcon); //配置适配器 contact_list.setAdapter(myExpandableListAdapter); //去掉ExpandableListView 默认的箭头 contact_list.setGroupIndicator(null); //设置ExpandableListView默认展开 for (int i = 0; i <group.length; i++) { contact_list.expandGroup(i); } //设置ExpandableListView不可点击收回 contact_list.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { return true; } }); return view; } }

实现方法很多大家开动吧(建议使用recyclerView)。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

时间: 2024-10-06 17:40:30

Android中使用Expandablelistview实现微信通讯录界面的相关文章

Android 中使用ExpandableListView 实现分组的实例_Android

 Android 中使用ExpandableListView 实现分组 一个视图显示垂直滚动两级列表中的条目.这不同于列表视图,允许两个层次,类似于QQ的好友分组.要实现这个效果的整体思路为: 1.要给ExpandableListView 设置适配器,那么必须先设置数据源. 2.数据源,就是此处的适配器类,此方法继承了BaseExpandableListAdapter,它是ExpandableListView的一个子类.需要重写里面的多个方法.方法的意思,代码中都有详细的注释.数据源中,用到了自

Android 中使用ExpandableListView 实现分组的实例

Android 中使用ExpandableListView 实现分组 一个视图显示垂直滚动两级列表中的条目.这不同于列表视图,允许两个层次,类似于QQ的好友分组.要实现这个效果的整体思路为: 1.要给ExpandableListView 设置适配器,那么必须先设置数据源. 2.数据源,就是此处的适配器类,此方法继承了BaseExpandableListAdapter,它是ExpandableListView的一个子类.需要重写里面的多个方法.方法的意思,代码中都有详细的注释.数据源中,用到了自定

Android 中解决Viewpage调用notifyDataSetChanged()时界面无刷新的问题

Android 中解决Viewpage调用notifyDataSetChanged()时界面无刷新的问题 问题描述 相信很多做过Viewpager的人肯定遇到过这个问题,这个是bug还是Android就是如此设计的,我们不做讨论.总之,它确实影响我们功能的实现了. 可能不少同学选择为Viewpager重新设置一遍适配器adapter,达到刷新的目的.但是这种方法在大多数情况下,是有问题的. 解决办法 以我们可以尝试着修改适配器的写法,覆盖getItemPosition()方法,当调用notify

Android中使用PopupWindow 仿微信点赞和评论弹出

微信朋友圈的点赞和评论功能,有2个组成部分:左下角的"更多"按钮:点击该按钮后弹出的对话框: PopupWindow,弹出框使用PopupWindow实现,这是点赞和评论的载体,具体要涉及 PopupWindow 点击非窗口位置和再次点击消失以及显示位置的问题(根据相应更多按钮的位置确定 PopupWindow 的显示位置 package com.example.cmm.helloworld; import android.app.AlertDialog; import android

在Android中实现Service动态更新UI界面(Service与主程序Activity之间的数据交互或控制)

案例:通过service向远程服务器发送请求,根据服务器返回的结果动态更新主程序UI界面,主程序可实时关闭或重启服务. 方案一:使用广播+Service 注册BroadcastReceiver 1.在主程序activity中注册一个BroadcastReceiver,用于接收Service发布的广播. @Override protected void onStart() {//重写onStart方法 dataReceiver = new DataReceiver(); IntentFilter

Android中使用ListView模拟微信好友功能

效果图: 分析: 1.创建listView 2.创建数据 3.创建适配器 将数据放到呈现数据的容器里面. 将这个容器(带数据)连接适配器. 其实是直接在我们自己写的adapter的getView重载方法中返回连接的view. View view=View.inflate(mContext, com.example.weChatFriends.R.layout.item_friend, null); return view; 4.ListView设置适配器 代码: package fry; imp

Android仿QQ、微信聊天界面长按提示框效果_Android

先来看看效果图 如何使用 示例代码 PromptViewHelper pvHelper = new PromptViewHelper(mActivity); pvHelper.setPromptViewManager(new ChatPromptViewManager(mActivity)); pvHelper.addPrompt(holder.itemView.findViewById(R.id.textview_content)); 使用起来还是很简单的 首先new一个PromptViewH

自定义view-android 中类似酷狗音乐主界面中的左右拖动界面如何实现?

问题描述 android 中类似酷狗音乐主界面中的左右拖动界面如何实现? 现在有很多APP都使用了主界面中页面切换实现了左右滑动来进行加载(实现方式应该不是ViewPager方式),而且在开始滑动的时候可以使的第一个界面显示多半,目测占屏幕的4/5,而即将要滑出进行显示的界面占1/5,再次向左滑动,第二个界面完全显示出来.看上去比较美观实用,请问如何才能实现这种效果呢? 解决方案 viewpager很容易完美实现,此下例子我已测试过了 参考:http://my.oschina.net/kzhou

string-Android中如何使用Intent打开新界面,并且进行传值

问题描述 Android中如何使用Intent打开新界面,并且进行传值 我需要在Mainactivity.java中打开ShowProdure.java,其中的一个传值为'String=',和坐标(0,0),谢谢 解决方案 Intent Intent=new Intent(this,show.class); Intent.putExtra传字符串 Intent.putInt传数值 startActivity(Intent);无返回值跳转 startActivityForResultExtraAc