Android TabLayout与ViewPager实现动态Tab
来源:互联网 发布:最新电视直播软件 编辑:程序博客网 时间:2024/05/17 01:28
Android TabLayout与ViewPager实现动态Tab
在项目中很少会遇到动态Tab这种需求,但是遇到了也要灵活处理,下面介绍一下实现方法。这里只是实现一个简单的纯文字的Tabs,重点在实现动态效果。
首先需要添加android.support.design依赖才能使用TabLayout这个控件。Android studio 添加如下代码到Gradle文件。
compile 'com.android.support:design:23.1.1'
布局文件
fragment_tablayout.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:orientation="vertical"> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/blue1" app:tabSelectedTextColor="@color/white" app:tabTextColor="@color/white" style="@style/MyCustomTabLayout" /> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="1" android:background="@android:color/white" /></LinearLayout>
tab style文件
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout"> <item name="tabIndicatorColor">@color/deepskyblue</item> <item name="tabIndicatorHeight">2.5dp</item> <item name="tabPaddingStart">12dp</item> <item name="tabPaddingEnd">12dp</item> <item name="tabBackground">?attr/selectableItemBackground</item> <item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item> <item name="tabSelectedTextColor">?android:textColorPrimary</item> </style>
Tablayout控件 xml属性说明:
- tabSelectedTextColor选中该Tab时文字的颜色
- app:tabTextColor正常状态下也就是没被选中的Tab的文字颜色
- style=”@style/MyCustomTabLayout” 通过style属性可以定义更多属性
- tabIndicatorColor Tab指示器的颜色
- tabIndicatorHeight Tab指示器的高度
Activity代码实现
1.实现一个自己的FragmentPagerAdapter,跟一般的Fragment+viewPager实现是一样的。
public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter { private Context context; private List<Fragment> fragments; public SimpleFragmentPagerAdapter(FragmentManager fm,List<Fragment> fragments) { super(fm); this.fragments = fragments; } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } //这个方法返回Tab显示的文字。这里通过在实例化TabFragment的时候,传入的title参数返回标题。 @Override public CharSequence getPageTitle(int position) { TabFragment fragment = (TabFragment) fragments.get(position); return fragment.getTitle(); }}
2.初始化Viewpager适配器
pagerAdapter = new SimpleFragmentPagerAdapter(getChildFragmentManager(),fragments);viewpager.setAdapter(pagerAdapter);
3.从服务器获取Tab分类
loadCategoryPresenter.loadCategory();
4.将返回的类别数据绑定到Tab上
这里有个TabMode说明一下:他是Tab的布局方式,
(1) TabLayout.MODE_SCROLLABLE:适用与多个Tab,可以滚动Tab栏
(2)TabLayout.MODE_FIXED:适用与Tab个数较少的情况,每个Tab都平分TabLayout的宽度,不可滚动。
动态Tab的实现是在Activity生命周期中的onResume()中加载服务器的栏目类别。加载完成后将栏目类别缓存到本地,下次再加载的时候比较栏目是否改变过。从而避免重复刷新界面。也就是说在用户进入这个Activity的时候就检测栏目是否改变,改变就重新加载Tabs数据
业务逻辑是通过MVP模式实现的,具体的Model层自行实现吧,也就是通过Http访问网络获取数据。
————-下面附上Activity、Presenter层、View层代码—————–
CategoryPresenterImp.java
public class CategoryPresenterImp extends BaseParenterImp implements CategoryPresenter { public CategoryPresenterImp(Context context) { super(context); } private LoadCategoryView categoryView; private CategoryMod loadCategoryMod; private AsyncTaskClient taskClient; private ACache aCache; public CategoryPresenterImp(Context context, LoadCategoryView categoryView){ super(context); this.categoryView = categoryView; this.loadCategoryMod = new CategoryModImp(context); this.taskClient = new AsyncTaskClient(); aCache = ACache.get(context); } @Override public void onDestroy() { if(taskClient!=null)taskClient.cancelRequests(context,true); loadCategoryMod = null; super.onDestroy(); } /** * 解析服务器返回的xml,在子线程执行任务 */ private TaskRequest.Background<List<Category>> parseBackground = new TaskRequest.Background<List<Category>>() { @Override public List<Category> doInBackground(Object param) { ArrayList<Category> categories = loadCategoryMod.parseCategory((String) param); return categories; } }; /** * 解析完成后回调 */ private TaskResponseHandler parseResponseHandler = new TaskResponseHandler() { @Override public void onSuccess(int statusCode, Object responseBody) { categoryView.categorySuccessCall((List<Category>) responseBody); } @Override public void onFailure(int statusCode, Throwable error) { categoryView.categoryFailedCall(error.getMessage()); } }; /** * 请求网络返回回调,返回成功后开始解析 */ private RequestCallBack<String> loadCallBack = new RequestCallBack<String>() { @Override public void onSuccess(ResponseInfo<String> responseInfo) { String res = responseInfo.result.toString(); TaskRequest taskRequest = new TaskRequest(res,parseBackground); taskClient.sendRequest(taskRequest, parseResponseHandler,context ); } @Override public void onFailure(HttpException error, String msg) { categoryView.categoryFailedCall("网络连接异常"); } }; @Override public void loadCategory() { loadCategoryMod.loadCategory(loadCallBack); } //缓存栏目类别 @Override public void saveCategory(ArrayList<Category> categoryArrayList) { ACache.get(context).put(AppConfig.CATEGORY_LIST,categoryArrayList); } //获取本地缓存栏目类别 @Override public ArrayList<Category> readCategory() { return (ArrayList<Category>) ACache.get(context).getAsObject(AppConfig.CATEGORY_LIST); } //比对当前类别很缓存类别是否发生改变 @Override public boolean categoryChanged(ArrayList<Category> nowCategoryList) { ArrayList<Category> lastcategories = readCategory(); if(lastcategories == null || lastcategories.size() == 0 || nowCategoryList == null || nowCategoryList.size() == 0){ return true; }else { if(nowCategoryList.size()!=lastcategories.size())return true; for(int i=0;i<lastcategories.size();i++){ String nowId = nowCategoryList.get(i).getId(); String lastId = lastcategories.get(i).getId(); if(!nowId.equals(lastId)){ return true; } } } return false; } //清空栏目缓存 @Override public void clearCategory() { ACache.get(context).put(AppConfig.CATEGORY_LIST,new ArrayList<Category>()); }
TablayoutFragment.java
public class TablayoutFragment extends BaseFragment implements LoadCategoryView{ @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_tablayout, null); } private TabLayout tabs; private ViewPager viewpager; private CategoryPresenter loadCategoryPresenter; private void assignViews() { tabs = (TabLayout) findView(R.id.tabs); viewpager = (ViewPager) findView(R.id.viewpager); } private SimpleFragmentPagerAdapter pagerAdapter; private List<Fragment> fragments = new ArrayList<>(); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); loadCategoryPresenter = new CategoryPresenterImp(mContext,this); loadCategoryPresenter.clearCategory();//每次运行的时候都清一下缓存,以免强制退出后,不会刷新类别 assignViews(); pagerAdapter = new SimpleFragmentPagerAdapter(getChildFragmentManager(),fragments); viewpager.setAdapter(pagerAdapter); tabs.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewpager) { @Override public void onTabSelected(TabLayout.Tab tab) { super.onTabSelected(tab); int position = tab.getPosition(); } }); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onSaveInstanceState(Bundle outState) { loadCategoryPresenter.clearCategory(); super.onSaveInstanceState(outState); } @Override public void onResume() { super.onResume(); loadCategoryPresenter.loadCategory(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void categorySuccessCall(List<Category> categoryList) { boolean categoryChanged = loadCategoryPresenter.categoryChanged((ArrayList<Category>) categoryList); if(categoryChanged){ fragments.clear(); for (Category category : categoryList){ String id = category.getId(); String name = category.getName(); TabFragment tabFragment = new TabFragment(id,name); fragments.add(tabFragment); } pagerAdapter.notifyDataSetChanged();viewpager.setOffscreenPageLimit(fragments.size()); tabs.setupWithViewPager(viewpager); if(fragments.size()>4){tabs.setTabMode(TabLayout.MODE_SCROLLABLE); }else { tabs.setTabMode(TabLayout.MODE_FIXED); } } loadCategoryPresenter.saveCategory((ArrayList<Category>) categoryList); } @Override public void categoryFailedCall(String info) { }
LoadCategoryView.java
/** * 加载栏目界面回调 */public interface LoadCategoryView { void categorySuccessCall(List<Category> categoryList); void categoryFailedCall(String info);}
- Android TabLayout与ViewPager实现动态Tab
- TabLayout与ViewPager组合实现tab导航
- Android应用ViewPager和TabLayout动态加载Fragment,并实现view和tab动态刷新。
- 解决Tablayout与ViewPager关联后,Tablayout动态生成的tab不显示问题
- android TabLayout+ViewPager有较多Tab,Tab随viewPager滚动
- TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签
- Android TabLayout、ViewPager实现顶部和底部Tab导航 点击滑动切换Tab页面
- Android开发:顶部&底部Tab导航栏实现(TabLayout+ViewPager+Fragment)
- Android之TabLayout+ViewPager+Fragment实现标题栏与页面联动
- TabLayout + ViewPager + Fragment 实现动态框架
- Android5.0新组件TabLayout+ViewPager实现Tab页面
- TabLayout+ViewPager 简单实现app底部Tab布局
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- Tablayout+viewpager+fragment实现tab导航以及滑动切换
- 安卓 TabLayout+ViewPager实现滑动Tab效果
- 使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
- 利用TabLayout+ViewPager+Fragment实现可滚动的Tab页面
- TokuDB的特点验证
- 【算法】链表
- ios开发autolayout之VFL语言使用总结
- .htaccess详解及.htaccess参数说明
- database link问题解决
- Android TabLayout与ViewPager实现动态Tab
- 文章标题
- AD域和第三方进行用户对接的注意事项
- 老黄聊架构:微服务架构落地之前,需要想清楚的几个关键问题
- hdu1754 I Hate It (分数修改)-线段树
- 微博MySQL优化之路--dockone微信群分享
- CentOS中mysql一些常用操作
- Android ContentProvider详解
- java之重载和重写<一>