美文网首页程序员
ViewDragHelper 嵌套h5冲突 Standard启动

ViewDragHelper 嵌套h5冲突 Standard启动

作者: Ad大成 | 来源:发表于2020-07-17 17:14 被阅读0次

    ViewDragHelper 这个滑动帮助类 网上一找一大堆的介绍 就不多赘述了

    在项目中遇到一个双指滑动 出现侧边栏 侧边栏还是个最近使用的功能列表
    在写的时候出现两个重要的问题,第一个就是滑动冲突,第二个就是standard自启后
    h5界面无效的问题

    看一下xml 的基础结构

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.WebviewActivity">
    
        <com.tencent.tinyapp.view.customview.DragViewGroup
            android:id="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
            <FrameLayout
                android:visibility="gone"
                android:background="@color/colorGray2"
                android:layout_width="500dp"
                android:layout_height="match_parent"
                >
                <TextView
                    android:id="@+id/tv_ceshi"
                    android:gravity="center"
                    android:layout_marginLeft="@dimen/dp_17"
                    android:textSize="@dimen/sp_40"
                    android:textColor="@color/colorWhite"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/dp_55"
                    android:text="最近使用" />
                <FrameLayout
                    android:id="@+id/recently_root"
                    android:layout_marginTop="@dimen/dp_55"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>
            </FrameLayout>
    
            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
               >
                <LinearLayout
                    android:background="@color/colorGray"
                    android:id="@+id/toolbar_webview"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_55"
                    android:orientation="horizontal"
                    >
                    <ImageView
                        android:layout_marginLeft="@dimen/dp_24"
                        android:id="@+id/iv_webtitale"
                        android:background="@drawable/back"
                        android:layout_width="@dimen/dp_55"
                        android:layout_height="@dimen/dp_55"/>
                    <TextView
                        android:layout_marginLeft="@dimen/dp_24"
                        android:id="@+id/wv_title"
                        android:textSize="@dimen/sp_40"
                        android:textColor="@color/colorWhite"
                        android:text="标题"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"/>
                </LinearLayout>
                <com.tencent.jsbridge.BridgeWebView
                    android:layout_marginTop="@dimen/dp_55"
                    android:layout_below="@id/toolbar_webview"
                    android:id="@+id/webview_show"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
    
                    />
            </FrameLayout>
        </com.tencent.tinyapp.view.customview.DragViewGroup>
    
    <!--    <com.tencent.smtt.sdk.WebView-->
    <!--        android:id="@+id/webview_show"-->
    <!--        android:layout_width="match_parent"-->
    <!--        android:layout_height="match_parent"-->
    <!--        android:layout_marginTop="48dp"-->
    <!--        app:layout_constraintLeft_toLeftOf="parent"-->
    <!--        app:layout_constraintTop_toBottomOf="@id/toolbar_webview" />-->
    </RelativeLayout>
    

    自定义drag类

    public class DragViewGroup extends FrameLayout {
        private ViewDragHelper mViewDragHelper;
        private View mMenuView, mMainView;
        private int mWidth;
        private int oldX1 = 0, oldX2 = 0, oldY1 = 0, oldY2 = 0, newX1 = 0, newY1 = 0, newX2 = 0, newY2 = 0, mScrollPointerId1, mScrollPointerId2;
        private BridgeWebView web;
        private FrameLayout root;
    
        public DragViewGroup(Context context) {
            super(context);
            initView();
        }
    
        public DragViewGroup(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView();
        }
    
        public DragViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView();
        }
    
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            mMenuView = getChildAt(0);
            mMainView = getChildAt(1);
            web = mMainView.findViewById(R.id.webview_show);
            root = mMenuView.findViewById(R.id.recently_root);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth = mMenuView.getMeasuredWidth();
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            int pointerCount = ev.getPointerCount();
            if (pointerCount==1)return false;
    
            return mViewDragHelper.shouldInterceptTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // 将触摸事件传递给ViewDragHelper,此操作必不可少
    
    //        int pointerCount = event.getPointerCount();
    //        if (pointerCount==1){
    ////            单指事件传递给web
    //            web.onTouchEvent(event);
    //            return false;
    //        }
    
            mViewDragHelper.processTouchEvent(event);
            return true;
        }
    
        private void initView() {
            mViewDragHelper = ViewDragHelper.create(this, callback);
        }
    
        private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
    
            // 何时开始检测触摸事件
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                Log.d("sss","pointerId"+pointerId);
    //            if (pointerId==0)return false;//过滤单指
    //            else if (pointerId==1){
                    return mMainView == child;
    //            }
                // 如果当前触摸的child是mMainView时开始检测
    //            return false;
            }
    
            // 触摸到View后回调
            @Override
            public void onViewCaptured(View capturedChild, int activePointerId) {
                super.onViewCaptured(capturedChild, 2);
            }
    
            // 当拖拽状态改变,比如idle,dragging
            @Override
            public void onViewDragStateChanged(int state) {
                super.onViewDragStateChanged(state);
            }
    
            // 当位置改变的时候调用,常用与滑动时更改scale等
            @Override
            public void onViewPositionChanged(View changedView, int left, int top,
                                              int dx, int dy) {
                super.onViewPositionChanged(changedView, left, top, dx, dy);
            }
    
            // 处理垂直滑动
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return 0;
            }
    
            // 处理水平滑动
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                if (left > 0) {
                    // 如果手势向右滑动则返回,如果向左滑动不返回
                    mMenuView.setVisibility(VISIBLE);
                    return left;
                }
    
    
                return 0;
            }
    
            @Override
            public int getViewHorizontalDragRange(@NonNull View child) {
                return 1;
            }
    
            // 拖动结束后调用
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                super.onViewReleased(releasedChild, xvel, yvel);
                // 手指抬起后缓慢移动到指定位置
                if (mMainView.getLeft() < 500) {
                    // 关闭菜单
                    // 相当于Scroller的startScroll方法
                    mViewDragHelper.smoothSlideViewTo(mMainView, 0, 0);
                    mMenuView.setVisibility(GONE);
                    ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                } else {
                    // 打开菜单
                    mViewDragHelper.smoothSlideViewTo(mMainView, 800, 0);
                    ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
                }
            }
        };
    
        @Override
        public void computeScroll() {
            if (mViewDragHelper.continueSettling(true)) {
                ViewCompat.postInvalidateOnAnimation(this);
            }
        }
    
    
    }
    

    这里解决冲突问题 主要还是onInterceptTouchEvent 事件拦截方法里面 设置单指不拦截 双指拦截交给
    viewDraghelper去处理就可以了

    问题二 就是侧滑打开了最近使用的一个fragment界面 但是最近使用的都是h5的小程序 所以启动还是自己
    如果用栈内复用和栈顶模式都是不可以跳转其他h5界面的 因为onNewIntent的缘故,所以需要设置standard
    启动模式!那么设置这个模式问题又来了 第二个界面覆盖第一个界面的时候 一旦返回 直接返回第一个界面
    而第一个界面的h5页面就会失去点击功能 具体情况不清楚 所以我做了任务栈处理来解决这个问题,不管开几个界面 最终返回的时候都回退到上一层界面 把所有的standard启动的自己 全部弹出任务栈

    简单版本的 TaskUtils

    public class ActivityStack {
    
        private static volatile ActivityStack mInstance;
        private LinkedList<Activity> mActivityList;
    
        public ActivityStack() {
            this.mActivityList = new LinkedList<>();
        }
    
        public static ActivityStack getInstance(){
            if (mInstance==null){
                synchronized (ActivityStack.class){
                    if (mInstance==null){
                        mInstance=new ActivityStack();
                    }
                }
            }
            return mInstance;
        }
    
        public void addActivity2Stack(Activity activity){
            mActivityList.add(activity);
        }
        public void removeActivity2Stack(Activity activity){
            mActivityList.remove(activity);
        }
    
        public void finishAll(){
            for (Activity activity : mActivityList) {
                activity.finish();
            }
        }
    }
    

    然后在自启界面的onResume 中add 当前activity实例 在需要退出的地方 finishAll 即可

    相关文章

      网友评论

        本文标题:ViewDragHelper 嵌套h5冲突 Standard启动

        本文链接:https://www.haomeiwen.com/subject/onoghktx.html