Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)

来源:互联网 时间:2017-01-13

之前的博文《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 设置适配器后,添加以下代码:

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


提醒:加载前别忘了判断adapter是否为空和有没有Group数据哦
(2)保持ExpandableListView始终展开无法收缩

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


(3)取消通讯录上方的groupName空间
微信通讯录中“新的朋友”,“群聊”,“标签”,“公众号”,作为一个整体自定义布局添加到ExpandableListView中,详情见以下代码实现
(4)修改ExpandableListView的分割线
大概思路就是这样,现在开始整体实现代码的演示:

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

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

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@color/fragmentback"> 6 <ExpandableListView 7 android:id="@+id/contact_list" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent"10 android:layout_alignParentTop="true"11 android:layout_alignParentStart="true"12 android:divider ="#FFFFFF"/>13 </LinearLayout>


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

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

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@color/fragmentback"> 6 <TextView 7 android:text="TextView" 8 android:textSize="20sp" 9 android:layout_width="match_parent"10 android:layout_height="wrap_content"11 android:layout_marginLeft="10dp"12 android:gravity="center_vertical"13 android:id="@+id/group_tv" />14 </LinearLayout>


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

这里添加了自定义分割线

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 <LinearLayout 6 android:background="@color/colorwhite" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 android:orientation="vertical">10 <LinearLayout11 android:paddingLeft="10dp"12 android:paddingTop="5dp"13 android:paddingBottom="5dp"14 android:gravity="center_vertical"15 android:layout_width="match_parent"16 android:layout_height="wrap_content"17 android:orientation="horizontal">18 <ImageView19 android:id="@+id/contact_item_iv"20 android:layout_width="wrap_content"21 android:layout_height="wrap_content"22 android:src="@mipmap/default_fmessage"23 android:adjustViewBounds="true"24 android:maxWidth="35dp"/>25 <TextView26 android:id="@+id/contact_item_tv"27 android:layout_margin="10dp"28 android:layout_width="0dp"29 android:layout_height="wrap_content"30 android:layout_weight="1"31 android:text="新的朋友"/>32 </LinearLayout>33 <View34 android:layout_width="match_parent"35 android:layout_height="1dp"36 android:layout_marginLeft="10dp"37 android:layout_marginRight="10dp"38 android:background="@color/fragmentback"/>39 </LinearLayout>40 </LinearLayout>


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

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

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 <LinearLayout 6 android:background="@color/colorwhite" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 android:orientation="vertical"> 10 <LinearLayout 11 android:paddingLeft="10dp" 12 android:paddingTop="5dp" 13 android:paddingBottom="5dp" 14 android:gravity="center_vertical" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:orientation="horizontal"> 18 <ImageView 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:src="@mipmap/default_fmessage" 22 android:adjustViewBounds="true" 23 android:maxWidth="35dp"/> 24 <TextView 25 android:layout_margin="10dp" 26 android:layout_width="0dp" 27 android:layout_height="wrap_content" 28 android:layout_weight="1" 29 android:text="新的朋友"/> 30 </LinearLayout> 31 <View 32 android:layout_width="match_parent" 33 android:layout_height="1dp" 34 android:layout_marginLeft="10dp" 35 android:layout_marginRight="10dp" 36 android:background="@color/fragmentback"/> 37 <LinearLayout 38 android:paddingLeft="10dp" 39 android:paddingTop="5dp" 40 android:paddingBottom="5dp" 41 android:gravity="center_vertical" 42 android:layout_width="match_parent" 43 android:layout_height="wrap_content" 44 android:orientation="horizontal"> 45 <ImageView 46 android:layout_width="wrap_content" 47 android:layout_height="wrap_content" 48 android:src="@mipmap/default_chatroom" 49 android:adjustViewBounds="true" 50 android:maxWidth="35dp"/> 51 <TextView 52 android:layout_margin="10dp" 53 android:layout_width="0dp" 54 android:layout_height="wrap_content" 55 android:layout_weight="1" 56 android:text="群聊"/> 57 </LinearLayout> 58 <View 59 android:layout_width="match_parent" 60 android:layout_height="1dp" 61 android:layout_marginLeft="10dp" 62 android:layout_marginRight="10dp" 63 android:background="@color/fragmentback"/> 64 <LinearLayout 65 android:paddingLeft="10dp" 66 android:paddingTop="5dp" 67 android:paddingBottom="5dp" 68 android:gravity="center_vertical" 69 android:layout_width="match_parent" 70 android:layout_height="wrap_content" 71 android:orientation="horizontal"> 72 <ImageView 73 android:layout_width="wrap_content" 74 android:layout_height="wrap_content" 75 android:src="@mipmap/default_contactlabel" 76 android:adjustViewBounds="true" 77 android:maxWidth="35dp"/> 78 <TextView 79 android:layout_margin="10dp" 80 android:layout_width="0dp" 81 android:layout_height="wrap_content" 82 android:layout_weight="1" 83 android:text="标签"/> 84 </LinearLayout> 85 <View 86 android:layout_width="match_parent" 87 android:layout_height="1dp" 88 android:layout_marginLeft="10dp" 89 android:layout_marginRight="10dp" 90 android:background="@color/fragmentback"/> 91 <LinearLayout 92 android:paddingLeft="10dp" 93 android:paddingTop="5dp" 94 android:paddingBottom="5dp" 95 android:gravity="center_vertical" 96 android:layout_width="match_parent" 97 android:layout_height="wrap_content" 98 android:orientation="horizontal"> 99 <ImageView100 android:layout_width="wrap_content"101 android:layout_height="wrap_content"102 android:src="@mipmap/default_servicebrand_contact"103 android:adjustViewBounds="true"104 android:maxWidth="35dp"/>105 <TextView106 android:layout_margin="10dp"107 android:layout_width="0dp"108 android:layout_height="wrap_content"109 android:layout_weight="1"110 android:text="公众号"/>111 </LinearLayout>112 </LinearLayout>113 </LinearLayout>


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

(1)这里模仿实际项目,将自定义适配器定义定义在外部同意管理,所以需要设置相关构造方法供expandableListView调用
(2)为了实现头文件的布局,需要在getGroupView与getChildView方法中判断头文件的位置,从而调整布局,这里我们将头文件定义在数据首位

1 import android.content.Context; 2 import android.view.LayoutInflater; 3 import android.view.View; 4 import android.view.ViewGroup; 5 import android.widget.BaseExpandableListAdapter; 6 import android.widget.ImageView; 7 import android.widget.TextView; 8 import com.mly.panhouye.wechat.R; 9 /** 10 * Created by panchengjia on 2016/12/28 0028. 11 */ 12 public class MyExpandableListAdapter extends BaseExpandableListAdapter { 13 Context context; 14 String[] group; 15 String[][] itemName; 16 int[][] itemIcon; 17 public MyExpandableListAdapter(Context context, String[] group, String[][] itemName, int[][] itemIcon) { 18 this.context = context; 19 this.group = group; 20 this.itemName = itemName; 21 this.itemIcon = itemIcon; 22 } 23 24 @Override 25 public int getGroupCount() { 26 return group.length; 27 } 28 29 @Override 30 public int getChildrenCount(int groupPosition) { 31 return itemName[groupPosition].length; 32 } 33 34 @Override 35 public Object getGroup(int groupPosition) { 36 return group[groupPosition]; 37 } 38 39 @Override 40 public Object getChild(int groupPosition, int childPosition) { 41 return itemName[groupPosition][childPosition]; 42 } 43 44 @Override 45 public long getGroupId(int groupPosition) { 46 return groupPosition; 47 } 48 49 @Override 50 public long getChildId(int groupPosition, int childPosition) { 51 return childPosition; 52 } 53 54 @Override 55 public boolean hasStableIds() { 56 return false; 57 } 58 59 @Override 60 public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 61 ViewHolder vh; 62 //ExpandableList的第一个分组没有组名,这里需要自定义布局 63 if(groupPosition==0){ 64 convertView =LayoutInflater.from(context).inflate(R.layout.contact_list_title,null); 65 }else{ 66 if(convertView==null){ 67 convertView= LayoutInflater.from(context).inflate(R.layout.contact_list_group_item,null); 68 vh = new ViewHolder(); 69 vh.tv = (TextView) convertView.findViewById(R.id.group_tv); 70 convertView.setTag(vh); 71 } 72 vh = (ViewHolder) convertView.getTag(); 73 74 vh.tv.setText(group[groupPosition]); 75 } 76 77 return convertView; 78 } 79 80 @Override 81 public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 82 ViewHolder vh; 83 //ExpandableList的第一个分组没有组名,这里需要自定义布局 84 if (groupPosition==0){ 85 convertView =LayoutInflater.from(context).inflate(R.layout.contact_list_title,null); 86 }else{ 87 if(convertView==null){ 88 convertView= LayoutInflater.from(context).inflate(R.layout.contact_list_item,null); 89 vh = new ViewHolder(); 90 vh.tv = (TextView) convertView.findViewById(R.id.contact_item_tv); 91 vh.iv= (ImageView) convertView.findViewById(R.id.contact_item_iv); 92 convertView.setTag(vh); 93 } 94 vh = (ViewHolder) convertView.getTag(); 95 vh.tv.setText(itemName[groupPosition][childPosition]); 96 vh.iv.setImageResource(itemIcon[groupPosition][childPosition]); 97 } 98 return convertView; 99 }100 @Override101 public boolean isChildSelectable(int groupPosition, int childPosition) {102 return true;103 }104 class ViewHolder{105 TextView tv;106 ImageView iv;107 }108 }


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

1 import android.os.Bundle; 2 import android.support.annotation.Nullable; 3 import android.support.v4.app.Fragment; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.ExpandableListView; 8 import com.mly.panhouye.wechat.R; 9 import com.mly.panhouye.wechat.adapter.MyExpandableListAdapter;10 11 /**12 * Created by panchengjia on 2016/12/28 0028.13 */14 15 public class ContactFragment extends Fragment {16 private ExpandableListView contact_list;17 //定义分组以及组内成员(设置头文件位置为空)18 String[] group ={"","好友列表"};19 String[][] itemName={{},{"郭嘉", "黄月英", "华佗",20 "刘备", "陆逊", "吕布", "吕蒙", "马超", "司马懿", "孙权", "孙尚香", "夏侯惇",21 "许褚", "杨修", "张飞", "赵云", "甄姬", "周瑜", "诸葛亮"}};22 int[][] itemIcon={{},{R.mipmap.guojia,23 R.mipmap.huangyueying, R.mipmap.huatuo,24 R.mipmap.liubei, R.mipmap.luxun, R.mipmap.lvbu, R.mipmap.lvmeng,25 R.mipmap.machao, R.mipmap.simayi, R.mipmap.sunquan, R.mipmap.sunshangxiang,26 R.mipmap.xiahoudun, R.mipmap.xuchu, R.mipmap.yangxiu, R.mipmap.zhangfei,27 R.mipmap.zhaoyun, R.mipmap.zhenji, R.mipmap.zhouyu, R.mipmap.zhugeliang}};28 @Override29 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {30 View view = inflater.inflate(R.layout.contact_fragment,container,false);31 contact_list = (ExpandableListView) view.findViewById(R.id.contact_list);32 //实例化适配器33 MyExpandableListAdapter myExpandableListAdapter=new MyExpandableListAdapter(getContext(),group,itemName,itemIcon);34 //配置适配器35 contact_list.setAdapter(myExpandableListAdapter);36 //去掉ExpandableListView 默认的箭头37 contact_list.setGroupIndicator(null);38 //设置ExpandableListView默认展开39 for (int i = 0; i <group.length; i++) {40 contact_list.expandGroup(i);41 }42 //设置ExpandableListView不可点击收回43 contact_list.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {44 @Override45 public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {46 return true;47 }48 });49 return view;50 }51 }


实现方法很多大家开动吧(建议使用recyclerView),我先睡了。

相关阅读:
Top