用ExpandableListView实现类似QQ好友列表

ExpandableListView是一个用来显示二级节点的listview。

qq好友列表中子列表上下移动时,父节点在顶端会始终显示,这里我们可以自定义一个view来充当这个父节点。

 

主布局文件qq_listview如下,其中当我们拖动列表时,系统默认拖动过程中列表背景是黑的,我们可以通过android:cacheColorHint="#00000000"将其设置为透明,其中前两位是透明效果参数(00-99),后六位是颜色的设置。

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   android:layout_width="fill_parent"  
  5.   android:layout_height="wrap_content"  
  6.   android:orientation="vertical"  
  7.   android:background="@drawable/default_bg_hdpi">  
  8.   <LinearLayout  
  9.      android:id="@+id/gone_linear"  
  10.      android:layout_width="fill_parent"  
  11.      android:layout_height="wrap_content"  
  12.      android:background="@drawable/expand_column_bg"  
  13.      android:visibility="gone"  
  14.      android:cacheColorHint="#50000000"  
  15.   >  
  16.   <ImageView android:id="@+id/qq_list_imageview"   
  17.     android:layout_width="wrap_content"  android:layout_height="30dip"   
  18.     android:src="@drawable/narrow_select" />  
  19.   <TextView android:id="@+id/qq_list_textview"   android:layout_marginLeft="50dip"  
  20.     android:layout_width="fill_parent" android:layout_height="wrap_content" />  
  21.     </LinearLayout>  
  22.     <FrameLayout android:layout_width="fill_parent"  
  23.         android:layout_height="fill_parent">  
  24.   <ExpandableListView android:id="@+id/qq_listview"  
  25.      android:cacheColorHint="#00000000"  
  26.     android:layout_width="fill_parent" android:layout_height="wrap_content" />  
  27.     </FrameLayout>  
  28. </LinearLayout>  

 

如果我们想更换父节点打开和关闭时的箭头,可以先设置一个selector.xml

 

Java代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:state_window_focused="false" android:drawable="@drawable/expand_column_bg_over" />  
  4.     <item android:state_pressed="true" android:drawable="@drawable/expand_column_bg" />  
  5.     <item android:state_pressed="false" android:drawable="@drawable/feedlistdividerbg"></item>  
  6. </selector>  

 然后在代码中调用

 

Java代码  收藏代码
  1. elistview = (ExpandableListView)findViewById(R.id.qq_listview);  
  2. //替换ExpandableListView的打开关闭时的箭头图标  
  3. elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector));  

 

此外,我们还要设置父节点和子节点item的布局文件

父节点qq_list_parent.xml如下

 

Java代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   android:layout_width="fill_parent"  
  5.   android:layout_height="fill_parent"     
  6.   android:background="@drawable/expand_column_bg">  
  7.   <TextView android:id="@+id/parend"  
  8.     android:layout_width="wrap_content"   
  9.     android:layout_height="30dip"  
  10.     android:layout_marginLeft="50dip"  
  11.      />  
  12. </LinearLayout>  

 

子节点qq_listview_child.xml

 

Java代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   android:layout_width="fill_parent"  
  5.   android:layout_height="fill_parent"  
  6.   android:cacheColorHint="#00000000"  
  7.  >  
  8.     <TextView android:id="@+id/child"  
  9.         android:layout_width="wrap_content" android:layout_height="40dip"  
  10.         android:layout_marginLeft="80dip"  
  11.         />  
  12. </LinearLayout>  

 

java代码如下

 

Java代码  收藏代码
  1. package com.sy.android.qqlistview;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.AbsListView;  
  12. import android.widget.AbsListView.OnScrollListener;  
  13. import android.widget.ExpandableListView;  
  14. import android.widget.ExpandableListView.OnGroupCollapseListener;  
  15. import android.widget.ExpandableListView.OnGroupExpandListener;  
  16. import android.widget.LinearLayout;  
  17. import android.widget.SimpleExpandableListAdapter;  
  18. import android.widget.TextView;  
  19.   
  20. import com.sy.android.testAndroid.R;  
  21.   
  22. public class QQListView extends Activity   {  
  23.       
  24.     private static ArrayList<Map<String,String>> parentData = new ArrayList<Map<String,String>>();  
  25.     private static ArrayList<ArrayList<Map<String,String>>> childData = new ArrayList<ArrayList<Map<String,String>>>();  
  26.     private ExpandableListView elistview;  
  27.     private TextView tv;  
  28.       
  29.     /** 
  30.      *当前打开的父节点 
  31.      */  
  32.     private int the_group_expand_position=-1;  
  33.     /** 
  34.      * 打开的父节点所与的子节点数 
  35.      */  
  36.     private int position_child_count=0;  
  37.     /** 
  38.      * 是否有打开的父节点 
  39.      */  
  40.     private boolean isExpanding=false;  
  41.       
  42.     public void getData(){  
  43.         for(int i=0; i<20;i++){  
  44.              Map<String,String> map = new HashMap<String,String>();  
  45.              map.put("parend", i+"");  
  46.              parentData.add(map);  
  47.         }  
  48.         for(int i=0;i<20;i++){  
  49.             ArrayList<Map<String,String>> child = new ArrayList<Map<String,String>>();  
  50.             for(int j=0; j<20;j++){  
  51.                 Map<String,String> map = new HashMap<String,String>();  
  52.                 map.put("child", i+""+j);  
  53.                 child.add(map);  
  54.             }  
  55.             childData.add(child);  
  56.         }  
  57.     }  
  58.       
  59.     public void onCreate(Bundle saveBundle){  
  60.         super.onCreate(saveBundle);  
  61.         setContentView(R.layout.qq_listview);  
  62.           
  63.         elistview = (ExpandableListView)findViewById(R.id.qq_listview);  
  64.         //替换ExpandableListView的打开关闭时的箭头图标  
  65.         elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector));  
  66.         tv = (TextView)findViewById(R.id.qq_list_textview);  
  67.           
  68.         /** 
  69.          * 滑动子列表时在上方显示父节点的view 
  70.          */  
  71.         final LinearLayout linear = (LinearLayout)findViewById(R.id.gone_linear);  
  72.           
  73.         /** 
  74.          * 监听父节点打开的事件 
  75.          */  
  76.         elistview.setOnGroupExpandListener(new OnGroupExpandListener(){  
  77.   
  78.             @Override  
  79.             public void onGroupExpand(int groupPosition) {  
  80.                 the_group_expand_position=groupPosition;  
  81.                 position_child_count=childData.get(groupPosition).size();  
  82.                 isExpanding=true;  
  83.             }  
  84.               
  85.         });  
  86.           
  87.         /** 
  88.          * 监听父节点关闭的事件 
  89.          */  
  90.         elistview.setOnGroupCollapseListener(new OnGroupCollapseListener(){  
  91.   
  92.             @Override  
  93.             public void onGroupCollapse(int groupPosition) {  
  94.                 if(linear.getVisibility()==View.VISIBLE){  
  95.                     linear.setVisibility(View.GONE);  
  96.                 }  
  97.                 isExpanding=false;  
  98.             }  
  99.               
  100.         });  
  101.           
  102.   
  103.         linear.setOnClickListener(new OnClickListener(){  
  104.   
  105.             @Override  
  106.             public void onClick(View v) {  
  107.                 linear.setVisibility(View.GONE);  
  108.                 elistview.collapseGroup(the_group_expand_position);  
  109.             }  
  110.               
  111.         });  
  112.           
  113.         /** 
  114.          * 通过setOnScrollListener来监听列表上下滑动时item显示和消失的事件 
  115.          */  
  116.           
  117.         elistview.setOnScrollListener(new OnScrollListener(){  
  118.   
  119.             @Override  
  120.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
  121.                   
  122.             }  
  123.   
  124.             @Override  
  125.             public void onScroll(AbsListView view, int firstVisibleItem,  
  126.                     int visibleItemCount, int totalItemCount) {  
  127.                 if(isExpanding){  
  128.                     // 当当前第一个item id小于打开的父节点id 或大于打开的父节点id和它的子节点总数之和时  
  129.                     if(firstVisibleItem<the_group_expand_position ||  
  130.                             firstVisibleItem>(the_group_expand_position+position_child_count)){  
  131.                         linear.setVisibility(View.GONE);  
  132.                     }else{  
  133.                         linear.setVisibility(View.VISIBLE);  
  134.                         tv.setText(((Map)parentData.get(the_group_expand_position)).get("parend").toString());  
  135.                     }  
  136.                 }  
  137.             }  
  138.               
  139.         });  
  140.           
  141.         getData();  
  142.           
  143.         SimpleExpandableListAdapter selAdapter = new SimpleExpandableListAdapter(this,  
  144.                 parentData,  
  145.                 R.layout.qq_listview_parend_item,  
  146.                 new String[]{"parend"},  
  147.                 new int[]{R.id.parend},  
  148.                 childData,  
  149.                 R.layout.qq_liatview_child_item,  
  150.                 new String[]{"child"},  
  151.                 new int[]{R.id.child}  
  152.                 );  
  153.         elistview.setAdapter(selAdapter);  
  154.   
  155.     }  
  156.   
  157. }  

 

 

实现的思路是通过setOnScrollListener来监听listview,从而获得显示在视图中的item的id,通过id的判断来决定显示在顶端的自定义的view是否显示

路漫漫其修远兮 吾将上下而求索
原文地址:https://www.cnblogs.com/hudabing/p/3085210.html