android 實現QQ好友列表(擴展listview:ExpandableListView)

某些android開發羣裏,看到有些新手問怎麼實現QQ好友列表,其實網上一搜挺多的。接觸Android,也才一年的時間,大部分時間花在工做上(解bug。。。),界面上開發不多參與。本身維護的系統應用裏,有個ExpandableListView的界面(其實android例子APIDemo也有相似的例子)就在這裏寫個Demo供新手參考。 html

        ExpandableListView的用法:難點就是重寫BaseExpandableListAdapter及提供的數據源。 java

        下面看看繼承BaseExpandableListAdapter的適配器: android


[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以下: app


[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>  ide

         另一個就是ChildView,本例仿QQ好友列表,如圖: 佈局


哈哈,熟悉吧。佈局child_item_layout.xml以下: ui


[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就用系統的,如今只剩下顯示的問題啦
        先來幾張效果圖: this

 

 

 

\

\

\

 

 

主Activity以下: spa

onChildClick xml

[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 + "]";      }    } 

相關文章
相關標籤/搜索