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);}
1 1
原创粉丝点击