42

NestedScrollView でボトムシートの動作を実装しました。そして、外側に触れたときにボトムシートビューを非表示にすることができるかどうか疑問に思っていました.

4

10 に答える 10

55

最後に、私はこれを行うことができました、

次のコード行を使用しました。

@Override public boolean dispatchTouchEvent(MotionEvent event){
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED) {

            Rect outRect = new Rect();
            bottomSheet.getGlobalVisibleRect(outRect);

            if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        }
    }

    return super.dispatchTouchEvent(event);
}

それが誰かの一日を救うことを願っています!

于 2016-07-04T13:26:18.880 に答える
33

質問/回答のOPに感謝します。私は彼のコードを使用しましたが、そのクリーンさが向上したので共有したいと思いました。ビューを拡張してインターフェイスを追加する代わりに、BottomSheetBehavior で直接コーディングできます。このような:

AutoCloseBottomSheetBehavior.java

import android.content.Context;
import android.graphics.Rect;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class AutoCloseBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {

    public AutoCloseBottomSheetBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN &&
            getState() == BottomSheetBehavior.STATE_EXPANDED) {

            Rect outRect = new Rect();
            child.getGlobalVisibleRect(outRect);

            if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
                setState(BottomSheetBehavior.STATE_COLLAPSED);
            }
        }
        return super.onInterceptTouchEvent(parent, child, event);
    }
}

次に、それを XML レイアウトに追加するだけです。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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">

   ... your normal content here ...
   <SomeLayout... />

    ... the bottom sheet with the behavior
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_behavior="<com.package.name.of.the.class>.AutoCloseBottomSheetBehavior">

        ... the bottom sheet views

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>
于 2017-08-30T10:52:34.147 に答える
15

アクティビティの場合:

@Override 
public boolean dispatchTouchEvent(MotionEvent event){
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED) {

            Rect outRect = new Rect();
            bottomSheet.getGlobalVisibleRect(outRect);

            if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        }
    }

    return super.dispatchTouchEvent(event);
}

フラグメントの場合:アクティビティで同じメソッドを使用します。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if (fragment != null && fragment instanceof HomeFragment) {
            ((HomeFragment) fragment).hideBottomSheetFromOutSide(event);
        }
    }
    return super.dispatchTouchEvent(event);
}

次のように Fragment でメソッドを作成します。

   /**
     * Calling from Dashboard Activity
     *
     * @param event Motion Event
     */
    public void hideBottomSheetFromOutSide(MotionEvent event) {
        if (isBottomSheetMenuExpanded()) {
            Rect outRect = new Rect();
            mBinding.homeBottomSheetLayout.getGlobalVisibleRect(outRect);
            if (!outRect.contains((int) event.getRawX(), (int) event.getRawY()))
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        }
    }

それがあなたを助けることを願っています。

ありがとうございました。

于 2018-10-03T14:32:19.077 に答える
0

フラグメントに dispatchTouchEvent を実装する方法を見つけている人はたくさんいます。そのため、これを行う方法は次のとおりです。

定義に従ってカスタム レイアウトを作成します。

public class DispatchTouchEvent extends LinearLayout {

    public interface onDispatchEvent
    {
        void dispatchEvent(MotionEvent e);
    }

    private onDispatchEvent dispatchEvent;

    public DispatchTouchEvent(Context context) {
        super(context);
    }

    public DispatchTouchEvent(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DispatchTouchEvent(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setDispatchEvent(onDispatchEvent dispatchEvent)
    {
        this.dispatchEvent=dispatchEvent;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(dispatchEvent!=null)
        {
            dispatchEvent.dispatchEvent(ev);
        }
        return super.dispatchTouchEvent(ev);
    }

}

このレイアウトをフラグメント レイアウトのベースとして使用します。フラグメント内で、このレイアウトを次のように初期化します。

public class ABC extends fragment implements DispatchTouchEvent.onDispatchEvent
{

DispatchTouchEvent dispatchTouchEvent;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
....
    dispatchTouchEvent = (DispatchTouchEvent)rootView.findViewById(R.id.dispatch_event);
    dispatchTouchEvent.setDispatchEvent(this);
....
}

@Override
public void dispatchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
    if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED) 
    {

        Rect outRect = new Rect();
        bottomSheet.getGlobalVisibleRect(outRect);

        if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))   
         mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    }
    }

    }

}
于 2017-07-27T12:19:03.073 に答える
0

私にとってそれは単純なものでしsetCancelable(true);

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);

    View contentView = View.inflate(getContext(), R.layout.layout_additional_prices, null);
    unbinder = ButterKnife.bind(this, contentView);
    dialog.setContentView(contentView);
    dialog.setOnKeyListener(new BottomSheetBackDismissListener());
    //makeBottomSheetFullScreen(getActivity(), mBottomSheetBehaviorCallback, contentView);
    setCancelable(true);
}
于 2021-03-14T20:28:39.643 に答える