ViewPager 滑动页卡切换

来源:互联网 发布:文件定时拷贝软件 编辑:程序博客网 时间:2024/04/30 10:09

http://blog.csdn.net/jxxfzgy/article/details/44162211

大神之作,可以直接使用


效果:

今天这篇 blog的内容同样可以拿来做 app 的整体架构,但与前面那篇 blog 不同,不同之处是前面那篇文章所讲的内容可用作底部导航,而这篇 blog 的内容,是用作顶部导航,老版本的微信就是此效果,ok,来看看效果图 




实现原理

根据效果图,不难分析,可以通过自定义 ViewGroup 来实现,但这样代码量偏多,看了我的前面 blog 的朋友应该清楚,这里最好的实现方式是通过重写 LinearLayout,相比通过 ViewGroup 来实现,省略了测量onMeasure()和布局onLayout()方法的实现,因为这些LinearLayout已经帮我们实现好了,而我们真正要做的就是为 LinearLayout 填充内容,填充内容可大致可分为以下四个步骤:

1、填充每个 item 的内容

2、绘制每个 item 之间的分割线

3、绘制底部线条

4、绘制指示器的内容

代码实现

1、先把需要用的属性定义出来 
需要的属性 
1、页卡指示器的颜色 
2、分割线的颜色 
3、底部线条的颜色 
4、页卡指示器的高度 
5、分割线距离上下边距的距离 
6、分割线的宽度

<?xml version="1.0" encoding="utf-8"?>  <resources>      <attr name="indicatorColor" format="color"/>      <attr name="dividerColor" format="color"/>      <attr name="bottomLineColor" format="color"/>      <attr name="dividerMargin" format="dimension"/>      <attr name="indicatorHeight" format="dimension"/>      <attr name="bottomLineHeight" format="dimension"/>      <attr name="dividerWidth" format="dimension"/>      <declare-styleable name="SlidingTabLayout">          <attr name="indicatorColor"/>          <attr name="dividerColor"/>          <attr name="bottomLineColor"/>          <attr name="dividerMargin"/>          <attr name="indicatorHeight"/>          <attr name="bottomLineHeight"/>          <attr name="dividerWidth"/>      </declare-styleable>  </resources>  


2、代码中获取属性,并附上相应的默认值


/*默认的页卡颜色*/      private final int DEFAULT_INDICATOR_COLOR = 0xffff00ff;      /*默认分割线的颜色*/      private final int DEFAULT_DIVIDER_COLOR = 0xff000000;      /*默认title字体的大小*/      private final int DEFAULT_TEXT_SIZE = 16;      /*默认padding*/      private final int DEFAULT_TEXT_PADDING = 16;      /*divider默认的宽度*/      private final int DEFAULT_DIVIDER_WIDTH = 1;      /*indicator 的高度*/      private final int DEFAULT_INDICATOR_HEIGHT = 5;      /*底部线条的高度默认值*/      private final int DEFAULT_BOTTOM_LINE_HEIGHT = 2;      /*分割线距离上下边缘的距离默认为8*/      private final int DEFAULT_DIVIDER_MARGIN = 8;      /*底部线条的颜色默认值*/      private final int DEFAULT_BOTTOM_LINE_COLOR = 0xff000000;      /*获取TypedArray*/          TypedArray typedArray = getResources().obtainAttributes(attrs, R.styleable.SlidingTabLayout);          /*获取自定义属性的个数*/          int N = typedArray.getIndexCount();          Log.v("zgy","=========getIndexCount========="+N) ;          for (int i = 0; i < N; i++) {              int attr = typedArray.getIndex(i);              switch (attr) {                  case R.styleable.SlidingTabLayout_indicatorColor:                      /*获取页卡颜色值*/                      mIndicatorColor = typedArray.getColor(attr, DEFAULT_INDICATOR_COLOR);                      break;                  case R.styleable.SlidingTabLayout_dividerColor:                      /*获取分割线颜色的值*/                      mDividerColor = typedArray.getColor(attr, DEFAULT_DIVIDER_COLOR);                      break;                  case R.styleable.SlidingTabLayout_bottomLineColor:                      /*获取底部线条颜色的值*/                      mBottomLineColor = typedArray.getColor(attr, DEFAULT_BOTTOM_LINE_COLOR);                      break;                  case R.styleable.SlidingTabLayout_dividerMargin:                      /*获取分割线的距离上线边距的距离*/                      mDividerMargin = (int) typedArray.getDimension(attr, DEFAULT_DIVIDER_MARGIN * getResources().getDisplayMetrics().density);                      Log.v("zgy","=========mDividerMargin========="+mDividerMargin) ;                      break;                  case R.styleable.SlidingTabLayout_indicatorHeight:                      /*获取页卡的高度*/                      mIndicatorHeight = (int) typedArray.getDimension(attr, DEFAULT_INDICATOR_HEIGHT * getResources().getDisplayMetrics().density);                      break;                  case R.styleable.SlidingTabLayout_bottomLineHeight:                      /*获取底部线条的高度*/                      mBottomLineHeight = (int) typedArray.getDimension(attr, DEFAULT_BOTTOM_LINE_HEIGHT * getResources().getDisplayMetrics().density);                      break;                  case R.styleable.SlidingTabLayout_dividerWidth:                      /*获取分割线的宽度*/                      mDividerWidth = (int) typedArray.getDimension(attr, DEFAULT_DIVIDER_WIDTH * getResources().getDisplayMetrics().density);                      break;              }          }          /*释放TypedArray*/          typedArray.recycle();  


3、为 LinearLayout 填充内容


/**      * 设置viewPager,初始化SlidingTab,      * 在这个方法中为SlidingLayout设置      * 内容,      *      * @param viewPager      */      public void setViewPager(ViewPager viewPager) {          /*先移除所以已经填充的内容*/          removeAllViews();          /* viewPager 不能为空*/          if (viewPager == null) {              throw new RuntimeException("ViewPager不能为空");          }          mViewPager = viewPager;          mViewPager.setOnPageChangeListener(new InternalViewPagerChange());          //填充内容          populateTabLayout();      }     /**      * 填充layout,设置其内容      */      private void populateTabLayout() {          final PagerAdapter adapter = mViewPager.getAdapter();          final OnClickListener tabOnClickListener = new TabOnClickListener();          mItemName = (TabItemName) adapter;          for (int i = 0; i < adapter.getCount(); i++) {              TextView textView = createDefaultTabView(getContext());              textView.setOnClickListener(tabOnClickListener);              textView.setText(mItemName.getTabName(i));              addView(textView);          }      }  

4、绘制相应的内容 
绘制内容,肯定在 onDraw()方法中 
绘制底部线条


canvas.drawRect(0,height - mBottomLineHeight,getWidth(),height,mBottomPaint);
绘制分割线

for (int i = 0; i < getChildCount() - 1; i++) {        View child = getChildAt(i);        canvas.drawLine(child.getRight(), mDividerMargin,child.getRight(), height - mDividerMargin,mDividerPaint);          }  

重点:绘制滑动页卡

/*当前页面的View tab*/          View selectView = getChildAt(mSelectedPosition);          /*计算开始绘制的位置*/          int left = selectView.getLeft();          /*计算结束绘制的位置*/          int right = selectView.getRight();          if (mSelectionOffset > 0) {              View nextView = getChildAt(mSelectedPosition + 1);              /*如果有偏移量,重新计算开始绘制的位置*/              left = (int) (mSelectionOffset * nextView.getLeft() + (1.0f - mSelectionOffset) * left);              /*如果有偏移量,重新计算结束绘制的位置*/              right = (int) (mSelectionOffset * nextView.getRight() + (1.0f - mSelectionOffset) * right);          }          /*绘制滑动的页卡*/          canvas.drawRect(left, height - mIndicatorHeight, right, height, mIndicatorPaint); 

为了体现他的简洁之处,这里把 xml 中的代码也贴出来

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"               xmlns:tools="http://schemas.android.com/tools"               xmlns:zgy="http://schemas.android.com/apk/res-auto"                  android:layout_width="match_parent"                  android:layout_height="match_parent"                  tools:context=".MainActivity">      <demo.slidingtablayout.view.SlidingTabLayout          android:id="@+id/id_tab"          android:layout_width="match_parent"          android:layout_height="wrap_content"          zgy:bottomLineColor="#AEAEAE"          zgy:dividerMargin="15dp"          zgy:indicatorColor="#77e69c"          zgy:indicatorHeight="5dp"          zgy:bottomLineHeight="2dp"          android:background="#eeeeee">      </demo.slidingtablayout.view.SlidingTabLayout>        <android.support.v4.view.ViewPager          android:layout_below="@+id/id_tab"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:id="@+id/id_view_pager"/>  </RelativeLayout>  

MainActivity.java


public class MainActivity extends ActionBarActivity {        /*viewPager*/      private ViewPager mViewPager ;      /*自定义的 tabLayout*/      private SlidingTabLayout mTabLayout ;      /*每个 tab 的 item*/      private List<PagerItem> mTab = new ArrayList<>() ;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          mViewPager = (ViewPager) findViewById(R.id.id_view_pager) ;          mTabLayout = (SlidingTabLayout) findViewById(R.id.id_tab) ;          mTab.add(new PagerItem("tab1","FirstPager")) ;          mTab.add(new PagerItem("tab2","SecondPager")) ;          mTab.add(new PagerItem("tab3","ThirdPager")) ;          mTab.add(new PagerItem("tab4","FourthPager")) ;          mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));          /*需要先为 viewpager 设置 adapter*/          mTabLayout.setViewPager(mViewPager);      }     private class ViewPagerAdapter extends FragmentPagerAdapter implements SlidingTabLayout.TabItemName{            public ViewPagerAdapter(FragmentManager fm) {              super(fm);          }            @Override          public Fragment getItem(int position) {              return mTab.get(position).createFragment();          }            @Override          public int getCount() {              return mTab.size();          }            @Override          public String getTabName(int position) {              return mTab.get(position).getTitle();  

实现fragment页面自定义的画可以在ContentFragment里面修改


 @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        Bundle bundle =getArguments();        String msg = bundle.getString("msg");        if(rootView == null){            switch (msg){                case "FirstPager" :                    rootView = inflater.inflate(R.layout.fragment_allpage,null);                    break;                case "SecondPager" :                    rootView = inflater.inflate(R.layout.fragment_stayin,null);                    break;                case "ThirdPager" :                    rootView = inflater.inflate(R.layout.fragment_stayout,null);                    break;                case "FourthPager" :                    rootView = inflater.inflate(R.layout.fragment_styassess,null);                    break;                case "FivePager" :                    rootView = inflater.inflate(R.layout.fragment_readassess,null);                    break;            }        }        ViewGroup parent = (ViewGroup)rootView.getParent();        if(parent != null){            parent.removeView(rootView);        }        return rootView;    }

源码是原作者上传,并未修改任何

点击下载源码




0 0
原创粉丝点击