• Android之微信朋友圈UI实现--ExpandableListView+GridView


    PS:我们都知道微信,更是知道朋友圈,很多人在朋友圈里卖起了化妆品,打入广告等为自己做一下推广,里面会附带一写好看的图片,上面有标题,有描述,整体布局每场的美观,那么这是怎么实现的呢,有些人可能会单个使用ListView,也会使用GridView,那么listview嵌套gridview你使用过吗,现在先看一张图,

    这张图是不是很熟悉,没错这个就是朋友圈,里面有一个,里面的布局我都画出来了,我不知道微信具体怎么实现的,但是我们会用安卓原生的方法去实现这样的布局,并有实实在在的数据。

    思路:

    首页这是一个可以滑动的view,但是分为标题(用户名)和内容,并且内容下面还有图片,图片也是不确定的。这里就用ExpandableListView+GridView,如果有人不了解这个ExpandableListView的话,看完这篇基本用法就会了。

    步骤:

    1. 总布局的创建,里面只要一个ExpandableListView控件。
    2. ExpandableListView的item布局创建,本布局用最传统的做法分为Group和Child布局。
      1. Group布局只显示一个用户名
      2. Child布局就要为描述内容和GridView(存放图片)。
    3. ExpandableListView适配器创建。
    4. 数据加载。

    查看效果图,这个图在上传的时候压缩了就变的模糊了,请谅解。

    1: 总布局的创建,里面只要一个ExpandableListView控件。

    这里文件非常简单,只有一个控件,当然ExpandableListView也是有很多属性的。这里都没有写,去掉箭头,在Activity中动态添加。这里布局文件我都省去了根布局LinearLayout。

     <ExpandableListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/id_elv"/>

    2:ExpandableListView的item布局创建,本布局用最传统的做法分为Group和Child布局

    2.1:这个就比较多了文件,首先来写一下Group的布局,名字你随便起,我这里叫grouplayout.xml

    <ImageView
            android:id="@+id/id_group_img"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/id_group_name"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:gravity="center"
            android:textSize="40px"
            android:layout_marginLeft="10dp"
            android:text="name"/>

    2.2:其次是Child的布局,名字也是随便起,我这里叫childlayout.xml

    <TextView
            android:id="@+id/id_dec"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:gravity="center"
            android:textSize="35px"
            android:layout_marginLeft="10dp"
            android:text="describe"/>
        <GridView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:numColumns="3"
            android:id="@+id/id_gv"></GridView>

    2.3:还有一个布局文件,那就是GridView的item布局

    <ImageView
            android:id="@+id/id_img"
            android:src="@mipmap/ic_launcher"
            android:layout_width="match_parent"
            android:layout_margin="20dp"
            android:layout_height="100dp" />

    3:ExpandableListView适配器创建

    适配器的创建才是重点,首先我们对ExpandableListView自定义适配器,然后再在里面嵌套一个GridView的自定义适配器,当然你也可以调用系统的,不过个人觉得自定义有更好的灵活性。在这之前呢,我们需要创建几个bean类,group里有img图片和text文字,child有text文字和img图片数组。因为用户可能会多发几张照片,不光是一个。下面有两个class,稍微看一下就Ok了,不用太在意非要一样。

    package mus.cn.shopeffect;
    /**
     * Created by cMusketeer on 18/5/23.
     *
     * @author 刘志通
     */
    
    public class GroupBean {
        String groupImg,name;
    
        public String getGroupImg() {
            return groupImg;
        }
    
        public void setGroupImg(String groupImg) {
            this.groupImg = groupImg;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    import java.util.List;
    
    /**
     * Created by cMusketeer on 18/5/23.
     *
     * @author 刘志通
     */
    
    public class ChildBean {
        public String childDesc;
        public List<String> childImg;
    
        public String getChildDesc() {
            return childDesc;
        }
    
        public void setChildDesc(String childDesc) {
            this.childDesc = childDesc;
        }
    
        public List<String> getChildImg() {
            return childImg;
        }
    
        public void setChildImg(List<String> childImg) {
            this.childImg = childImg;
        }
    }

    创建Adapter,首先我们要继承adapter,这里和以前的就不一样了,我们要继承BaseExpandableListAdapter,当你继承后,系统就会让你重写里面的方法,方法有很多,不用全部,有如下几个就行了(有的小伙伴系统提示的全部继承,还缺一个)。

    3.1:方法作用详情(没有先后顺序,古无序号)

    首先定义变量(这里listChild为什么list里泛型还是list,我在Activity中解释)

      public Context context;
        public List<GroupBean> listGroup;
        public List<List<ChildBean>> listChild;

    组Group(父)的长度

     @Override
        public int getGroupCount() {
            return listGroup.size();
        }

    某个组中child(子)的长度

     @Override
        public int getChildrenCount(int groupPosition) {
            return listChild.get(groupPosition).size();
        }

    拿到父的项

     @Override
        public Object getGroup(int groupPosition) {
            return listGroup.get(groupPosition);
        }

    拿到组(父)中子的项

     @Override
        public Object getChild(int groupPosition, int childPosition) {
            return listChild.get(groupPosition).get(childPosition);
        }

    拿到父、子id

    @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }
    
        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

    组和子元素是否持有稳定的ID。

    @Override
        public boolean hasStableIds() {
            return false;
        }

     返回值:如果当前适配器不包含任何数据则返回True。经常用来决定一个空视图是否应该被显示。

    @Override
        public boolean isEmpty() {
            return false;
        }
    子项是否可以选中
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

    3.2:补充:这里还有一些方法,你如果是没有用的话,就不用写。

    public abstract void onGroupCollapsed (int groupPosition)
    当组收缩状态的时候此方法被调用。
    参数: groupPosition 收缩状态的组索引
    public abstract void onGroupExpanded(int groupPosition)
    当组展开状态的时候此方法被调用。

    3.3:下面才是重点,分别是getGroupView和getChildView用来显示视图。具体看注释。

    图片加载库Glide依赖:compile 'com.github.bumptech.glide:glide:3.7.0'
    @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            ViewHoldeGroup viewHoldeGroup;
            if (convertView == null) {//没有视图时创建
                convertView = LayoutInflater.from(context).inflate(R.layout.grouplayout, null);//添加布局文件
                viewHoldeGroup = new ViewHoldeGroup();//创建holder对象
                viewHoldeGroup.imageView = (ImageView) convertView.findViewById(R.id.id_group_img);//拿到控件
                viewHoldeGroup.textView = (TextView) convertView.findViewById(R.id.id_group_name);
                convertView.setTag(viewHoldeGroup);
            } else {
                viewHoldeGroup = (ViewHoldeGroup) convertView.getTag();
            }//这里我用的Glide框架,用来加载网络图片的。
            Glide.with(context).load(listGroup.get(groupPosition).getGroupImg()).asBitmap().into(viewHoldeGroup.imageView);
            viewHoldeGroup.textView.setText(listGroup.get(groupPosition).getName());
            return convertView;
        }
    
        class ViewHoldeGroup {
            ImageView imageView;
            TextView textView;
        }
    
        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            ViewHoldeChild viewHoldeChild;
            GVAdapter gvAdapter;
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.childlayout, null);
                viewHoldeChild = new ViewHoldeChild();
                viewHoldeChild.gridView = (GridView) convertView.findViewById(R.id.id_gv);
                viewHoldeChild.textView = (TextView) convertView.findViewById(R.id.id_dec);
                convertView.setTag(viewHoldeChild);
            } else {
                viewHoldeChild = (ViewHoldeChild) convertView.getTag();
            }
            viewHoldeChild.textView.setText(listChild.get(groupPosition).get(childPosition).getChildDesc());
            gvAdapter = new GVAdapter(context, listChild.get(groupPosition).get(childPosition).getChildImg());//适配器
            viewHoldeChild.gridView.setAdapter(gvAdapter);
            return convertView;
        }
    
        class ViewHoldeChild {
            TextView textView;
            GridView gridView;
        }

    到这里呢我们可以看到Gridview的适配器,写在了ExpandableListView适配器的里面,数据还是一样的传递。GridView的适配器我就不写了,太简单,写上代码量就大了。

    4:数据加载

    4.1:Activity中最后一步,下面有解释。

     //添加组数据
            List<GroupBean> listGroup = new ArrayList<>();
            GroupBean groupBean;
            for (int i = 0; i < 10; i++) {
                groupBean = new GroupBean();
                groupBean.setGroupImg("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1116338067,147640299&fm=27&gp=0.jpg");
                groupBean.setName("测试");
                listGroup.add(groupBean);
            }
            //添加组中子的数据,这里我解释一下list嵌套list,比如说一共是10个组,每个组里有一个子项目,每个子项目中又有2个图片
            List<List<ChildBean>> listChild = new ArrayList<>();
            List<ChildBean> list;//子的数据
            List<String> liImg;//子中图片的数据
            ChildBean childBean;
            for (int i = 0; i < 10; i++) {
                list = new ArrayList<>();
                for (int j = 0; j < 1; j++) {
                    childBean = new ChildBean();
                    liImg = new ArrayList<>();
                    for (int k = 0; k < 2; k++) {//图片加载
                        liImg.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1527344951394&di=6dc7f379165a02c45e8df43106dbb153&imgtype=0&src=http%3A%2F%2Fimg.sc115.com%2Fuploads%2Fsc%2Fjpgs%2F1407%2Fapic4833_sc115.com.jpg");
                    }
                    childBean.setChildImg(liImg);
                    childBean.setChildDesc("我是一个描述,我在图片的上面");
                    list.add(childBean);//添加到子中
                }
                listChild.add(list);
            }
    
            ExpandableAdapter expandableAdapter = new ExpandableAdapter(this, listGroup, listChild);
            lv.setAdapter(expandableAdapter);
            //默认展开
            if (expandableAdapter != null) {
                for (int i = 0; i < listGroup.size(); i++) {
                    lv.expandGroup(i);
                }
            }
            //去除箭头
            lv.setGroupIndicator(null);

    List<List<ChildBean>>解释,红色的是组,里面的是子,每个组里不一定有几个子(这里画了两个)。

     完

  • 相关阅读:
    织梦系统的安装与详细信息
    js 报错 :object is not a function
    css3中动画animation的应用
    js 中 setTimeout()的用法
    CSS3 Gradient-CSS3渐变
    css3 transform 变形
    CSS3 transition 属性
    只要有人的地方,世界就不是冰冷的。
    CSS层
    css区块定位之浮动与清除属性
  • 原文地址:https://www.cnblogs.com/cmusketeer/p/9079941.html
Copyright © 2020-2023  润新知