• 滑动关闭activity


    对于微信滑动关闭activity的功能,我一直觉得挺酷,想在自己的项目上也加上这个功能。网上找了一下发现一个不错的思路。

    使用ViewDragHelper。

    首先要让activity在滑动的时候下面的activity能够看得到,那么就得设置activity的主题,让activity的窗口变透明。

    <style name="MyActivityBackground" parent="MyAppTheme">
            <item name="android:windowBackground">@android:color/transparent</item>
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
    </style>

    该主题继承MyAppTheme(这也是个自定义的主题,整个application就是用这个主题,为了不避免冲突,继承它)。
    尤其要注意的是windowAnimationStyle,这个是设置activity的进入与退出的动画效果,设置为默认的效果。

    然后在需要实现滑动退出的activity的注册文件上用上这个主题就行了。

     以下是全部代码

    public class MyDragViewGroup extends FrameLayout{
    
        private ViewDragHelper mViewDragHelper;
    
        //该自定义组件的宽
        private int mWidth;
    
        //该自定义组件的高
        private int mHeight;
    
        //需要滑动的组件目前已经滑动的距离
        private int currentLeft;
    
        //该滑动距离用于判断是否可以将activity关闭
        private int mSlidX;
    
        private static final int x=40;
        private Context mContext;
    
        //需要滑动的view
        private View view;
    
        private Paint mPaint;
    
        public MyDragViewGroup(Context context) {
            super(context);
            initView(context);
        }
    
        public void bind()
        {
            //获取activity的视图
            ViewGroup viewGroup= (ViewGroup) ((Activity)mContext).getWindow().getDecorView();
            view=viewGroup.getChildAt(0);
    
            viewGroup.removeView(view); //将该视图移除
            addView(view);  //将该视图添加进去这个自定义的组件
            viewGroup.addView(this); //将该自定义的组件整个添加进decorView
        }
    
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth=getMeasuredWidth();
            mHeight=getMeasuredHeight();
            mSlidX= (int) (mWidth*0.3);
        }
    
        private void initView(Context context)
        {
            mContext=context;
    
            mViewDragHelper=ViewDragHelper.create(this,callback);
            //边缘检测
            mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    
            mPaint=new Paint();
            mPaint.setStrokeWidth(2);
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.GRAY);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            return mViewDragHelper.shouldInterceptTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            mViewDragHelper.processTouchEvent(event);
            return true;
        }
    
    
        private ViewDragHelper.Callback callback=new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                return false;
            }
    
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return 0;
            }
    
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                return left;
            }
    
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                super.onViewReleased(releasedChild, xvel, yvel);
    
                //如果滑动的距离小于mSlidX,那么就滑回原处
                if (view.getLeft()<mSlidX)
                {
                    mViewDragHelper.smoothSlideViewTo(view,0,0);
                    ViewCompat.postInvalidateOnAnimation(MyDragViewGroup.this);
                }
                //否则滑出屏幕
                else
                {
                    mViewDragHelper.smoothSlideViewTo(view,mWidth,0);
                    ViewCompat.postInvalidateOnAnimation(MyDragViewGroup.this);
                }
                invalidate();
            }
    
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                mViewDragHelper.captureChildView(view,pointerId);
            }
    
            @Override
            public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
                currentLeft=left;
                invalidate();
                if (left>=mWidth)
                {
                    ((Activity)mContext).finish();
                }
            }
        };
    
        @Override
        public void computeScroll() {
            if (mViewDragHelper.continueSettling(true))
            {
                ViewCompat.postInvalidateOnAnimation(this);
                invalidate();
            }
        }
    
        @Override
        protected void dispatchDraw(Canvas canvas) {
            drawShadow(canvas);
            super.dispatchDraw(canvas);
        }
    
        protected void drawShadow(Canvas canvas) {
            canvas.save();
    
            Shader mShader=new LinearGradient(currentLeft - x, 0, currentLeft, 0, new int[]{Color.parseColor("#1edddddd"),
                    Color.parseColor("#6e666666"), Color.parseColor("#9e666666")}, null, Shader.TileMode.REPEAT);
            mPaint.setShader(mShader);
            //绘制时,注意向左边偏移
            RectF rectF = new RectF(currentLeft - x, 0, currentLeft, mHeight);
            canvas.drawRect(rectF, mPaint);
            canvas.restore();
        }
    }

    如果知道ViewDragHelper的使用,那么上面的代码很容易看得明白。drawShadow()是为了绘制阴影,注意在滑动的过程中要不断的刷新重绘,让阴影跟随着activity的移动而移动。

    值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(), getIntrinsicHeight()方法,然后设为背景。

    要使用的时候只需要在activity里加入

    MyDragViewGroup myDragViewGroup=new MyDragViewGroup(this); myDragViewGroup.bind();就OK了。

    myDragViewGroup.bind();主要是将activity的视图放入该自定义的ViewGroup当中,然后再把整个自定义的ViewGroup设置给activity。

    参考博客:http://blog.csdn.net/meijian531161724/article/details/50763931

  • 相关阅读:
    1、Python的初识与简介
    解密解密
    python看是32位还是64
    linux实战一段,安装python3(centos)
    前段技巧
    django后端safe和前端safe的方法
    测试
    python小知识整理
    ajax格式
    111
  • 原文地址:https://www.cnblogs.com/tangZH/p/6896192.html
Copyright © 2020-2023  润新知