Android 左右切换页面item
2016-08-22 12:26
176 查看
转载请标明出处: 【明明爱的博客】
这种登录方式没必要让用户要切换界面。
本文先用viewpager来实现,后续会出用自定义view的文章。
难点分析:
- 怎样得到滑动时的事件
- 通过什么数值来得到动画的比例
- 得到需要滑动的view
ok,其实同过分析就这两个难点而已。通过查看viewpager的api可以知道viewpager提供了onPageScrolled(int position, float offset, int offsetPixels)方法,刚好解决了得到滑动事件的难点。
position 当前viewpager的fragment 第一个为0,第二个为1,如此类推
offset 滑动比例 如果position 从 0到1时 滑动比例:0~1, 当position = 1时,offset=0, offsetPixels=0。 如果position 从1~0时 滑动比例:1~0。
offsetPixels 屏幕宽度
代码分析:
leftView和rightView分别是要滑动的两个View,主要的动画都在startAnimate()里,mLScaleY是leftView缩小或放大的比例。if (positionOffsetPixels > scrollX) 当leftView滑动多少距离之后向相反方向返回,之后将rightView在前面显示:rightView.bringToFront();。mTrans是算出需要滑动的距离。
其实viewpager默认的布局是:
所以一开始就把fragment2移动到了fragment1的下面:mTrans = -getWidth() - getPageMargin() + positionOffsetPixels*2+defaultTranslationX;
要理解了动画滑动是滑动view的内容,而非view的实体。但viewpager本身的滑动是会滑动实体的,通过看viewpager的源码,发现viewpager的动画是用了Scroller对象来滑动的。Scroller每次滑动都会调用onDraw里的computeScroll()方法。只有理解好这含义,其他就很好理解了。
一、概述
好的交互会让人用起来很舒服,其实很多页面是没有必要切换页面的,例如图上密码登录和短信登录的两种情况。什么都不说,先上图:这种登录方式没必要让用户要切换界面。
二、分析
其实以上的实现方式有很多,如viewpager、自定义view等。本文先用viewpager来实现,后续会出用自定义view的文章。
难点分析:
- 怎样得到滑动时的事件
- 通过什么数值来得到动画的比例
- 得到需要滑动的view
ok,其实同过分析就这两个难点而已。通过查看viewpager的api可以知道viewpager提供了onPageScrolled(int position, float offset, int offsetPixels)方法,刚好解决了得到滑动事件的难点。
position 当前viewpager的fragment 第一个为0,第二个为1,如此类推
offset 滑动比例 如果position 从 0到1时 滑动比例:0~1, 当position = 1时,offset=0, offsetPixels=0。 如果position 从1~0时 滑动比例:1~0。
offsetPixels 屏幕宽度
package com.mingmingai.test_custom_login.customview; /** * Created by 明明爱 */ public class CustomViewpager extends ViewPager { private View leftView; private View rightView; private List<Fragment> fragmentsList; private float mTrans; //滑动的距离 private float mLScaleY; //最大的缩小比例 private static final float lDefaultScaleX = 0.9f; //leftView默认缩小X的比例 private static final float defaultScaleY = 0.9f; //默认缩小Y的比例 private static final float scalePrecent = 0.1f; //默认缩小的比例 private int screenWidth = 0; //屏幕宽度 private int scrollX = 230; //滑动多少距离之后向相反方向返回 private int defaultTranslationX = 10; //默认移动的X距离 public CustomViewpager(Context context) { super(context); } public CustomViewpager(Context context, AttributeSet attrs) { super(context, attrs); screenWidth = CommonUtils.getWindowWidth(context); } public void setFragmentsList(List<Fragment> fragmentsList) { this.fragmentsList = fragmentsList; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; //拦截 } @Override public boolean onTouchEvent(MotionEvent ev) { return false; //不给viewpager滑动 } @Override protected void onPageScrolled(int position, float offset, int offsetPixels) { if (position +1<= fragmentsList.size() - 1) { // 滑动特别小的距离时,我们认为没有动,可有可无的判断 float effectOffset = isSmall(offset) ? 0 : offset; leftView = fragmentsList.get(position).getView(); //得到View rightView = fragmentsList.get(position + 1).getView(); //得到View startAnimate(leftView, rightView, effectOffset, offsetPixels); } super.onPageScrolled(position, offset, offsetPixels); } private void startAnimate(View leftView, View rightView, float effectOffset, int positionOffsetPixels) { if (leftView != null) { manageLayer(leftView, true); mLScaleY = (float) (defaultScaleY - scalePrecent*effectOffset); if (positionOffsetPixels > scrollX){ mTrans = scrollX*((positionOffsetPixels-scrollX)/(screenWidth - scrollX))+(positionOffsetPixels-scrollX)-defaultTranslationX; rightView.bringToFront(); }else{ leftView.bringToFront(); mTrans = -defaultTranslationX; } ViewHelper.setTranslationX(leftView,mTrans); ViewHelper.setScaleX(leftView, lDefaultScaleX); ViewHelper.setScaleY(leftView, mLScaleY); } if (rightView != null) { manageLayer(rightView, true); mLScaleY = (float) (defaultScaleY - scalePrecent*(1-effectOffset)); ViewHelper.setScaleX(rightView, lDefaultScaleX); ViewHelper.setScaleY(rightView, mLScaleY); if (positionOffsetPixels > scrollX){ mTrans = -getWidth()+scrollX*2+defaultTranslationX; if (Math.abs(mTrans) >= getWidth()-positionOffsetPixels){ mTrans = -getWidth() - getPageMargin() + positionOffsetPixels+defaultTranslationX; } }else{ mTrans = -getWidth() - getPageMargin() + positionOffsetPixels*2+defaultTranslationX; } ViewHelper.setTranslationX(rightView, mTrans); } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void manageLayer(View v, boolean enableHardware) { // if (!API_11) // return; int layerType = enableHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE; if (layerType != v.getLayerType()) v.setLayerType(layerType, null); } private boolean isSmall(float positionOffset) { return Math.abs(positionOffset) < 0.0001; } }
代码分析:
leftView和rightView分别是要滑动的两个View,主要的动画都在startAnimate()里,mLScaleY是leftView缩小或放大的比例。if (positionOffsetPixels > scrollX) 当leftView滑动多少距离之后向相反方向返回,之后将rightView在前面显示:rightView.bringToFront();。mTrans是算出需要滑动的距离。
其实viewpager默认的布局是:
所以一开始就把fragment2移动到了fragment1的下面:mTrans = -getWidth() - getPageMargin() + positionOffsetPixels*2+defaultTranslationX;
要理解了动画滑动是滑动view的内容,而非view的实体。但viewpager本身的滑动是会滑动实体的,通过看viewpager的源码,发现viewpager的动画是用了Scroller对象来滑动的。Scroller每次滑动都会调用onDraw里的computeScroll()方法。只有理解好这含义,其他就很好理解了。
相关文章推荐
- Android 页面左右滑动切换
- Android 手势识别 (左右滑动)实现 页面 切换
- Android 左右滑动切换页面或Activity的效果实现
- android安卓 Fragment实现页面标题左右同步切换以及点击标题切换页面
- android 页面切换左右滑动动画
- android ViewPager页面左右滑动切换
- Android 左右滑动切换页面或Activity的效果实现
- Android 手势识别 (左右滑动)实现 页面 切换
- Android 页面左右切换动画实现
- Android 手势识别 (左右滑动)实现 页面 切换
- Android高级UI ViewFlipper左右滑屏切换页面
- Android-仿微信左右滑动点击切换页面和图标
- Android面试题-终极解决ViewPager.setCurrentItem中间很多页面切换方案
- Android 实现item或页面上下滑动切换
- Android:Fragment实现带导航条的页面左右切换
- android ViewPager页面左右滑动切换
- Android 利用ViewPager实现底部圆点导航左右滑动效果以及Fragment页面切换
- android ViewPager实现页面左右切换效果
- Android实现页面左右切换
- Android左右滑动切换页面