竖直滑动View制作引导页

传承者(Inheritors)打造共同进步生态圈!!!

转载:http://write.blog.youkuaiyun.com/postedit/23692439

三段论:滑动所需要的准备,自定义ViewGoup,布局中使用

自定义ViewGoup
public class VerticalLinearLayout extends ViewGroup {


   public class VerticalLinearLayout extends ViewGroup {


    /**
     * 屏幕的高度
     */
    private int mScreenHeight;
    /**
     * 手指按下时的getScrollY
     */
    private int mScrollStart;
    /**
     * 手指抬起时getScrollY
     */
    private int mScrollEnd;
    /**
     * 记录移动时的Y
     */
    private int mLastY;
    /**
     * 滚动的辅助类
     */
    private Scroller mScroller;
    /**
     * 是否正在滚动
     */
    private boolean isScrolling;

    /**
     * 加速度检测
     *
     */
    private VelocityTracker mVelocityTracker;

    /**
     * 记录当前页
     *
     */
    private int currentPage = 0;

    private OnPageChangeListener mOnPageChangeListener;
    private int childHeight;


    public VerticalLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        /**
         * 获得屏幕的高度
         */
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenHeight = outMetrics.heightPixels;

        //初始化
        mScroller = new Scroller(context);



    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View childView = getChildAt(i);

            measureChild(childView,widthMeasureSpec,mScreenHeight);
        }

    }



    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(changed){
            int childCount = getChildCount();
            //设置主布局的高度
            MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
            lp.height = mScreenHeight*childCount;
            setLayoutParams(lp);

            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if(child.getVisibility() != View.GONE){
                    child.layout(l,i*mScreenHeight,r,(i+1)*mScreenHeight);//调用每个自布局的layout
                }
                childHeight = getChildAt(0).getMeasuredHeight();
            }
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {


        //如果当前正在滚动,调用父类的onTouchEvent
        if (isScrolling) {
            return super.onTouchEvent(event);
        }
         int action =event.getAction();
        int y = (int)event.getY();

        obtainVelocity(event);
        switch (action){
            case MotionEvent.ACTION_DOWN:
                mScrollStart = getScrollY();
                mLastY =  y;
                break;
            case MotionEvent.ACTION_MOVE:
                if(!mScroller.isFinished()){
                    mScroller.abortAnimation();
                }
                int dy = mLastY - y;
                //边际值检查
                int scrollY = getScrollY();

               //已经到达顶端,下拉多少,就往上滚动多少
                if(dy<0 && scrollY+dy < 0 ){
                  dy = -scrollY;
                }
                //已经达到底部了,上拉多少,留往下滚动多少
                if(dy>0 && scrollY+dy > getHeight() - mScreenHeight){
                   dy = getHeight() - mScreenHeight - scrollY;
                }
                scrollBy(0,dy);

                mLastY = y;
                break;
            case MotionEvent.ACTION_UP:
                mScrollEnd = getScrollY();
                int dScrollY = mScrollEnd - mScrollStart;
                if(wantScrollToNext()){
                    //往上滑动
                    if(shouldScrollToNext()){
                        mScroller.startScroll(0,getScrollY(),0, mScreenHeight - dScrollY);

                    }else{
                        mScroller.startScroll(0,getScrollY(),0,-dScrollY);
                    }
                }
                if(wantScrollToPre()){
                    //往下下滑
                    if(shouldScrollToPre()){
                        mScroller.startScroll(0,getScrollY(),0,-mScreenHeight - dScrollY);

                    }else{
                        mScroller.startScroll(0,getScrollY(),0 , -dScrollY);
                    }
                }
                isScrolling = true;
                postInvalidateDelayed(0);
                recycleVelocity();
                break;
        }
        return  true;
    }

    /**
     * 根据滚动距离判断是否能够滚动到下一页
     */
    private boolean shouldScrollToNext() {


        return mScrollEnd - mScrollStart > mScreenHeight / 2 || Math.abs(getYVelocity()) > 600;
    }

    /**
     * 根据用户滑动,判断用户的意图是否是滚动到下一页
     *
     */
    private boolean wantScrollToNext(){
        return mScrollEnd> mScrollStart ;
    }

    /**
     * 根据滚动距离判断是否能够滚动到上一页
     * @return
     */
    private boolean shouldScrollToPre(){

        return -mScrollEnd + mScrollStart > mScreenHeight / 2 || Math.abs(getYVelocity())>600;
    }

    /**
     * 根据用户滑动,判断用户意图是否是滚动到上一页
     * @return
     */
    private boolean wantScrollToPre(){

        return mScrollEnd < mScrollStart;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            scrollTo(0,mScroller.getCurrY());
            postInvalidate();
        }else {
            int position = getScrollY() / mScreenHeight;
            if(position != currentPage){
                if(mOnPageChangeListener!= null){
                currentPage = position;
                mOnPageChangeListener.onPageChange(currentPage);
            }}
            isScrolling = false;
        }


    }

    /**
     * 初始化加速度检测器
     * @param event
     */
    private void obtainVelocity(MotionEvent event) {
        if(mVelocityTracker == null){
            mVelocityTracker = VelocityTracker.obtain();

        }
        mVelocityTracker.addMovement(event);
    }


    /**
     * 资源释放
     */
    private void recycleVelocity(){
        if(mVelocityTracker != null){
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    /**
     * 设置回调接口
     * @param onPageChangeListener
     */
    public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener){
        mOnPageChangeListener = onPageChangeListener;
    }

    public int getYVelocity() {

        mVelocityTracker.computeCurrentVelocity(1000);

        return (int) mVelocityTracker.getYVelocity();
    }

    public interface  OnPageChangeListener{
        void onPageChange(int  currentPage);
    }
}

布局出来

<com.example.administrator.testapplication.VerticalLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/id_main_ly"
    android:background="#fff"
    tools:context="com.example.administrator.testapplication.MainActivity">


     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@mipmap/shenang"
         >

     </RelativeLayout>
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@mipmap/dragon_boat"
         >

     </RelativeLayout>
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@mipmap/zhagao"
         >

     </RelativeLayout>
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@mipmap/dragon_boat_fes"
         >
     </RelativeLayout>
</com.example.administrator.testapplication.VerticalLinearLayout>

在Activity中使用

public class MainActivity extends Activity {
private VerticalLinearLayout mMainLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMainLayout = (VerticalLinearLayout) findViewById(R.id.id_main_ly);
        mMainLayout.setOnPageChangeListener(new VerticalLinearLayout.OnPageChangeListener() {
            @Override
            public void onPageChange(int currentPage) {
                Toast.makeText(MainActivity.this, "第"+(currentPage+1)+"页", Toast.LENGTH_SHORT).show();
            }
        });

    }

}
基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型,个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业,代码资料完整,下载可用。 基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值