ViewDragHelper 嵌套h5衝突 Standard啓動模式管理

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章