zoukankan      html  css  js  c++  java
  • Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)

    之前的博文《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、length
    2 for (int i = 0; i < Group.size(); i++) { 
    3     expandableListView.expandGroup(i); 
    4 } 
    提醒:加载前别忘了判断adapter是否为空和有没有Group数据哦

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

    1 expandableListView.setOnGroupClickListener(new OnGroupClickListener() {
    2     @Override
    3     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         <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: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             <TextView
    26                 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         <View
    34             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                 <ImageView
    100                     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                 <TextView
    106                     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     @Override
    101     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     @Override
    29     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             @Override
    45             public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
    46                 return true;
    47             }
    48         });
    49         return view;
    50     }
    51 }

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

  • 相关阅读:
    我的 vs code 中setting 设置
    创建Vue cli 脚手架中遇到的空格,函数问题的解决
    C#与.Net的关系
    c#可以开发哪些类型的应用程序
    json注解使用(jackson与fastjson)
    MySQL优化:如何避免回表查询
    二叉树基础知识总结
    Redis,Memcache,MongoDb的特点
    MySQL的InnoDB存储引擎为什么要用自增的主键?
    分布式事务atomikos使用
  • 原文地址:https://www.cnblogs.com/panhouye/p/6231599.html
Copyright © 2011-2022 走看看