zoukankan      html  css  js  c++  java
  • 仿ViewPager实现页面切换的动画效果

    (1)自定义类继承ViewGroup,并实现一个构造方法和onLayout方法

    public class MyScrollPager extends ViewGroup{
        
        private Context ctx;

        public MyScrollPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        
        //定义页面的布局
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
        }

    (2)在xml(activity_mian.xml)布局中添加自定义view

      <com.bxf.myviewpager.MyScrollPager
             android:id="@+id/mypager"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

    (3)在MainActivity中找到此view比添加几个子view

    public class MainActivity extends Activity{
        
        private int[] ids = {R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4,R.drawable.a5,R.drawable.a6};
        private MyScrollPager scrollPager;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            scrollPager = (MyScrollPager) findViewById(R.id.mypager);
            
            for (int i = 0; i < ids.length; i++) {
                ImageView image = new ImageView(this);
                image.setBackgroundResource(ids[i]);
                scrollPager.addView(image);//将imageview 添加到view中
            }
        }
    }
    (4)在MyScrollPager中找到新添加的子view,并指定其位置

    //定义页面的布局
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            //定义每一个view的布局
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                View view = getChildAt(i);
                view.layout(i*getWidth(), 0, getWidth() + i*getWidth(), getHeight());
            }
        }

    (5)添加滑动监听事件,并实现滑动切换

    GestureDetector gestureDetector = new GestureDetector(ctx, new OnGestureListener() {
                
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return false;
                }
                
                @Override
                public void onShowPress(MotionEvent e) {
                    
                }
                
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                        float distanceY) {
                    scrollBy((int) distanceX, 0);//在屏幕上滑动
                    return false;
                }
                
                @Override
                public void onLongPress(MotionEvent e) {
                    
                }
                
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                        float velocityY) {
                    return false;
                }
                
                @Override
                public boolean onDown(MotionEvent e) {
                    return false;
                }
            });//手势识别器
        private float firstX = 0;//初始位置
        private float offsetX = 0;//初始位置
        private int currId = 0;//当前屏幕显示的图片ID
        //设置滑动监听
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            gestureDetector.onTouchEvent(event);
            
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                firstX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                
                break;
            case MotionEvent.ACTION_UP:
                offsetX = event.getX() - firstX;
                updateCurrId(offsetX);
                //瞬间移动
                scrollTo(currId * getWidth(), 0);
                break;

            }
            return true;
        }

    //更新当前显示的图片ID
        private void updateCurrId(float endX2) {
            if(offsetX > getWidth()/2){
                currId --;//上一张图片
            }else if(offsetX < -getWidth()/2){
                currId ++;//下一张图片
            }
            currId = (currId>0)?currId:0;
            currId = (currId>=getChildCount()-1)?getChildCount()-1:currId;
        }

    (6)实现缓慢滚动效果

    创建滚动类,Scroller管理滚动的位置

    public class Scroller {
        
        private int duration = 500;//需要滚动的时间
        private float currX;//滚动到的当前位置
        
        

        private float startX;
        private float startY;
        private float disX;
        private float disY;
        private long startTime;
        private boolean isFinish;//是否结束了滚动--true->是
        public void startScroll(float startX, float startY, float disX, float disY) {
            this.startX = startX;
            this.startY = startY;
            this.disX = disX;
            this.disY = disY;
            this.startTime = SystemClock.uptimeMillis();
            this.isFinish = false;
        }
        
        public boolean computeScrollOffset(){
            if(isFinish){//滚动已经结束
                return false;
            }
            long currTime = SystemClock.uptimeMillis();
            long scrollTime = currTime - startTime;
            //计算滚动到的当前位置
            if(scrollTime < duration){
                //正在滚动
                currX = startX + disX*scrollTime/duration;
            }else{
                //滚动完成
                currX = startX + disX;
                isFinish = true;
            }
            return true;
        }
        
        
        public int getDuration() {
            return duration;
        }

        public void setDuration(int duration) {
            this.duration = duration;
        }

        public float getCurrX() {
            return currX;
        }

        public void setCurrX(float currX) {
            this.currX = currX;
        }
        
    }

    (7)最后MianActivity中的代码如下

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.GestureDetector.OnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;

    public class MyScrollPager extends ViewGroup{
        
        private Context ctx;
        private Scroller scroller;

        public MyScrollPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.ctx = context;
            init();
        }
        
        //定义页面的布局
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            //定义每一个view的布局
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                View view = getChildAt(i);
                view.layout(i*getWidth(), 0, getWidth() + i*getWidth(), getHeight());
            }
        }
        
        GestureDetector gestureDetector;//手势识别器
        private float firstX = 0;//初始位置
        private float offsetX = 0;//初始位置
        private int currId = 0;//当前屏幕显示的图片ID
        //设置滑动监听
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            gestureDetector.onTouchEvent(event);
            
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                firstX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                
                break;
            case MotionEvent.ACTION_UP:
                offsetX = event.getX() - firstX;
                updateCurrId(offsetX);
                //瞬间移动
                scrollTo(currId * getWidth(), 0);
                //缓慢移动
                getScrollX();//代表左边缘总共滑动的距离距起始点的距离
                scroller.startScroll(getScrollX(), 0,currId * getWidth() - getScrollX(),0);
                break;

            }
            invalidate();//刷新界面,这个方法会导致computeScroll方法的执行
            return true;
        }
        @Override
        public void computeScroll() {
            if(scroller.computeScrollOffset()){
                float currX = scroller.getCurrX();
                scrollTo((int) currX, 0);
                invalidate();//刷新界面
            }
        }
        //更新当前显示的图片ID
        private void updateCurrId(float endX2) {
            if(offsetX > getWidth()/2){
                currId --;//上一张图片
            }else if(offsetX < -getWidth()/2){
                currId ++;//下一张图片
            }
            currId = (currId>0)?currId:0;
            currId = (currId>=getChildCount()-1)?getChildCount()-1:currId;
        }

        private void init() {
            scroller = new Scroller();
            gestureDetector = new GestureDetector(ctx, new OnGestureListener() {
                
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return false;
                }
                
                @Override
                public void onShowPress(MotionEvent e) {
                    
                }
                
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                        float distanceY) {
                    scrollBy((int) distanceX, 0);//在屏幕上滑动
                    return false;
                }
                
                @Override
                public void onLongPress(MotionEvent e) {
                    
                }
                
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                        float velocityY) {
                    return false;
                }
                
                @Override
                public boolean onDown(MotionEvent e) {
                    return false;
                }
            });
        }
    }

  • 相关阅读:
    使用element-ui是下拉筛选选择
    vue 组件传值
    vue element 地址联动的使用
    vux scroller
    实时监听组件中路由的变化
    vuex的使用
    对移动端滚动高度的获取
    【转】ACM 取石子问题
    【转】ACM博弈知识汇总
    EOJ 2857 编辑距离
  • 原文地址:https://www.cnblogs.com/bxf123/p/5122353.html
Copyright © 2011-2022 走看看