TabLayout+ ViewPager + RecyclerView,ViewPager再嵌套ViewPager

文章目录

  • TabLayout+ ViewPager + RecyclerView, ViewPager再嵌套ViewPager,RecyclerView中实现线性布局和网格布局
    • Gradle 跟布局文件
    • 在最后加入网络请求

TabLayout+ ViewPager + RecyclerView, ViewPager再嵌套ViewPager,RecyclerView中实现线性布局和网格布局

一般ViewPager里面都是使用Fragment,但是现在页面复杂,除了顶部有标签页之外,下面底部还会有几个模块,这次我是实现其中的一个模块,因为模块使用Fragment,所以这里就没有使用Fragment,直接使用RecyclerView,下面放上图片介绍这次app

TabLayout+ ViewPager + RecyclerView,ViewPager再嵌套ViewPager_第1张图片

TabLayout+ ViewPager + RecyclerView,ViewPager再嵌套ViewPager_第2张图片

Gradle 跟布局文件

implementation 'com.android.support:recyclerview-v7:26.1.0'

布局文件中直接定义TabLayout 和VIewPager

   <android.support.design.widget.TabLayout
        android:id="@+id/tbl_main"
        android:layout_width="match_parent"
        android:layout_height="128dp"
        app:tabIndicatorColor="#EF8092"
        app:tabSelectedTextColor="#333333"
        app:tabTextColor="#999999"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="5dp"></android.support.v4.view.ViewPager>


private static int[] titles = {R.string.jd, R.string.tb, R.string.share_make};
private void initView(){

        tbLayout = (TabLayout) findViewById(R.id.tbl_main);
        viewPager = findViewById(R.id.viewpager);

        RecyclerView recycler1 = (RecyclerView) LayoutInflater.from(this).inflate(R.layout.layout_recycler, null);
        RecyclerView recycler2 = (RecyclerView) LayoutInflater.from(this).inflate(R.layout.layout_recycler, null);
        RecyclerView recycler3 = (RecyclerView) LayoutInflater.from(this).inflate(R.layout.layout_recycler, null);

        // 设置布局
        GridLayoutManager linearLayoutManager1 = new GridLayoutManager(this, 2);
        GridLayoutManager linearLayoutManager2 = new GridLayoutManager(this, 2);
        GridLayoutManager linearLayoutManager3 = new GridLayoutManager(this, 2);
        recycler1.setLayoutManager(linearLayoutManager1);
        recycler2.setLayoutManager(linearLayoutManager2);
        recycler3.setLayoutManager(linearLayoutManager3);

        adapterJd = new RvAdapter(this, false, false);
        adapterTb = new RvAdapter(this, false, true);
        adapterShare = new RvAdapter(this, true, false);

        recycler1.setAdapter(adapterJd);
        recycler2.setAdapter(adapterTb);
        recycler3.setAdapter(adapterShare);

        mList.add(recycler1);
        mList.add(recycler2);
        mList.add(recycler3);

        ViewPAdapter adapter = new ViewPAdapter(mList);
        viewPager.setAdapter(adapter);
        tbLayout.setupWithViewPager(viewPager);

        viewPager.setOnPageChangeListener(this);

        //设置自定义视图
        for (int i = 0; i < titles.length; i++) {
            tbLayout.getTabAt(i).setCustomView(getTabView(i));
        }
        tbLayout.setTabMode(TabLayout.MODE_FIXED);
    }

/**
     * 自定义Tab
     * @param position  位置
     * @return
     */
public View getTabView(int position) {
        View v = LayoutInflater.from(this).inflate(R.layout.layout_tab, null);
        ImageView imgIcon = (ImageView) v.findViewById(R.id.img_tab_icon);
        TextView tv = (TextView) v.findViewById(R.id.tv_tab_jd);
        TextView tvDes = (TextView) v.findViewById(R.id.tv_tab_jd_tip);
        tv.setText(getString(titles[position]));
       
        return v;
    }

定义ViewHolder

static class HeadViewHolder extends RecyclerView.ViewHolder{
        ImageView imgAdIcon;
        ChildViewPager viewPager;
        TabLayout tabLayout;
        TextView tvTitle, tvSubTitle;
        public HeadViewHolder(View itemView) {
            super(itemView);

            imgAdIcon = itemView.findViewById(R.id.img_item_part_ad);
            viewPager = (ChildViewPager) itemView.findViewById(R.id.viewpager_ad);
            tabLayout = (TabLayout) itemView.findViewById(R.id.tbl_share_ad);
            tvTitle = itemView.findViewById(R.id.tv_item_part_con1);
            tvSubTitle = itemView.findViewById(R.id.tv_item_part_con2);


        }
    }


    static class LViewHolder extends RecyclerView.ViewHolder{

        ImageView imgIcon;
        TextView tvName, tvPrice, tvCurPrice;

        public LViewHolder(View itemView) {
            super(itemView);
            imgIcon = itemView.findViewById(R.id.img_item_l_icon);
            tvName = itemView.findViewById(R.id.tv_item_list_name);
            tvPrice = itemView.findViewById(R.id.tv_item_l_yuan_price);
            tvCurPrice = itemView.findViewById(R.id.tv_item_list_price);

        }
    }

    static class LineViewHolder extends RecyclerView.ViewHolder{
        TextView tvName, tvCon;
        public LineViewHolder(View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.item_part_name);
            tvCon = itemView.findViewById(R.id.item_part_con);
        }
    }

    static class GViewHolder extends RecyclerView.ViewHolder{

        ImageView imgIcon;
        TextView tvName, tvPrice, tvCurPrice, tvFTab;

        public GViewHolder(View itemView) {
            super(itemView);
            imgIcon = itemView.findViewById(R.id.img_item_g_icon);
            tvName = itemView.findViewById(R.id.tv_item_g_name);
            tvPrice = itemView.findViewById(R.id.tv_item_g_yuan_price);
            tvCurPrice = itemView.findViewById(R.id.tv_item_g_price);
            tvFTab = itemView.findViewById(R.id.tv_item_g_ftab);

        }
    }

判断ViewType,并调用onCreateViewHolder

private static final int Type_View_Head = 0;    //头部,广告和子网格
    private static final int Type_View_List = 1;    //线性列表
    private static final int Type_View_Gride = 2;   //最下面的网格
    private static final int Type_View_Line = 3;    //两个布局之间的文字
@Override
    public int getItemViewType(int position) {
        return checkViewType(position);
    }
    
    /**
     * 判断属于那种类型
     * @param position
     * @return
     */
    private int checkViewType(int position){
        if(position == 0){
            return Type_View_Head;
        } else if(position > getListCount()+1) { //网格
            return Type_View_Gride;
        } else if(position == getListCount()+1){
            return Type_View_Line;
        } else{
            return Type_View_List;
        }
    }

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder;
        if(viewType == Type_View_Head){
            View view = LayoutInflater.from(mContext).inflate(R.layout.item_part_ad, null);
            viewHolder = new HeadViewHolder(view);
        } else if(viewType == Type_View_Line){
            View view = LayoutInflater.from(mContext).inflate(R.layout.item_part_tv, null);
            viewHolder = new LineViewHolder(view);
        } else if(viewType == Type_View_List){
            View view = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
            viewHolder = new LViewHolder(view);
        } else {
            View view = LayoutInflater.from(mContext).inflate(R.layout.item_g, null);
            viewHolder = new GViewHolder(view);
        }

        return viewHolder;
    }

下面接下来这个方法就是把其他非网格布局的改为线性布局,根据个人需求可以在这个方法修改为其他布局

/**
     * 把网格布局换为线性布局
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
            GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup(){
                @Override
                public int getSpanSize(int position) {

                    if(checkViewType(position) == Type_View_Gride) { //网格
                        return Type_View_List;
                    }else{
                        return Type_View_Gride;
                    }
                }
            });
        }


    }
 @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        ProductBean bean;
        if(checkViewType(position) == Type_View_Head){  //头部
            HeadViewHolder h = (HeadViewHolder) holder;
            if(bannerBean != null){
                String imgUrl = bannerBean.getCover();
                if(null != imgUrl && !imgUrl.startsWith("http")){
                    imgUrl = HttpUrl.Image_Url + imgUrl;
                }
                Glide.with(mContext).load(imgUrl).error(R.mipmap.ic_launcher).into(h.imgAdIcon);
            }

            if(cateList != null && !cateList.isEmpty()){
                int a = cateList.size();
                int b = 10;
                int pager = a%b == 0 ? (a/b) : (a/b)+1;
                List<List<CategoriesBean>> catList = groupList(cateList);
                List<View> viewList = new ArrayList<>();
                for(int i=0; i<pager; i++){
                    LinearLayout layout = (LinearLayout) LayoutInflater.from(mContext)
                            .inflate(R.layout.item_part_ad_childvp, null);
                    GridViewInScrollView gridView = layout.findViewById(R.id.gridview_item);
                    MenuShareAdapter adapter = new MenuShareAdapter(mContext);
                    gridView.setAdapter(adapter);

                    viewList.add(layout);
                    adapter.update(catList.get(i));
                }
                if(isShare){
                    h.viewPager.setVisibility(View.VISIBLE);
                }else{
                    h.viewPager.setVisibility(View.GONE);
                }
                ViewPAdapter adapter = new ViewPAdapter(viewList);
                h.viewPager.setAdapter(adapter);
                h.tabLayout.setupWithViewPager(h.viewPager);
                h.tabLayout.setTabMode(TabLayout.MODE_FIXED);

                adapter.notifyDataSetChanged();
            }



        } else if(checkViewType(position) == Type_View_Line){   //显示线
            LineViewHolder h = (LineViewHolder) holder;
            h.tvName.setText(title);
            h.tvCon.setText(description);
        } else if(checkViewType(position) == Type_View_Gride){ //网格
            bean = gList.get(getGridPosition(position));
            GViewHolder h = (GViewHolder) holder;
            h.tvName.setText(bean.getName());
            h.tvPrice.setText(bean.getPrice());

            if(isTb){
                h.tvFTab.setVisibility(View.VISIBLE);
            } else {
                h.tvFTab.setVisibility(View.GONE);
            }

            bean.isFinalPrice();
            h.tvCurPrice.setText(bean.getPriceName() + mContext.getString(R.string.pri_tab)
                    +bean.getAfterCouponPrice());
            if(!bean.getImgUrl().startsWith("http")){
                bean.setImgUrl(HttpUrl.Image_Url + bean.getImgUrl());
            }
            Glide.with(mContext).load(bean.getImgUrl()).error(R.mipmap.ic_launcher).centerCrop().into(h.imgIcon);

        } else {    //列表数量
            bean = mList.get(getListPosition(position));
            LViewHolder h = (LViewHolder) holder;
            h.tvName.setText(bean.getName());
            h.tvPrice.setText(bean.getPrice());
            bean.isFinalPrice();
            h.tvCurPrice.setText(bean.getPriceName() + mContext.getString(R.string.pri_tab)
                    +bean.getAfterCouponPrice());
            if(!bean.getImgUrl().startsWith("http")){
                bean.setImgUrl(HttpUrl.Image_Url + bean.getImgUrl());
            }
            Glide.with(mContext).load(bean.getImgUrl()).error(R.mipmap.ic_launcher).centerCrop().into(h.imgIcon);

        }

    }

接下来再加个VIewPager的adapter

import android.support.v4.view.PagerAdapter; 
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * Created by Administrator on 2020/4/13.
 */

public class ViewPAdapter extends PagerAdapter {


    List<View> mList;
    public ViewPAdapter(List<View> list){
        mList = list;
    }

    @Override
    public int getCount() {
        return mList == null ? 0 : mList.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(mList.get(position));
        return mList.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(mList.get(position));
    }



}

到这里就大致完成了外面的ViewPager,接下来编写第三个Tab中的ViewPager,里面使用了GridView作为网格布局,先来XML文件代码

<?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="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/img_item_part_ad"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:src="@mipmap/ic_launcher"
        android:layout_marginRight="15dp"
        android:layout_marginLeft="15dp"
        android:scaleType="fitXY"/>
    
    <com.example.administrator.testshop.view.ChildViewPager
        android:id="@+id/viewpager_ad"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:visibility="gone"/>
    <android.support.design.widget.TabLayout
        android:id="@+id/tbl_share_ad"
        android:layout_width="40dp"
        android:layout_height="3dp"
        android:layout_gravity="center"
        app:tabIndicatorColor="#CD661D"
        app:tabSelectedTextColor="#1A1A1A"
        app:tabTextColor="#B3B3B3"
        />

    <TextView
        android:id="@+id/tv_item_part_con1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#333333"
        android:text="人气推荐"
        android:textSize="15sp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="30dp"
        />
    <TextView
        android:id="@+id/tv_item_part_con2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/gray_999"
        android:text="自购省钱"
        android:textSize="14sp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="7dp"
        />

</LinearLayout>

接下来是在RecyclerView.Adapter中加入ViewPager+GridView的编写,其实在上面代码中也有复制出来,在这里再写一遍

首先定义ViewHolder

static class HeadViewHolder extends RecyclerView.ViewHolder{
        ImageView imgAdIcon;
        ChildViewPager viewPager;
        TabLayout tabLayout;
        TextView tvTitle, tvSubTitle;
        public HeadViewHolder(View itemView) {
            super(itemView);

            imgAdIcon = itemView.findViewById(R.id.img_item_part_ad);
            viewPager = (ChildViewPager) itemView.findViewById(R.id.viewpager_ad);
            tabLayout = (TabLayout) itemView.findViewById(R.id.tbl_share_ad);
            tvTitle = itemView.findViewById(R.id.tv_item_part_con1);
            tvSubTitle = itemView.findViewById(R.id.tv_item_part_con2);


        }
    }

然后在onBindViewHolder方法中对应的VIewType把ViewPager和GridView绑定adapter,因为GridView中的数据是一个List返回的,所以在这里我把List切割成多个了。

if(checkViewType(position) == Type_View_Head){  //头部
            HeadViewHolder h = (HeadViewHolder) holder;
            if(bannerBean != null){
                String imgUrl = bannerBean.getCover();
                if(null != imgUrl && !imgUrl.startsWith("http")){
                    imgUrl = HttpUrl.Image_Url + imgUrl;
                }
                Glide.with(mContext).load(imgUrl).error(R.mipmap.ic_launcher).into(h.imgAdIcon);
            }

            if(cateList != null && !cateList.isEmpty()){
                int a = cateList.size();
                int b = 10;
                int pager = a%b == 0 ? (a/b) : (a/b)+1;
                List<List<CategoriesBean>> catList = groupList(cateList);
                List<View> viewList = new ArrayList<>();
                for(int i=0; i<pager; i++){
                    LinearLayout layout = (LinearLayout) LayoutInflater.from(mContext)
                            .inflate(R.layout.item_part_ad_childvp, null);
                    GridViewInScrollView gridView = layout.findViewById(R.id.gridview_item);
                    MenuShareAdapter adapter = new MenuShareAdapter(mContext);
                    gridView.setAdapter(adapter);

                    viewList.add(layout);
                    adapter.update(catList.get(i));
                }
                if(isShare){
                    h.viewPager.setVisibility(View.VISIBLE);
                }else{
                    h.viewPager.setVisibility(View.GONE);
                }
                ViewPAdapter adapter = new ViewPAdapter(viewList);
                h.viewPager.setAdapter(adapter);
                h.tabLayout.setupWithViewPager(h.viewPager);
                h.tabLayout.setTabMode(TabLayout.MODE_FIXED);

                adapter.notifyDataSetChanged();
            }

        }
/*
     * List分割
     */
    public static List<List<CategoriesBean>> groupList(List<CategoriesBean> list) {
        List<List<CategoriesBean>> listGroup = new ArrayList<List<CategoriesBean>>();
        int listSize = list.size();
        //子集合的长度
        int toIndex = 10;
        for (int i = 0; i < list.size(); i += toIndex) {
            if (i + toIndex > listSize) {
                toIndex = listSize - i;
            }
            List<CategoriesBean> newList = list.subList(i, i + toIndex);
            listGroup.add(newList);
        }
        return listGroup;
    }

在最后加入网络请求

使用了Rxjava + retrofit + OkHttp ,Gson解析数据

compile 'io.reactivex:rxandroid:1.2.0'
    compile 'com.artemzin.rxjava:proguard-rules:1.1.3.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'

写成一个类直接调用

import com.example.administrator.testshop.HttpUrl;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.GzipSink;
import okio.Okio;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class InitRetrofit {


    private static OkHttpClient client = new OkHttpClient
            .Builder()
            .connectTimeout(5, TimeUnit.MINUTES)
            .readTimeout(5, TimeUnit.MINUTES)
            .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.NONE))
            //.addInterceptor(new GzipRequsetInterceptor())
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request()
                            .newBuilder()
                            .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                            .addHeader("Accept-Encoding", "gzip, deflate")
                            .addHeader("Connection", "keep-alive")
                            .addHeader("Accept", "*/*")
                            .addHeader("Cookie", "add cookies here")
                            .build();
                    return chain.proceed(request);
                }
            })
            .build();

    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(HttpUrl.Base_Url)
            .client(client)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();



    private InitRetrofit() {

    }

    public static <T> T createApi(Class<T> mClass) {

        return retrofit.create(mClass);
    }

}

UKL接口的存放地,其中ProListStrBean是个人自定义的一个数据集合类

public interface NetService {

    /**
     * 获取淘宝列表
     * @return
     */
    @GET("/indexRight/taobao")
    Observable<ProListStrBean> loadTbListData();
 }

调用,然后自己把数据回调就好

/**
     * 
     */
    public void loadTbListData(){
        InitRetrofit.createApi(NetService.class)
                .loadTbListData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ProListStrBean>() {
                    @Override
                    public void onCompleted() {

                    }
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }
                    @Override
                    public void onNext(ProListStrBean strBean) {
                        tbDataInter.onTbListSuccess(strBean.getResult());
                    }
                });
    }

最后加上源码地址:https://github.com/YanVsyi/Test.git

你可能感兴趣的:(android)