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>>解釋,紅色的是組,里面的是子,每個組里不一定有幾個子(這里畫了兩個)。

 完


免責聲明!

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



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