关闭

Android自定义控件:将ViewPager封装自己的TabPager控件

标签: androidviewpager控件阅读数据
3098人阅读 评论(1) 收藏 举报
分类:

用途

最近项目页面中经常出现诸如下图的控件,如果为每个页面分别写一个将会造成非常多的重复代码,不利于项目的阅读和维护,也会使项目变得非常凌乱。所以,对于这种情况我们可以进行一定的抽取,传入相关数据后自动显示到控件上。

这里写图片描述

思路

由上图可知,我们需要上面的Tab作为指示,下面是类似轮播图ViewPager。我们需要实现点击Tab切换到相应轮播图页面,同时滚动Page上面的Tab做相应的变化。

此时我们要动态填充上面Tab的内容以及轮播图的内容。所以我把这两块建立了一个组合控件。Tab用一条LinearLayout,下面是ViewPager。同时提供数据接口,分别用于传入Tab和ViewPager内容。

此处Tab分为背景和内容,背景是控件统一的,可以封装在控件内部设置,所以我们要传入文字的相关部分,这里我使用传入TextView。

ViewPager的内容,我们封装在一个Holder中,Holder可以提供显示内容及其数据。

有了这两个内容,我们就可以以适当的方e式将内容分别填充到上面的LinearLayout中和ViewPager中。

具体做法及关键代码

主要涉及的问题

  1. Tab动态加入LinearLayout时布局问题
  2. Tab的滑动与ViewPager的关联
主要代码

git

https://git.oschina.net/vonchenchen/MySlidingTabPager.git

调用方法及效果

假设我们需要四个Tab
这里写图片描述

    private void initView(){
        //构造Tab
        TextView tab1 = new TextView(MainActivity.this);
        tab1.setText("TAB1");
        TextView tab2 = new TextView(MainActivity.this);
        tab2.setText("TAB2");
        TextView tab3 = new TextView(MainActivity.this);
        tab3.setText("TAB3");
        TextView tab4 = new TextView(MainActivity.this);
        tab4.setText("TAB4");
        //加入Tab
        mMySlidingTabPager.addTab(tab1);
        mMySlidingTabPager.addTab(tab2);
        mMySlidingTabPager.addTab(tab3);
        mMySlidingTabPager.addTab(tab4);
        //创建页面holder
        ViewHolder1 holder1 = new ViewHolder1();
        ViewHolder2 holder2 = new ViewHolder2();
        ViewHolder3 holder3 = new ViewHolder3();
        ViewHolder4 holder4 = new ViewHolder4();
        //加入页面holder
        mMySlidingTabPager.addHolder(holder1);
        mMySlidingTabPager.addHolder(holder2);
        mMySlidingTabPager.addHolder(holder3);
        mMySlidingTabPager.addHolder(holder4);

        //页面填充  这里就可以显示啦!!!
        mMySlidingTabPager.start();
    }
ViewHolder
/**
 * 自绘控件封装类
 * Created by vonchenchen on 2015/11/3 0003.
 */
public abstract class BaseWidgetHolder<T> {

    protected View mRootView;

    public abstract View initView();
    public abstract void refreshView(T data);

    public BaseWidgetHolder(){
        mRootView = initView();
        mRootView.setTag(this);
    }

    public View getRootView(){
        return mRootView;
    }
}
控件实现
/**
 * Created by vonchenchen on 2015/11/19 0019.
 */
public class MySlidingTabPager extends RelativeLayout{

    private Context mCtx;
    /** Tab布局 */
    private LinearLayout mTabsLayout;
    /** ViewPager */
    private ViewPager mContentViewPager;

    private List<TextView> mTabList;
    private List<BaseWidgetHolder> mHolderList;

    private MyPagerAdapter mMyPagerAdapter;

    private int mRecordPosition = -1;

    public MySlidingTabPager(Context context) {
        super(context);
        this.mCtx = context;
    }

    public MySlidingTabPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mCtx = context;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        View.inflate(mCtx, R.layout.layout_slidingtabpager, this);
        mTabsLayout = (LinearLayout) findViewById(R.id.ll_tabs);
        mContentViewPager = (ViewPager) findViewById(R.id.vp_content);

        mTabList = new ArrayList<TextView>();
        mHolderList = new ArrayList<BaseWidgetHolder>();

        //监听ViewPager滚动
        mContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                //ViewPager滑动 对应Tab选择
                updateTab(position, false);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    /**
     * 添加Tab
     * @param tab
     */
    public void addTab(TextView tab){
        mTabList.add(tab);
    }

    /**
     * 添加holder
     * @param holder
     */
    public void addHolder(BaseWidgetHolder holder){
        mHolderList.add(holder);
    }

    /**
     * 开启显示
     */
    public void start(){
        initTabView();
        initViewPager();
    }

    private void initTabView(){
        //设置Layout参数,用于添加新的Tab
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, dip2px(MyApplication.getContext(), 40));
        params.weight = 1;

        for(int i=0; i<mTabList.size(); i++){

            TextView view = mTabList.get(i);
            view.setGravity(Gravity.CENTER);

            final int position = i;
            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    mContentViewPager.setCurrentItem(position);
                    updateTab(position, true);
                }
            });
            //将TextView加入到LinearLayout上
            mTabsLayout.addView(view, params);
            setViewUnSelected(view, i);
        }

        //初始化默认Tab颜色及其位置
        mRecordPosition = 0;
        setViewSelectd(mTabList.get(0), 0);
    }

    private void updateTab(int position, boolean isTouchTab){
        if(position != mRecordPosition){
            setViewSelectd(mTabList.get(position), position);
        }

        if(mRecordPosition >= 0 && !isTouchTab){
            setViewUnSelected(mTabList.get(mRecordPosition), mRecordPosition);
        }

        mRecordPosition = position;
    }

    /**
     * 当Pager被选择时设置对应Tab的颜色
     * @param view
     * @param position
     */
    private void setViewSelectd(View view, int position){
        if(position == 0){
            view.setBackgroundResource(R.drawable.shape_detail_rb_left_blue);
        }else if(position == mTabList.size()-1){
            view.setBackgroundResource(R.drawable.shape_detail_rb_right_blue);
        }else{
            view.setBackgroundResource(R.drawable.shape_detail_rb_mid_blue);
        }
    }

    /**
     * 取消Tab的选中颜色
     * @param view
     * @param position
     */
    private void setViewUnSelected(View view, int position){
        if(position == 0) {
            view.setBackgroundResource(R.drawable.shape_detail_rb_left_white);
        }else if(position == mTabList.size()-1){
            view.setBackgroundResource(R.drawable.shape_detail_rb_right_white);
        }else{
            view.setBackgroundResource(R.drawable.shape_detail_rb_mid_white);
        }
    }

    private void initViewPager(){
        mMyPagerAdapter = new MyPagerAdapter();
        mContentViewPager.setAdapter(mMyPagerAdapter);
    }

    public class MyPagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return mTabList.size();
        }
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View)object);
        }

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

    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale);
    }
}
2
0
查看评论

TabPagerIndicator和viewpager实现tab的切换(慕课网笔记)

使用第三方的TabPageIndicator,viewpager,fragment,fragmentPagerAdapter实现顶部tab 导航栏的切换,效果图 1 顶部是一个布局文件,top.xml,中间的tab切换是一个TabPageIndicator,下面的内容区域是viewpager ...
  • hnyzwtf
  • hnyzwtf
  • 2015-12-17 10:02
  • 4456

Android快速SDK(18)Tab页面TabPager【傻瓜模式】

代码:http://download.csdn.net/detail/huangbin95487710/9260337 依赖包模式 基于ViewPager装载在SlidingMenu内适用 新特性配置支持 配置Tab样式 空白下划线三角型下划线+三角型三角型+下划线 右竖线配置一行...
  • huangbin95487710
  • huangbin95487710
  • 2015-11-11 14:04
  • 453

Android之Tab分页标签的实现方法一-----TabActivity和TabHost的结合(二)

Android之Tab分页标签的实现方法一-----TabActivity和TabHost的结合(二)
  • kkfdsa132
  • kkfdsa132
  • 2011-04-14 19:10
  • 5513

Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager

  • 2014-04-29 22:40
  • 1.47MB
  • 下载

Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager

Android现在实现Tab类型的界面方式越来越多,今天就把常见的实现方式给大家来个总结。目前写了: 1、传统的ViewPager实现 2、FragmentManager+Fragment实现 3、ViewPager+FragmentPagerAdapter实现 4、TabPageIndicator...
  • lmj623565791
  • lmj623565791
  • 2014-04-29 22:25
  • 137748

Android使用viewpager,tabpagerindicator实现tab切换

  • 2015-12-16 19:21
  • 1.27MB
  • 下载

仿今日头条最强顶部导航指示器,支持6种模式

项目中经常会用到类似今日头条中顶部的导航指示器,一共支持6种模式,基本涵盖了所有常用的模式。使用起来非常简单,非常方便。
  • shan_yao
  • shan_yao
  • 2016-06-24 16:34
  • 10783

ViewPager封装工具类: 轻松实现APP导航或APP中的广告栏

ViewPager封装工具类: 轻松实现APP导航或APP中的广告栏...
  • zuiwuyuan
  • zuiwuyuan
  • 2015-10-25 22:10
  • 1667

少年郎,你需要封装好的ViewPager工具类

作者:夏至,欢迎转载,也请保留这段申明,谢谢 http://blog.csdn.net/u011418943/article/details/78493002 你是否有遇到这样的问题,每次开发一个新的项目,在 viewpager 这一块上,总是在做重复的东西,比如app引导页,轮播图,viewp...
  • u011418943
  • u011418943
  • 2017-11-09 19:21
  • 2777

ViewPager 系列之 打造一个通用的 ViewPager

背景 CommonViewPager.png ViewPager是Android开发者比较常用的一个控件了,由于它允许数据页从左到右或者从右到左翻页,因此这种交互也备受设计师的青睐。在APP中的很多场景都用得到,比如第一次安装APP时的用户引导页、图片浏览时左右翻页、广告Banner页等等都会用...
  • u012295927
  • u012295927
  • 2017-05-31 11:10
  • 544
    个人资料
    • 访问:194645次
    • 积分:2977
    • 等级:
    • 排名:第13998名
    • 原创:83篇
    • 转载:2篇
    • 译文:1篇
    • 评论:95条
    最新评论