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>
/*默认的页卡颜色*/ 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
- ViewPager 滑动页卡切换
- ViewPager + Fragment 仿微信滑动切换页卡
- ViewPager实现滑动切换标签页
- ViewPager在首尾页滑动切换
- viewpager、fragment滑动切换卡顿问题
- ViewPager滑动切换界面
- ViewPager的滑动切换
- ViewPager 滑动切换 activity
- ViewPager页面滑动切换
- ViewPager滑动切换禁用
- ViewPager切换滑动速度
- ViewPager切换滑动速度
- ViewPager滑动切换界面
- android: ViewPager滑动切换Activity
- android: ViewPager滑动切换Activity
- ViewPager切换滑动速度修改
- ViewPager切换滑动速度修改
- ViewPager切换滑动速度修改
- 《深入理解Linux网络技术内幕》阅读笔记(三十)
- padding在li种的解决
- Intent传递对象的两种方法Serializable 和 Parcelable
- 学习算法的网站值得推荐
- Android下载apk和自动安装,断点下载
- ViewPager 滑动页卡切换
- 耦合
- java springMVC前台和后台间传数据乱码
- 如何在已创建好的cocos2dx项目中查看使用引擎的版本号
- php 把非数组转换为数组方法
- 探究CSS display:inline|block|inline-block差异
- 我的Java学习之路——关键字final、static、this
- c语言结构体学习笔记
- 注册你app所支持的文件类型以及Document interaction案例