之前的博文《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),我先睡了。

Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)的更多相关文章

  1. Android中Fragment和ViewPager那点事儿(仿微信APP)

    在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...

  2. vue聊天室|h5+vue仿微信聊天界面|vue仿微信

    一.项目简介 基于Vue2.0+Vuex+vue-router+webpack2.0+es6+vuePhotoPreview+wcPop等技术架构开发的仿微信界面聊天室——vueChatRoom,实现 ...

  3. web版仿微信聊天界面|h5仿微信电脑端案例开发

    前几天开发了一款手机端h5仿微信聊天,人唯有不停学习才能进步,这段时间倒腾着整理了下之前项目,又重新在原先的那版基础上开发了一款仿微信聊天电脑端web版本,聊天页面又重新优化了多图预览.视频播放,右键 ...

  4. Android中如何做到自定义的广播只能有指定的app接收

    今天没吊事,又去面试了,具体哪家公司就不说了,因为我在之前的blog中注明了那些家公司的名字,结果人家给我私信说我泄露他们的题目,好吧,我错了...其实当我们已经在工作的时候,我们可以在空闲的时间去面 ...

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

    昨天的(今天凌晨)的博文<Android中Fragment和ViewPager那点事儿>中,我们通过使用Fragment和ViewPager模仿实现了微信的布局框架.今天我们来通过使用Li ...

  6. Android中使用ExpandableListView实现好友分组

    一个视图显示垂直滚动两级列表中的条目.这不同于列表视图,允许两个层次,类似于QQ的好友分组.要实现这个效果的整体思路为: 1.要给ExpandableListView 设置适配器,那么必须先设置数据源 ...

  7. uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面

    一.介绍 运用UniApp+Vue+Vuex+swiper+uniPop等技术开发的仿微信原生App聊天室|仿微信聊天界面实例项目uniapp-chatroom,实现了发送图文消息.表情(gif图), ...

  8. Android 平板中 自己定义键盘(popuwindow) 居于屏幕左下方 仿微信的password输入界面

          之前博客中,介绍过使用谷歌提供的键盘的一些api,能够非常好地自己定义键盘,參考我之前的博客链接:android 自己定义键盘 ,这个有一个局限性,仅仅能占满屏幕,无法做到仅仅能占一部分的 ...

  9. 在Android中实现service动态更新UI界面

    之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...

随机推荐

  1. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  2. html中如何添加提示信息

    提示:在标签中添加title属性 1.文本中如何添加提示信息? 1.1直接在标签中加title="值": 例如:<p title="爱笑,爱哭,爱生活"& ...

  3. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  4. 02.LoT.UI 前后台通用框架分解系列之——灵活的菜单栏

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  5. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 3.安装Clus ...

  6. 编写高质量代码:改善Java程序的151个建议(第8章:异常___建议114~117)

    建议114:不要在构造函数中抛出异常 Java异常的机制有三种: Error类及其子类表示的是错误,它是不需要程序员处理也不能处理的异常,比如VirtualMachineError虚拟机错误,Thre ...

  7. JQuery的基础和应用

    <参考文档>   1.什么是?    DOM的作用:提供了一种动态的操作HTML元素的方法.    jQuery是一个优秀的js库.用来操作HTML元素的工具.    jQuery和DOM ...

  8. Node.js Express连接mysql完整的登陆注册系统(windows)

    windows学习环境: node 版本: v0.10.35 express版本:4.10.0 mysql版本:5.6.21-log 第一部分:安装node .Express(win8系统 需要&qu ...

  9. VS2013中的MVC5模板部署到mono上的艰辛历程

    部署环境:CentOS7 + Mono 3.10 + Jexus 5.6 在Xamarin.Studio创建的asp.net项目,部署过程非常顺利,没有遇到什么问题:但在VS2013中创建的asp.n ...

  10. 【初码干货】在Window Server 2016中使用Web Deploy方式发布.NET Web应用的重新梳理

    在学习和工作的过程中,发现很多同事.朋友,在做.NET Web应用发布的时候,依然在走 生成-复制到服务器 这样的方式,稍微高级一点的,就是先发布到本地,再上传到服务器 这种方式不仅效率低下,而且不易 ...