android 实现QQ好友列表(扩展listview:ExpandableListView)

某些android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的。接触Android,也才一年的时间,大部分时间花在工作上(解bug。。。),界面上开发很少参与。自己维护的系统应用里,有个ExpandableListView的界面(其实android例子APIDemo也有类似的例子)就在这里写个Demo供新手参考。

        ExpandableListView的用法:难点就是重写BaseExpandableListAdapter及提供的数据源。

        下面看看继承BaseExpandableListAdapter的适配器:


[java]
<span xmlns="http://www.w3.org/1999/xhtml" style="">package com.xyz.expande; 
 
import java.util.List; 
 
import android.app.AlertDialog; 
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; 
 
public class ExpandAdapter extends BaseExpandableListAdapter { 
 
    private Context mContext; 
    private LayoutInflater mInflater = null; 
    private String[]   mGroupStrings = null; 
    private List<List<Item>>   mData = null; 
 
    public ExpandAdapter(Context ctx, List<List<Item>> list) { 
        mContext = ctx; 
        mInflater = (LayoutInflater) mContext 
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        mGroupStrings = mContext.getResources().getStringArray(R.array.groups); 
        mData = list; 
    } 
 
    public void setData(List<List<Item>> list) { 
        mData = list; 
    } 
 
    @Override 
    public int getGroupCount() { 
        // TODO Auto-generated method stub 
        return mData.size(); 
    } 
 
    @Override 
    public int getChildrenCount(int groupPosition) { 
        // TODO Auto-generated method stub 
        return mData.get(groupPosition).size(); 
    } 
 
    @Override 
    public List<Item> getGroup(int groupPosition) { 
        // TODO Auto-generated method stub 
        return mData.get(groupPosition); 
    } 
 
    @Override 
    public Item getChild(int groupPosition, int childPosition) { 
        // TODO Auto-generated method stub 
        return mData.get(groupPosition).get(childPosition); 
    } 
 
    @Override 
    public long getGroupId(int groupPosition) { 
        // TODO Auto-generated method stub 
        return groupPosition; 
    } 
 
    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
        // TODO Auto-generated method stub 
        return childPosition; 
    } 
 
    @Override 
    public boolean hasStableIds() { 
        // TODO Auto-generated method stub 
        return false; 
    } 
 
    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, 
            View convertView, ViewGroup parent) { 
        // TODO Auto-generated method stub 
        if (convertView == null) { 
            convertView = mInflater.inflate(R.layout.group_item_layout, null); 
        } 
        GroupViewHolder holder = new GroupViewHolder(); 
        holder.mGroupName = (TextView) convertView 
                .findViewById(R.id.group_name); 
        holder.mGroupName.setText(mGroupStrings[groupPosition]); 
        holder.mGroupCount = (TextView) convertView 
                .findViewById(R.id.group_count); 
        holder.mGroupCount.setText("[" + mData.get(groupPosition).size() + "]"); 
        return convertView; 
    } 
 
    @Override 
    public View getChildView(int groupPosition, int childPosition, 
            boolean isLastChild, View convertView, ViewGroup parent) { 
        // TODO Auto-generated method stub 
        if (convertView == null) { 
            convertView = mInflater.inflate(R.layout.child_item_layout, null); 
        } 
        ChildViewHolder holder = new ChildViewHolder(); 
        holder.mIcon = (ImageView) convertView.findViewById(R.id.img); 
        holder.mIcon.setBackgroundResource(getChild(groupPosition, 
                childPosition).getImageId()); 
        holder.mChildName = (TextView) convertView.findViewById(R.id.item_name); 
        holder.mChildName.setText(getChild(groupPosition, childPosition) 
                .getName()); 
        holder.mDetail = (TextView) convertView.findViewById(R.id.item_detail); 
        holder.mDetail.setText(getChild(groupPosition, childPosition) 
                .getDetail()); 
        return convertView; 
    } 
 
    @Override 
    public boolean isChildSelectable(int groupPosition, int childPosition) { 
        // TODO Auto-generated method stub 
        <span style="color:#cc0000;">/*很重要:实现ChildView点击事件,必须返回true*/ 
</span>        return true; 
    } 
 
    private class GroupViewHolder { 
        TextView mGroupName; 
        TextView mGroupCount; 
    } 
 
    private class ChildViewHolder { 
        ImageView mIcon; 
        TextView mChildName; 
        TextView mDetail; 
    } 
 

</span> 
        里面用到的有两个布局,GroupView(子list没展开的view)如图: 
布局group_item_layout.xml如下:


[java] 
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" 
    android:orientation="horizontal" > 
 
    <TextView 
        android:id="@+id/group_name" 
        android:layout_width="wrap_content" 
        android:layout_height="?android:attr/listPreferredItemHeight" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_marginLeft="35dip" 
        android:gravity="center_vertical" 
        android:singleLine="true" /> 
 
    <TextView 
        android:id="@+id/group_count" 
        android:layout_width="wrap_content" 
        android:layout_height="?android:attr/listPreferredItemHeight" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_marginLeft="5dip" 
        android:gravity="center_vertical" 
        android:singleLine="true"/> 
 
</LinearLayout></span></span> 

         另外一个就是ChildView,本例仿QQ好友列表,如图:


哈哈,熟悉吧。布局child_item_layout.xml如下:


[java]
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:minHeight="@dimen/min_Height" 
    <span style="color:#ff0000;">android:descendantFocusability="blocksDescendants" 
</span>    android:orientation="horizontal" > 
 
    <ImageButton 
        android:id="@+id/img" 
        android:layout_width="@dimen/image_width" 
        android:layout_height="@dimen/image_width" 
        android:layout_marginLeft="2dip" 
        android:layout_marginRight="10dip" 
        android:layout_gravity="center_vertical" /> 
 
    <LinearLayout 
        android:layout_width="wrap_content" 
        android:layout_height="match_parent" 
        android:descendantFocusability="blocksDescendants" 
        android:orientation="vertical" > 
 
        <TextView 
            android:id="@+id/item_name" 
            android:layout_width="wrap_content" 
            android:layout_height="0.0dip" 
            android:gravity="center_vertical" 
            android:layout_weight="1" /> 
 
        <TextView 
            android:id="@+id/item_detail" 
            android:layout_width="wrap_content" 
            android:layout_height="0.0dip" 
            android:gravity="center_vertical" 
            android:singleLine="true" 
            android:ellipsize="end" 
            android:layout_weight="1" /> 
         
    </LinearLayout> 
 
</LinearLayout></span></span> 
        适配器弄好了,ExpandableListView就用系统的,现在只剩下显示的问题啦
        先来几张效果图:

 android 实现QQ好友列表(扩展listview:ExpandableListView)_第1张图片

 

 

android 实现QQ好友列表(扩展listview:ExpandableListView)_第2张图片

android 实现QQ好友列表(扩展listview:ExpandableListView)_第3张图片

android 实现QQ好友列表(扩展listview:ExpandableListView)_第4张图片

 

 

主Activity如下:

onChildClick

[java] 
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style="">package com.xyz.expande; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.DialogInterface.OnClickListener; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.ExpandableListView; 
import android.widget.ExpandableListView.OnChildClickListener; 
 
public class HomeActivity extends Activity implements OnChildClickListener { 
 
    private ExpandableListView mListView = null; 
    private ExpandAdapter mAdapter = null; 
    private List<List<Item>> mData = new ArrayList<List<Item>>(); 
 
    private int[] mGroupArrays = new int[] {  
            R.array.tianlongbabu, 
            R.array.shediaoyingxiongzhuan,  
            R.array.shendiaoxialv }; 
 
    private int[] mDetailIds = new int[] {  
            R.array.tianlongbabu_detail, 
            R.array.shediaoyingxiongzhuan_detail,  
            R.array.shendiaoxialv_detail }; 
 
    private int[][] mImageIds = new int[][] { 
            { R.drawable.img_00,  
              R.drawable.img_01,  
              R.drawable.img_02 }, 
            { R.drawable.img_10,  
              R.drawable.img_11,  
              R.drawable.img_12, 
              R.drawable.img_13,  
              R.drawable.img_14,  
              R.drawable.img_15, 
              R.drawable.img_16 }, 
            { R.drawable.img_20, 
              R.drawable.img_21 } }; 
 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        initData(); 
        mListView = new ExpandableListView(this); 
        mListView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
                LayoutParams.FILL_PARENT)); 
        setContentView(mListView); 
         
        mListView.setGroupIndicator(getResources().getDrawable( 
                R.drawable.expander_floder)); 
        mAdapter = new ExpandAdapter(this, mData); 
        mListView.setAdapter(mAdapter); 
        mListView 
                .setDescendantFocusability(ExpandableListView.FOCUS_AFTER_DESCENDANTS); 
        mListView.setOnChildClickListener(this); 
    } 
 
    <span style="color:#ff0000;">/*
     * ChildView 设置 布局很可能onChildClick进不来,要在 ChildView layout 里加上
     * android:descendantFocusability="blocksDescendants",
     * 还有isChildSelectable里返回true
     */ 
</span>    @Override 
    public boolean onChildClick(ExpandableListView parent, View v, 
            int groupPosition, int childPosition, long id) { 
        // TODO Auto-generated method stub 
        Item item = mAdapter.getChild(groupPosition, childPosition); 
        new AlertDialog.Builder(this) 
                .setTitle(item.getName()) 
                .setMessage(item.getDetail()) 
                .setIcon(android.R.drawable.ic_menu_more) 
                .setNegativeButton(android.R.string.cancel, 
                        new OnClickListener() { 
                            @Override 
                            public void onClick(DialogInterface dialog, 
                                    int which) { 
                                // TODO Auto-generated method stub 
 
                            } 
                        }).create().show(); 
        return true; 
    } 
 
    private void initData() { 
        for (int i = 0; i < mGroupArrays.length; i++) { 
            List<Item> list = new ArrayList<Item>(); 
            String[] childs = getStringArray(mGroupArrays[i]); 
            String[] details = getStringArray(mDetailIds[i]); 
            for (int j = 0; j < childs.length; j++) { 
                Item item = new Item(mImageIds[i][j], childs[j], details[j]); 
                list.add(item); 
            } 
            mData.add(list); 
        } 
    } 
 
    private String[] getStringArray(int resId) { 
        return getResources().getStringArray(resId); 
    } 
 
}</span></span> 
        这这个demo的时候,想实现ChildView的点击事件,实现接口onChildClick,发现不进来,很尴尬。。。最后还是在网上找到答案了,第一,在适配器里isChildSelectable 必须返回true,第二,ChildView布局child_item_layout.xml最外层的layout设置个属性:

[java] 
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style="">android:descendantFocusability="blocksDescendants"</span></span></span></span> 
上面已标示红色的啦。
       细心的同学会发现 Item 是啥?也贴出来吧

 

[java]
package com.xyz.expande; 
 
public class Item { 
     
    private int resId; 
    private String name; 
    private String detail; 
     
    public Item(int resId, String name, String detail) { 
        this.resId  = resId; 
        this.name   = name; 
        this.detail = detail; 
    } 
     
    public void setImageId(int resId) { 
        this.resId  = resId; 
    } 
     
    public int getImageId() { 
        return resId; 
    } 
     
    public void setName(String name) { 
        this.name   = name; 
    } 
     
    public String getName() { 
        return name; 
    } 
     
    public void setDetail(String detail) { 
        this.detail = detail; 
    } 
     
    public String getDetail() { 
        return detail; 
    } 
     
    public String toString() { 
        return "Item[" + resId + ", " + name + ", " + detail + "]"; 
    } 
 

你可能感兴趣的:(android 实现QQ好友列表(扩展listview:ExpandableListView))