用ExpandableListView实现类似QQ好友列表
ExpandableListView是一个用来显示二级节点的listview。
qq好友列表中子列表上下移动时,父节点在顶端会始终显示,这里我们可以自定义一个view来充当这个父节点。
主布局文件qq_listview如下,其中当我们拖动列表时,系统默认拖动过程中列表背景是黑的,我们可以通过android:cacheColorHint="#00000000"将其设置为透明,其中前两位是透明效果参数(00-99),后六位是颜色的设置。
Xml代码
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="https://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="@drawable/default_bg_hdpi">
- <LinearLayout
- android:id="@+id/gone_linear"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/expand_column_bg"
- android:visibility="gone"
- android:cacheColorHint="#50000000"
- >
- <ImageView android:id="@+id/qq_list_imageview"
- android:layout_width="wrap_content" android:layout_height="30dip"
- android:src="@drawable/narrow_select" />
- <TextView android:id="@+id/qq_list_textview" android:layout_marginLeft="50dip"
- android:layout_width="fill_parent" android:layout_height="wrap_content" />
- </LinearLayout>
- <FrameLayout android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ExpandableListView android:id="@+id/qq_listview"
- android:cacheColorHint="#00000000"
- android:layout_width="fill_parent" android:layout_height="wrap_content" />
- </FrameLayout>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/default_bg_hdpi"> <LinearLayout android: android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/expand_column_bg" android:visibility="gone" android:cacheColorHint="#50000000" > <ImageView android: android:layout_width="wrap_content" android:layout_height="30dip" android:src="@drawable/narrow_select" /> <TextView android: android:layout_marginLeft="50dip" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ExpandableListView android: android:cacheColorHint="#00000000" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </FrameLayout> </LinearLayout>
如果我们想更换父节点打开和关闭时的箭头,可以先设置一个selector.xml
Java代码
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="https://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:drawable="@drawable/expand_column_bg_over" />
- <item android:state_pressed="true" android:drawable="@drawable/expand_column_bg" />
- <item android:state_pressed="false" android:drawable="@drawable/feedlistdividerbg"></item>
- </selector>
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:andro> <item android:state_window_focused="false" android:drawable="@drawable/expand_column_bg_over" /> <item android:state_pressed="true" android:drawable="@drawable/expand_column_bg" /> <item android:state_pressed="false" android:drawable="@drawable/feedlistdividerbg"></item> </selector>
然后在代码中调用
Java代码
- elistview = (ExpandableListView)findViewById(R.id.qq_listview);
- //替换ExpandableListView的打开关闭时的箭头图标
- elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector));
elistview = (ExpandableListView)findViewById(R.id.qq_listview); //替换ExpandableListView的打开关闭时的箭头图标 elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector));
此外,我们还要设置父节点和子节点item的布局文件
父节点qq_list_parent.xml如下
Java代码
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="https://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/expand_column_bg">
- <TextView android:id="@+id/parend"
- android:layout_width="wrap_content"
- android:layout_height="30dip"
- android:layout_marginLeft="50dip"
- />
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/expand_column_bg"> <TextView android: android:layout_width="wrap_content" android:layout_height="30dip" android:layout_marginLeft="50dip" /> </LinearLayout>
子节点qq_listview_child.xml
Java代码
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="https://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:cacheColorHint="#00000000"
- >
- <TextView android:id="@+id/child"
- android:layout_width="wrap_content" android:layout_height="40dip"
- android:layout_marginLeft="80dip"
- />
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#00000000" > <TextView android: android:layout_width="wrap_content" android:layout_height="40dip" android:layout_marginLeft="80dip" /> </LinearLayout>
java代码如下
Java代码
- package com.sy.android.qqlistview;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Map;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.ExpandableListView;
- import android.widget.ExpandableListView.OnGroupCollapseListener;
- import android.widget.ExpandableListView.OnGroupExpandListener;
- import android.widget.LinearLayout;
- import android.widget.SimpleExpandableListAdapter;
- import android.widget.TextView;
- import com.sy.android.testAndroid.R;
- public class QQListView extends Activity {
- private static ArrayList<Map<String,String>> parentData = new ArrayList<Map<String,String>>();
- private static ArrayList<ArrayList<Map<String,String>>> childData = new ArrayList<ArrayList<Map<String,String>>>();
- private ExpandableListView elistview;
- private TextView tv;
- /**
- *当前打开的父节点
- */
- private int the_group_expand_position=-1;
- /**
- * 打开的父节点所与的子节点数
- */
- private int position_child_count=0;
- /**
- * 是否有打开的父节点
- */
- private boolean isExpanding=false;
- public void getData(){
- for(int i=0; i<20;i++){
- Map<String,String> map = new HashMap<String,String>();
- map.put("parend", i+"");
- parentData.add(map);
- }
- for(int i=0;i<20;i++){
- ArrayList<Map<String,String>> child = new ArrayList<Map<String,String>>();
- for(int j=0; j<20;j++){
- Map<String,String> map = new HashMap<String,String>();
- map.put("child", i+""+j);
- child.add(map);
- }
- childData.add(child);
- }
- }
- public void onCreate(Bundle saveBundle){
- super.onCreate(saveBundle);
- setContentView(R.layout.qq_listview);
- elistview = (ExpandableListView)findViewById(R.id.qq_listview);
- //替换ExpandableListView的打开关闭时的箭头图标
- elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector));
- tv = (TextView)findViewById(R.id.qq_list_textview);
- /**
- * 滑动子列表时在上方显示父节点的view
- */
- final LinearLayout linear = (LinearLayout)findViewById(R.id.gone_linear);
- /**
- * 监听父节点打开的事件
- */
- elistview.setOnGroupExpandListener(new OnGroupExpandListener(){
- @Override
- public void onGroupExpand(int groupPosition) {
- the_group_expand_position=groupPosition;
- position_child_count=childData.get(groupPosition).size();
- isExpanding=true;
- }
- });
- /**
- * 监听父节点关闭的事件
- */
- elistview.setOnGroupCollapseListener(new OnGroupCollapseListener(){
- @Override
- public void onGroupCollapse(int groupPosition) {
- if(linear.getVisibility()==View.VISIBLE){
- linear.setVisibility(View.GONE);
- }
- isExpanding=false;
- }
- });
- linear.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- linear.setVisibility(View.GONE);
- elistview.collapseGroup(the_group_expand_position);
- }
- });
- /**
- * 通过setOnScrollListener来监听列表上下滑动时item显示和消失的事件
- */
- elistview.setOnScrollListener(new OnScrollListener(){
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- }
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- if(isExpanding){
- // 当当前第一个item id小于打开的父节点id 或大于打开的父节点id和它的子节点总数之和时
- if(firstVisibleItem<the_group_expand_position ||
- firstVisibleItem>(the_group_expand_position+position_child_count)){
- linear.setVisibility(View.GONE);
- }else{
- linear.setVisibility(View.VISIBLE);
- tv.setText(((Map)parentData.get(the_group_expand_position)).get("parend").toString());
- }
- }
- }
- });
- getData();
- SimpleExpandableListAdapter selAdapter = new SimpleExpandableListAdapter(this,
- parentData,
- R.layout.qq_listview_parend_item,
- new String[]{"parend"},
- new int[]{R.id.parend},
- childData,
- R.layout.qq_liatview_child_item,
- new String[]{"child"},
- new int[]{R.id.child}
- );
- elistview.setAdapter(selAdapter);
- }
- }
package com.sy.android.qqlistview; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnGroupCollapseListener; import android.widget.ExpandableListView.OnGroupExpandListener; import android.widget.LinearLayout; import android.widget.SimpleExpandableListAdapter; import android.widget.TextView; import com.sy.android.testAndroid.R; public class QQListView extends Activity { private static ArrayList<Map<String,String>> parentData = new ArrayList<Map<String,String>>(); private static ArrayList<ArrayList<Map<String,String>>> childData = new ArrayList<ArrayList<Map<String,String>>>(); private ExpandableListView elistview; private TextView tv; /** *当前打开的父节点 */ private int the_group_expand_position=-1; /** * 打开的父节点所与的子节点数 */ private int position_child_count=0; /** * 是否有打开的父节点 */ private boolean isExpanding=false; public void getData(){ for(int i=0; i<20;i++){ Map<String,String> map = new HashMap<String,String>(); map.put("parend", i+""); parentData.add(map); } for(int i=0;i<20;i++){ ArrayList<Map<String,String>> child = new ArrayList<Map<String,String>>(); for(int j=0; j<20;j++){ Map<String,String> map = new HashMap<String,String>(); map.put("child", i+""+j); child.add(map); } childData.add(child); } } public void onCreate(Bundle saveBundle){ super.onCreate(saveBundle); setContentView(R.layout.qq_listview); elistview = (ExpandableListView)findViewById(R.id.qq_listview); //替换ExpandableListView的打开关闭时的箭头图标 elistview.setGroupIndicator(this.getResources().getDrawable(R.drawable.expand_list_selector)); tv = (TextView)findViewById(R.id.qq_list_textview); /** * 滑动子列表时在上方显示父节点的view */ final LinearLayout linear = (LinearLayout)findViewById(R.id.gone_linear); /** * 监听父节点打开的事件 */ elistview.setOnGroupExpandListener(new OnGroupExpandListener(){ @Override public void onGroupExpand(int groupPosition) { the_group_expand_position=groupPosition; position_child_count=childData.get(groupPosition).size(); isExpanding=true; } }); /** * 监听父节点关闭的事件 */ elistview.setOnGroupCollapseListener(new OnGroupCollapseListener(){ @Override public void onGroupCollapse(int groupPosition) { if(linear.getVisibility()==View.VISIBLE){ linear.setVisibility(View.GONE); } isExpanding=false; } }); linear.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { linear.setVisibility(View.GONE); elistview.collapseGroup(the_group_expand_position); } }); /** * 通过setOnScrollListener来监听列表上下滑动时item显示和消失的事件 */ elistview.setOnScrollListener(new OnScrollListener(){ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if(isExpanding){ // 当当前第一个item id小于打开的父节点id 或大于打开的父节点id和它的子节点总数之和时 if(firstVisibleItem<the_group_expand_position || firstVisibleItem>(the_group_expand_position+position_child_count)){ linear.setVisibility(View.GONE); }else{ linear.setVisibility(View.VISIBLE); tv.setText(((Map)parentData.get(the_group_expand_position)).get("parend").toString()); } } } }); getData(); SimpleExpandableListAdapter selAdapter = new SimpleExpandableListAdapter(this, parentData, R.layout.qq_listview_parend_item, new String[]{"parend"}, new int[]{R.id.parend}, childData, R.layout.qq_liatview_child_item, new String[]{"child"}, new int[]{R.id.child} ); elistview.setAdapter(selAdapter); } }
实现的思路是通过setOnScrollListener来监听listview,从而获得显示在视图中的item的id,通过id的判断来决定显示在顶端的自定义的view是否显示
最后更新:2017-04-02 06:51:49