zoukankan      html  css  js  c++  java
  • Android ExpandableListView BaseExpandableListAdapter (类似QQ分组列表)

    分组列表视图(ExpandableListView)

    和ListView不同的是它是一个两级的滚动列表视图,每一个组可以展开,显示一些子项,类似于
    QQ列表,这些项目来至于ExpandableListAdapter的子类,也就是说,要实现向里面添加项目,必
    须写一个子类实现ExpandableListAdapter的接口或者使用系统为我们实现在子类

       常用属性   

        1. android:childDivider 指定各组内子类表项之间的分隔条,

        2. android:childIndicator 显示在子列表旁边的Drawable对象

        3. android:childIndicatorLeft 子列表项指示符的左边约束位置

        4. android:childIndicatorRight 子列表项指示符的右边约束位置

        5. android:groupIndicator 显示在组列表旁边的Drawable对象

        6. android:indicatorLeft 组列表项指示器的左边约束位置

        7. android:indicatorRight 组列表项指示器的右边约束位置

    一般适用于ExpandableListView的Adapter都要继承BaseExpandableListAdapter这个类,
    并且必须重载getGroupView和getChildView这两个最为重要的方法。
    当扩展BaseExpandableListAdapter时,要实现全部方法,关键是实现其中的四个方法。

    1、首相activity_main.xml布局搭建

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent">
     4 
     5     <ExpandableListView
     6         android:layout_width="wrap_content"
     7         android:layout_height="wrap_content"
     8         android:id="@+id/elv"/>
     9 
    10 </RelativeLayout>
    activity_main.xml

    2、然后是搭建QQ分组的布局

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical" >
     5 
     6     <TextView
     7         android:id="@+id/groupName"
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         android:textSize="20sp"
    11         android:text="分组名称" />
    12 
    13     <TextView
    14         android:id="@+id/groupOnline"
    15         android:layout_alignParentRight="true"
    16         android:layout_width="wrap_content"
    17         android:layout_height="wrap_content"
    18         android:text="0/8" />
    19 
    20 </RelativeLayout>
    item_group.xml

    3、再搭建分组中各选项的布局(QQ联系人,包括头像,昵称,签名)

       这里由于引用了外部的自定义的控件,所以这里包名加类名

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:layout_gravity="center_vertical"
     5     android:orientation="horizontal" >
     6 
     7     <com.test.lesson7_expandablelistview.CircleImageView
     8         android:id="@+id/img"
     9         android:layout_width="80dp"
    10         android:layout_height="80dp"
    11         android:src="@drawable/ic_launcher" />
    12 
    13     <LinearLayout
    14         android:layout_width="match_parent"
    15         android:layout_height="wrap_content"
    16         android:layout_marginLeft="10dp"
    17         android:orientation="vertical" >
    18 
    19         <TextView
    20             android:id="@+id/nickName"
    21             android:layout_width="match_parent"
    22             android:layout_height="wrap_content"
    23             android:text="昵称"
    24             android:textSize="18sp" />
    25 
    26         <LinearLayout
    27             android:layout_width="match_parent"
    28             android:layout_height="wrap_content"
    29             android:layout_marginTop="10dp"
    30             android:orientation="horizontal" >
    31 
    32             <TextView
    33                 android:id="@+id/online"
    34                 android:layout_width="wrap_content"
    35                 android:layout_height="wrap_content"
    36                 android:text="[在线]" />
    37 
    38             <TextView
    39                 android:id="@+id/sign"
    40                 android:layout_width="wrap_content"
    41                 android:layout_height="wrap_content"
    42                 android:layout_marginLeft="10dp"
    43                 android:text="我要飞的更高~" />
    44         </LinearLayout>
    45     </LinearLayout>
    46 
    47 </LinearLayout>
    item_child.xml

    4、圆角图片形状

      在res/values中建circle_attr.xml

    1 <resources>
    2 
    3     <declare-styleable name="CircularImage">
    4         <attr name="border_width" format="dimension" />
    5         <attr name="border_color" format="color" />
    6     </declare-styleable>
    7 
    8 </resources>

    5、然后新建一个CircleImageView继承ImageView

      此处自定义控件是在GitHub上下载

     1 public class CircleImageView extends ImageView {
     2     private static final Xfermode MASK_XFERMODE;
     3     private Bitmap mask;
     4     private Paint paint;
     5     private int mBorderWidth = 10;
     6     private int mBorderColor = Color.parseColor("#f2f2f2");
     7     private boolean useDefaultStyle = false;
     8 
     9     static {
    10         PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
    11         MASK_XFERMODE = new PorterDuffXfermode(localMode);
    12     }
    13 
    14     public CircleImageView(Context context) {
    15         super(context);
    16     }
    17 
    18     public CircleImageView(Context context, AttributeSet attrs) {
    19         this(context, attrs, 0);
    20     }
    21 
    22     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
    23         super(context, attrs, defStyle);
    24         TypedArray a = context.obtainStyledAttributes(attrs,
    25                 R.styleable.CircularImage);
    26         mBorderColor = a.getColor(R.styleable.CircularImage_border_color,
    27                 mBorderColor);
    28         final int def = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
    29         mBorderWidth = a.getDimensionPixelOffset(
    30                 R.styleable.CircularImage_border_width, def);
    31         a.recycle();
    32     }
    33 
    34     private void useDefaultStyle(boolean useDefaultStyle) {
    35         this.useDefaultStyle = useDefaultStyle;
    36     }
    37 
    38     @Override
    39     protected void onDraw(Canvas canvas) {
    40         if (useDefaultStyle) {
    41             super.onDraw(canvas);
    42             return;
    43         }
    44         final Drawable localDraw = getDrawable();
    45         if (localDraw == null) {
    46             return;
    47         }
    48         if (localDraw instanceof NinePatchDrawable) {
    49             return;
    50         }
    51         if (this.paint == null) {
    52             final Paint localPaint = new Paint();
    53             localPaint.setFilterBitmap(false);
    54             localPaint.setAntiAlias(true);
    55             localPaint.setXfermode(MASK_XFERMODE);
    56             this.paint = localPaint;
    57         }
    58         final int width = getWidth();
    59         final int height = getHeight();
    60         int layer = canvas.saveLayer(0.0F, 0.0F, width, height, null, 31);
    61         localDraw.setBounds(0, 0, width, height);
    62         localDraw.draw(canvas);
    63         if ((this.mask == null) || (this.mask.isRecycled())) {
    64             this.mask = createOvalBitmap(width, height);
    65         }
    66         canvas.drawBitmap(this.mask, 0.0F, 0.0F, this.paint);
    67         canvas.restoreToCount(layer);
    68         drawBorder(canvas, width, height);
    69     }
    70 
    71     private void drawBorder(Canvas canvas, final int width, final int height) {
    72         if (mBorderWidth == 0) {
    73             return;
    74         }
    75         final Paint mBorderPaint = new Paint();
    76         mBorderPaint.setStyle(Paint.Style.STROKE);
    77         mBorderPaint.setAntiAlias(true);
    78         mBorderPaint.setColor(mBorderColor);
    79         mBorderPaint.setStrokeWidth(mBorderWidth);
    80         canvas.drawCircle(width / 2, height / 2, (width - mBorderWidth) / 2,
    81                 mBorderPaint);
    82         canvas = null;
    83     }
    84 
    85     public Bitmap createOvalBitmap(final int width, final int height) {
    86         Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
    87         Bitmap localBitmap = Bitmap.createBitmap(width, height, localConfig);
    88         Canvas localCanvas = new Canvas(localBitmap);
    89         Paint localPaint = new Paint();
    90         final int padding = (mBorderWidth - 3) > 0 ? mBorderWidth - 3 : 1;
    91 
    92         RectF localRectF = new RectF(padding, padding, width - padding, height
    93                 - padding);
    94         localCanvas.drawOval(localRectF, localPaint);
    95 
    96         return localBitmap;
    97     }
    98 
    99 }
    CircleImageView

    6、创建Group类

     1 public class Group {
     2     //分组名
     3     public String groupName;
     4     //有很多User
     5     public List<User> list;
     6     
     7     public Group(String groupName){
     8         this.groupName = groupName;
     9         list = new ArrayList<User>();
    10     }
    11     //添加User
    12     public void addUser(User user){
    13         list.add(user);
    14     }
    15     
    16     //获取某个分组中User的数量
    17     public int getChildCount() {
    18         return list.size();
    19     }
    20     //获取某个分组中User在线的数量
    21     public int getOnlineCount(){
    22         int sum = 0;
    23         for (User user : list) {
    24             if(user.isOnline()){
    25                 sum++;
    26             }
    27         }
    28         return sum;
    29     }
    30     //获取分组中某个孩子
    31     public User getChild(int childPosition) {
    32         return list.get(childPosition);
    33     }
    34     
    35     
    36 }
    Group.java

    7、创建User类

     1 public class User {
     2     private int imgId;
     3     private String nickName;
     4     private boolean isOnline;
     5     private String sign;
     6     
     7     
     8     public User() {
     9         super();
    10     }
    11     public User(int imgId, String nickName, boolean isOnline, String sign) {
    12         super();
    13         this.imgId = imgId;
    14         this.nickName = nickName;
    15         this.isOnline = isOnline;
    16         this.sign = sign;
    17     }
    18     
    19     public int getImgId() {
    20         return imgId;
    21     }
    22     public void setImgId(int imgId) {
    23         this.imgId = imgId;
    24     }
    25     public String getNickName() {
    26         return nickName;
    27     }
    28     public void setNickName(String nickName) {
    29         this.nickName = nickName;
    30     }
    31     public boolean isOnline() {
    32         return isOnline;
    33     }
    34     public void setOnline(boolean isOnline) {
    35         this.isOnline = isOnline;
    36     }
    37     public String getSign() {
    38         return sign;
    39     }
    40     public void setSign(String sign) {
    41         this.sign = sign;
    42     }
    43     
    44     
    45     
    46     
    47 }
    User

    8、设置适配器

      1 public class GroupAdapter extends BaseExpandableListAdapter{
      2 
      3     Context context;
      4     List<Group> list;
      5     
      6     public GroupAdapter(Context context, List<Group> list) {
      7         this.context = context;
      8         this.list = list;
      9     }
     10     
     11     @Override
     12     public View getGroupView(int groupPosition, boolean isExpanded,
     13             View convertView, ViewGroup parent) {
     14         GroupHolder holder;
     15         if(convertView == null){
     16             convertView = View.inflate(context, R.layout.item_grouplayout, null);
     17             holder = new GroupHolder(convertView);
     18             convertView.setTag(holder);
     19         }else{
     20             holder = (GroupHolder) convertView.getTag();
     21         }
     22         //设置数据
     23         Group group = getGroup(groupPosition);
     24         holder.groupName.setText(group.groupName);
     25         holder.groupOnline.setText(group.getOnlineCount()+"/"+getChildrenCount(groupPosition));
     26         
     27         return convertView;
     28     }
     29 
     30     @Override
     31     public View getChildView(int groupPosition, int childPosition,
     32             boolean isLastChild, View convertView, ViewGroup parent) {
     33         ChildHolder holder;
     34         if(convertView == null){
     35             convertView = View.inflate(context, R.layout.item_childlayout, null);
     36             holder = new ChildHolder(convertView);
     37             convertView.setTag(holder);
     38         }else{
     39             holder = (ChildHolder) convertView.getTag();
     40         }
     41         //设置数据
     42         User user = getGroup(groupPosition).getChild(childPosition);
     43         holder.img.setImageResource(user.getImgId());
     44         holder.nickName.setText(user.getNickName());
     45         holder.online.setText(user.isOnline()?"[在线]":"[离线]");
     46         holder.sign.setText(user.getSign());
     47         
     48         return convertView;
     49         
     50     }
     51     
     52     class GroupHolder{
     53         TextView groupName;
     54         TextView groupOnline;
     55         
     56         public GroupHolder(View convertView){
     57             groupName = (TextView) convertView.findViewById(R.id.groupName);
     58             groupOnline = (TextView) convertView.findViewById(R.id.groupOnline);
     59             
     60         }
     61     }
     62     class ChildHolder{
     63         ImageView img;
     64         TextView nickName;
     65         TextView online;
     66         TextView sign;
     67         
     68         public ChildHolder(View convertView){
     69             img = (ImageView) convertView.findViewById(R.id.img);
     70             nickName = (TextView) convertView.findViewById(R.id.nickName);
     71             online = (TextView) convertView.findViewById(R.id.online);
     72             sign = (TextView) convertView.findViewById(R.id.sign);
     73             
     74         }
     75         
     76     }
     77     
     78     @Override
     79     public int getGroupCount() {
     80         return list.size();
     81     }
     82 
     83     @Override
     84     public int getChildrenCount(int groupPosition) {
     85         return list.get(groupPosition).getChildCount();
     86     }
     87 
     88     @Override
     89     public Group getGroup(int groupPosition) {
     90         return list.get(groupPosition);
     91     }
     92 
     93     @Override
     94     public User getChild(int groupPosition, int childPosition) {
     95         return list.get(groupPosition).getChild(childPosition);
     96     }
     97 
     98     @Override
     99     public long getGroupId(int groupPosition) {
    100         return groupPosition;
    101     }
    102 
    103     @Override
    104     public long getChildId(int groupPosition, int childPosition) {
    105         return childPosition;
    106     }
    107 
    108     @Override
    109     public boolean hasStableIds() {
    110         return true;
    111     }
    112 
    113     @Override
    114     public boolean isChildSelectable(int groupPosition, int childPosition) {
    115         return true;
    116     }
    117 
    118 }
    GroupAdapter

    9、MainActivity.java中将所有组件找到,初始化数据源,并给ListView设置适配器

     1 public class MainActivity extends Activity {
     2 
     3     ExpandableListView elv;
     4     private List<Group> list = new ArrayList<Group>();
     5     int[] img = new int[6];
     6     
     7     @Override
     8     protected void onCreate(Bundle savedInstanceState) {
     9         super.onCreate(savedInstanceState);
    10         setContentView(R.layout.activity_main);
    11         initData();
    12         elv = (ExpandableListView) findViewById(R.id.elv);
    13         GroupAdapter adapter = new GroupAdapter(getBaseContext(), list);
    14         elv.setAdapter(adapter);
    15         
    16     }
    17 
    18     private void initData() {
    19         for (int i = 0; i < img.length; i++) {
    20             try {
    21                 img[i] = R.drawable.class.getField("img0"+(i+1)).getInt(null);
    22             } catch (Exception e) {
    23                 e.printStackTrace();
    24             }
    25         }
    26         
    27         Group group1 = new Group("贵圈好乱");
    28         group1.addUser(new User(img[0], "张翰", true, "我爱娜扎!"));
    29         group1.addUser(new User(img[1], "郑爽", false, "妈蛋,要么瘦,要么死!"));
    30         group1.addUser(new User(img[2], "胡彦斌", true, "其实我只是长得抽象了"));
    31         group1.addUser(new User(img[5], "撒贝宁", true, "子怡当年没选择我是个美丽的错误"));
    32         group1.addUser(new User(img[3], "杨幂", false, "其实我跟恺威已经离婚了,现在跟李易峰在一起,就酱~"));
    33         
    34         Group group2 = new Group("超星星");
    35         group2.addUser(new User(img[4], "林志炫", true, "其实我的小肚子都是唱歌导致的,哈哈哈"));
    36         
    37         list.add(group1);
    38         list.add(group2);
    39         
    40     }
    41     
    42     
    43 }
    MainActivity.java

    运行效果有点渣渣。请忽略:

  • 相关阅读:
    XML to bean
    监控Informix-Url
    ld-linux.so.2: bad ELF interpreter
    Oracle
    我的北漂生活:我来北京一个月了
    C/C++ 常量的定义与应用(编程中的常量)
    C/C++ 常量的定义与应用(编程中的常量)
    英文名字的昵称(亲切的叫法)
    英文名字的昵称(亲切的叫法)
    动态规划的关键 —— 子问题 & 公式化
  • 原文地址:https://www.cnblogs.com/Claire6649/p/5955713.html
Copyright © 2011-2022 走看看