Tablayout、ViewPage与Fragment使用
看下效果图:
实现步骤:
1、xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<com.yanzhenjie.sofia.StatusView
android:id="@+id/status_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_below="@+id/status_view"
android:gravity="center"
android:text="发现"
android:textColor="@color/color_333333"
android:textSize="18sp" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@+id/tv_title"
android:background="#eaeaea" />
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_below="@+id/divider"
android:layout_centerVertical="true"
app:tabIndicatorColor="@color/color_333333"
app:tabSelectedTextColor="@color/color_333333"
app:tabTextAppearance="@style/MyTabBar"
app:tabTextColor="@color/color_999999" />
<android.support.v4.view.ViewPager
android:id="@+id/view_pager_hair"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tab"
android:visibility="visible" />
</RelativeLayout>
布局文件没什么好说的,就是个头部文件和viewpage。
2、初始化控件相关
package com.jm.ec.main.find;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.View;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jm.core.delegates.bottom.BottomItemDelegate;
import com.jm.core.net.RestClient;
import com.jm.core.util.log.JLogger;
import com.jm.ec.R;
import com.jm.ec.constant.JConstants;
import com.jm.ui.launcher.ILauncherListener;
import java.util.ArrayList;
import java.util.List;
public class FindDelegate extends BottomItemDelegate {
private TabLayout mTabLayout = null;
private ViewPager mViewPager = null;
private ILauncherListener launcherListener = null;
private FindPagerAdapter pagerAdapter;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof ILauncherListener) {
launcherListener = (ILauncherListener) activity;
}
}
@Override
public Object setLayout() {
return R.layout.find_delegate;
}
@Override
public void onSupportVisible() {
super.onSupportVisible();
getAppBar().statusBarDarkFont();
}
@Override
public void onBindView(@Nullable Bundle savedInstanceState, @NonNull View rootView) {
mViewPager = $(R.id.view_pager_hair);
mTabLayout = $(R.id.tab);
}
@Override
public void onLazyInitView(@Nullable Bundle savedInstanceState) {
super.onLazyInitView(savedInstanceState);
requestArticleCategory();
}
private void requestArticleCategory() {
RestClient.builder()
.url("数据接口")
.success(this::updateIndexView)
.build()
.post();
}
private void updateIndexView(String response) {
JLogger.e(response);
try {
final JSONObject jsonObject = JSON.parseObject(response);
if (JConstants.OK.equals(jsonObject.getString("code"))) {
List<FindEntity> entities = new ArrayList<>();
entities.add(new FindEntity("", "推荐"));//将标题“推荐”加入进去
entities.addAll(FindDataConverter.convert(response));//解析的全部数据存放进entities中
initTabLayout(entities);//初始化tablayout
}
} catch (Exception e) {
}
}
private void initTabLayout(List<FindEntity> entities) {
mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);//TabLayout位置居中
pagerAdapter = new FindPagerAdapter(getChildFragmentManager(), entities);//adpter适配器
mViewPager.setAdapter(pagerAdapter);//为viewpage设置adapter
mTabLayout.setupWithViewPager(mViewPager);//tablayout与viewpager绑定
}
}
这里项目中的tablayout的标题是动态获取的,这样做的好处是,不需要固定标题的,后期产品那边可以任意更改标题。只需要数据接口提供方过来,解析这一数据,再添加进去即可。看下数据接口解析方法
package com.jm.ec.main.find;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jm.core.util.log.JLogger;
import com.jm.ec.main.index.article.ArticleEntity;
import java.util.ArrayList;
import java.util.List;
public class FindDataConverter {
public static List<FindEntity> convert(String json) {
JLogger.json(json);
final List<FindEntity> dataList = new ArrayList<>();
final JSONArray jsonArray = JSON.parseObject(json).getJSONArray("data");
final int size = jsonArray.size();
for (int i = 0; i < size; i++) {
final JSONObject arrayJSONObject = jsonArray.getJSONObject(i);
final String id = arrayJSONObject.getString("id");
final String name = arrayJSONObject.getString("name");
FindEntity entity = new FindEntity(id, name);
dataList.add(entity);
}
return dataList;
}
}
3、Entity类
package com.jm.ec.main.find;
import java.io.Serializable;
public class FindEntity implements Serializable {
private String id;
private String name;
public FindEntity(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public FindEntity setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public FindEntity setName(String name) {
this.name = name;
return this;
}
}
因为参数只需要id和name,这里解析和entity也就写此两个即可。
4、adapter方法
主要看这句pagerAdapter = new FindPagerAdapter(getChildFragmentManager(), entities);getChildFragmentManager()所得到的是在fragment 里面子容器的管理器。
看下adapter方法
package com.jm.ec.main.find;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.jm.ec.gallery.HairDelegate;
import java.util.List;
/**
* FragmentStatePagerAdapter继承自 PagerAdapter。但是,和 FragmentPagerAdapter 不一样的是,
* 正如其类名中的 'State' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,
* 当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。
* 这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存
*/
public class FindPagerAdapter extends FragmentStatePagerAdapter {
private final List<FindEntity> entities;
public FindPagerAdapter(FragmentManager fm, List<FindEntity> entities) {
super(fm);
this.entities =entities;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
// Do NOTHING
}
@Override
public Fragment getItem(int position) {
FindEntity entity = entities.get(position);
return RecommendDelegate.create(entity.getId()); //从Fragment队列中得到文章类Fragment并加入到ViewPager中
}
@Override
public int getCount() {
return entities.size();
}
@Override
public CharSequence getPageTitle(int position) {
return entities.get(position).getName();//得到对应tablayout的标题
}
}
关于FragmentStatePagerAdapter的相关知识,可以参考这个链接,讲解的很详细http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDataSetChanged-does-not-work.html