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