程序员

ViewDragHelper 嵌套h5冲突 Standard启动

2020-07-17  本文已影响0人  Ad大成

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 即可

上一篇下一篇

猜你喜欢

热点阅读