android 實現QQ好友列表


在某些Android開發群里,看到有些新手問怎么實現QQ好友列表,其實網上一搜挺多的。接觸Android,也才一年的時間,大部分時間花在工作上(解bug。。。),界面上開發很少參與。自己維護的系統應用里,有個ExpandableListView的界面(其實android例子APIDemo也有類似的例子)就在這里寫個Demo供新手參考。        ExpandableListView的用法:難點就是重寫BaseExpandableListAdapter及提供的數據源。

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

代碼片段,雙擊復制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<SPAN xmlns= "http://www.w3.org/1999/xhtml" > 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;
  
</LinearLayout></SPAN></SPAN>


        TextView mDetail;
    }

}
</SPAN>[/mw_shl_code]

里面用到的有兩個布局,GroupView(子list沒展開的view)如圖:  
<IGNORE_JS_OP>




布局group_item_layout.xml如下:

代碼片段,雙擊復制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<SPAN xmlns= "http://www.w3.org/1999/xhtml" ><SPAN xmlns= "http://www.w3.org/1999/xhtml" ><?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好友列表,如圖:
<IGNORE_JS_OP>




布局child_item_layout.xml如下:

代碼片段,雙擊復制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<SPAN xmlns= "http://www.w3.org/1999/xhtml" ><SPAN xmlns= "http://www.w3.org/1999/xhtml" ><?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就用系統的,現在只剩下顯示的問題啦

先來幾張效果圖:

<IGNORE_JS_OP>

    <IGNORE_JS_OP>



<IGNORE_JS_OP>

   <IGNORE_JS_OP>



主Activity如下:

onChildClick

代碼片段,雙擊復制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<SPAN xmlns= "http://www.w3.org/1999/xhtml" ><SPAN xmlns= "http://www.w3.org/1999/xhtml" > 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設置個屬性

細心的同學會發現 Item 是啥?也貼出來吧

代碼片段,雙擊復制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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 + "]" ;
    }
  
}



源碼下載: <IGNORE_JS_OP> ExpandeList.zip (670.11 KB, 下載次數: 988)

http://www.eoeandroid.com/forum.php?mod=misc&action=attachcredit&aid=81469&formhash=2f2ef89c

原文:http://blog.csdn.net/zhouyuanjing/article/details/8254421


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM