बॉटमशीट पर उपयोगकर्ता को खींचना अक्षम करना


99

मैं उपयोगकर्ता को खींचने पर अक्षम करने का प्रयास कर रहा हूं BottomSheet। मुझे अक्षम करने का कारण दो चीजें हैं। 1. यह ListViewनीचे की ओर स्क्रॉल करने से रोक रहा है, 2. मैं उपयोगकर्ताओं को ड्रैगिंग का उपयोग करके खारिज नहीं करना चाहता, लेकिन इस पर एक बटन के साथ BottomSheetView। यही मैंने किया है

 bottomSheetBehavior = BottomSheetBehavior.from(bottomAnc);
    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                //Log.e("BottomSheet", "Expanded");
            } else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                //Log.e("BottomSheet", "Collapsed");
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            // React to dragging events
            bottomSheet.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int action = MotionEventCompat.getActionMasked(event);
                    switch (action) {
                        case MotionEvent.ACTION_DOWN:
                            return false;
                        default:
                            return true;
                    }
                }
            });
        }
    });

सबसे नीचे

    <?xml version="1.0" encoding="utf-8"?><FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior"
android:id="@+id/bottomSheet">

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:elevation="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical">

            <TextView
                android:id="@+id/text1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Order Items"
                android:layout_margin="16dp"
                android:textAppearance="@android:style/TextAppearance.Large"/>


            <Button
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="5dp"
                android:background="@drawable/bg_accept"/>

            <Button
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="8dp"
                android:background="@drawable/bg_cancel"/>

        </LinearLayout>

        <ListView
            android:id="@+id/item_edit"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:divider="@color/md_divider_black"
            android:dividerHeight="1dp"/>

    </LinearLayout>

</android.support.v7.widget.CardView>


कृपया, मेरा उत्तर जांचें। मैंने देखा है कि यह स्वीकृत उत्तर की तुलना में अधिक प्रासंगिक है
विटालि ओबाइडिको

जवाबों:


92

यह अब प्रासंगिक नहीं हो सकता है, लेकिन मैं इसे यहां छोड़ दूंगा:

import android.content.Context
import android.util.AttributeSet
import androidx.coordinatorlayout.widget.CoordinatorLayout
import android.view.MotionEvent
import android.view.View
import com.google.android.material.bottomsheet.BottomSheetBehavior

@Suppress("unused")
class LockableBottomSheetBehavior<V : View> : BottomSheetBehavior<V> {
    constructor() : super()
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    var swipeEnabled = true

    override fun onInterceptTouchEvent(
        parent: CoordinatorLayout,
        child: V,
        event: MotionEvent
    ): Boolean {
        return if (swipeEnabled) {
            super.onInterceptTouchEvent(parent, child, event)
        } else {
            false
        }
    }

    override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
        return if (swipeEnabled) {
            super.onTouchEvent(parent, child, event)
        } else {
            false
        }
    }

    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ): Boolean {
        return if (swipeEnabled) {
            super.onStartNestedScroll(
                coordinatorLayout,
                child,
                directTargetChild,
                target,
                axes,
                type
            )
        } else {
            false
        }
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        if (swipeEnabled) {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
        }
    }

    override fun onStopNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        target: View,
        type: Int
    ) {
        if (swipeEnabled) {
            super.onStopNestedScroll(coordinatorLayout, child, target, type)
        }
    }

    override fun onNestedPreFling(
        coordinatorLayout: CoordinatorLayout,
        child: V,
        target: View,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        return if (swipeEnabled) {
            super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
        } else {
            false
        }
    }
}

और अपने xml फ़ाइल में इसका उपयोग करें:

app:layout_behavior="com.your.package.LockableBottomSheetBehavior"

यह सभी उपयोगकर्ता क्रियाओं को अक्षम कर देता है, इसका उपयोग तब किया जा सकता है जब आप केवल प्रोग्रामेटिक रूप से बॉटमशीट को नियंत्रित करना चाहते हैं।


2
यह सबसे अच्छा जवाब है, बॉटमशीटबीहेवियर को निष्क्रिय करने के लिए। ऊपर के एक व्यक्ति ने भी अनुकरणीय समाधान पोस्ट किया था, लेकिन उसने दूसरों की घटना को onTouchEvent () की तरह ओवरराइड करने के लिए नहीं लिखा । दूसरे हाथ में आप अपने जवाब में सुधार कर सकते हैं यदि आप झूठे के
लगाते हैं

3
आप बॉटमशीटफ्रैगमेंट के साथ इसका उपयोग कैसे करते हैं?
user3144836

7
आपको अपने XML में विशेष रूप से इस वर्ग का उल्लेख करना होगा। app: layout_behavior = "com.my.package.UserLockBottomSheetBehavior"
स्टीव

3
कुछ मामलों में, यह अभी भी काम नहीं करता है, अगर हमारे पास नीचे शीट के टुकड़े में एक सूची है, तो यह अभी भी डगमगाता है
दीपक जोशी

1
@DeepakJoshi शायद u RecyclerView का विस्तार कर सकती है और 'hasNestedScrollingParent' जैसे कुछ तरीकों को ओवरराइड कर सकती है, लेकिन मुझे यकीन नहीं है
विटाली ओबाइडिको

74

राज्य की onStateChangedविधि में जाँच करें कि setBottomSheetCallbackक्या राज्य है BottomSheetBehavior.STATE_DRAGGINGतो इसे BottomSheetBehavior.STATE_EXPANDEDइस तरह बदलें कि आप STATE_DRAGGINGउपयोगकर्ता द्वारा रोक सकें । नीचे की तरह

final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            }
        });

नीचे की तरह करीब की शीट खोलने के लिए बटन का उपयोग करें

fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (behavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                } else {
                    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                }
            }
        });

उपयोग न करें setPeekHeightयाapp:behavior_peekHeight

ऊपर से आप अपने लक्ष्य तक पहुँच सकते हैं


1
अच्छी चाल। उस पर ध्यान नहीं दिया। धन्यवाद। और यह भी, क्या आप इसके साथ मदद कर सकते हैं। जब मैं इसे पहले विस्तार करने के लिए कहता हूं, तो यह पारदर्शी है और मैं इसके पीछे का दृश्य देख सकता हूं, लेकिन मैं इसे दृश्यमान बनाने से पहले शीट व्यू में EditText पर टैप करने तक बातचीत नहीं कर सकता।
टॉन्सपी

मैंने अपना बना लिया BottomSheet View match_parentऔर जब भी मैं इसे ऊपर लाने की कोशिश करता हूं तो Activityमुझे लगता है कि यह ऊपर स्लाइड करता है, लेकिन यह तब तक दिखाई नहीं देता जब तक मैं इसमें टैप नहीं EditTextकरता जो ऊपर लाता है Keyboardऔर BottomSheet Viewदृश्यमान
बनाता है

1
मैंने यह कोशिश की, लेकिन राज्यों में समाप्त हो गया STATE_SETTLING। मेरे पास नीचे की शीट को खोलने और बंद करने के लिए एक बटन है, अगर यह हिडेन है, तो मैं इसका विस्तार करता हूं। यदि यह विस्तारित है, तो मैं इसे छिपाता हूं। चूंकि यह SETTLING में फंस गया है, मेरा बटन नीचे की शीट को खींचने के बाद काम नहीं करता है। उस पर कोई विचार?
गोचन अरिक

3
यह समाधान अविश्वसनीय है; नीचे की शीट एक बुरी स्थिति में आ जाती है, जैसा कि गोखान ने कहा था ... और जब वह खराब स्थिति में होता है, तो नीचे की शीट में एक नया टुकड़ा लोड करने जैसे कॉल बस खाली हो जाएंगे।
रे डब्ल्यू

7
यह काम नहीं करेगा यदि आपके पास नीचे की शीट के अंदर नेस्ट्रोक्रोलव्यू है
ऋषभ चंदेल

32

ठीक है, इसलिए स्वीकृत जवाब मेरे काम नहीं आया। हालाँकि, Виталий Обидейко के जवाब ने मेरे अंतिम समाधान को प्रेरित किया।

सबसे पहले, मैंने निम्न कस्टम बॉटमशीटबेहवियर बनाया। यह स्पर्श से जुड़े सभी तरीकों को ओवरराइड करता है, और अगर यह बंद है तो गलत (या कुछ भी नहीं) लौटाता है। अन्यथा, यह एक सामान्य बॉटमशीटबहेवियर की तरह काम करता है। यह उपयोगकर्ता की नीचे खींचने की क्षमता को अक्षम करता है, और कोड में स्थिति को बदलने को प्रभावित नहीं करता है।

LockableBottomSheetBehavior.java

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

    private boolean mLocked = false;

    public LockableBottomSheetBehavior() {}

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

    public void setLocked(boolean locked) {
        mLocked = locked;
    }

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        boolean handled = false;

        if (!mLocked) {
            handled = super.onInterceptTouchEvent(parent, child, event);
        }

        return handled;
    }

    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        boolean handled = false;

        if (!mLocked) {
            handled = super.onTouchEvent(parent, child, event);
        }

        return handled;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
        boolean handled = false;

        if (!mLocked) {
            handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        }

        return handled;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) {
        if (!mLocked) {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        }
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
        if (!mLocked) {
            super.onStopNestedScroll(coordinatorLayout, child, target);
        }
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY) {
        boolean handled = false;

        if (!mLocked) {
            handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
        }

        return handled;

    }
}

इसका उपयोग कैसे करें, इसका एक उदाहरण यहां दिया गया है। मेरे मामले में, मुझे इसकी आवश्यकता थी इसलिए नीचे की शीट को विस्तारित करते समय लॉक किया गया।

activity_home.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|snap"
            app:titleEnabled="false"/>
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>
    </android.support.design.widget.AppBarLayout>

    <!-- Use layout_behavior to set your Behavior-->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_behavior="com.myapppackage.LockableBottomSheetBehavior"/>

</android.support.design.widget.CoordinatorLayout>

HomeActivity.java

public class HomeActivity extends AppCompatActivity {
    BottomSheetBehavior mBottomSheetBehavior;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setAdapter(new SomeAdapter());

        mBottomSheetBehavior = BottomSheetBehavior.from(recyclerView);
        mBottomSheetBehavior.setBottomSheetCallback(new MyBottomSheetCallback());
    }

    class MyBottomSheetCallback extends BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                if (mBottomSheetBehavior instanceof LockableBottomSheetBehavior) {
                    ((LockableBottomSheetBehavior) mBottomSheetBehavior).setLocked(true);
                }
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {}
    });
}

आशा है कि यह बहुत भ्रम को दूर करने में मदद करता है!


1
अच्छा है, यह सबसे अच्छा जवाब है कि हम इन राज्यों में बदलाव से बच सकते हैं जो मिस ईवेंट की ओर ले जाते हैं। धन्यवाद।
Tấn Nguyên

@ नाम - अच्छा जवाब लेकिन अब मैं सेटाइटाइट () नहीं कर पा रहा हूं। कोई उपाय?
आदर्श यादव

मैंने यह कोशिश की। इससे मेरा काम बनता है। मेरी गांड को बचाने के लिए धन्यवाद भाई
Sup.Ia

1
यह एक अच्छा समाधान है, हालाँकि यह आज तक अपडेट नहीं किया गया है। OnNestedPreScroll और कुछ अन्य तरीकों को हटा दिया गया है। उन तरीकों को अद्यतन करने की आवश्यकता है और यह ठीक काम करता है।
अजय

4
हैलो, यह एक BottomSheetDialogFragment पर नहीं काम करता है, मैं अभी भी bottomsheet खींच सकते हैं
फ्लोरियन-करते

23

मैंने डायनेमिक रूप से अक्षम उपयोगकर्ता को खींचने के इस उपयोग के मामले को संबोधित करने के लिए एक वर्कअराउंड लिखना समाप्त कर दिया है, जिससे बॉटमशीटबाइहाइवर को InInceptceptTouchEvent को ओवरराइड करने के लिए उप-वर्गित किया गया है, और कस्टम फ्लैग (इस मामले में mAllowUserDragging) को गलत पर सेट करने पर इसे अनदेखा किया जाता है:

import android.content.Context;
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 WABottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
    private boolean mAllowUserDragging = true;
    /**
     * Default constructor for instantiating BottomSheetBehaviors.
     */
    public WABottomSheetBehavior() {
        super();
    }

    /**
     * Default constructor for inflating BottomSheetBehaviors from layout.
     *
     * @param context The {@link Context}.
     * @param attrs   The {@link AttributeSet}.
     */
    public WABottomSheetBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setAllowUserDragging(boolean allowUserDragging) {
        mAllowUserDragging = allowUserDragging;
    }

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        if (!mAllowUserDragging) {
            return false;
        }
        return super.onInterceptTouchEvent(parent, child, event);
    }
}

और अपने लेआउट में xml:

    <FrameLayout
        android:id="@+id/bottom_sheet_frag_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:behavior_hideable="true"
        app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
        app:elevation="@dimen/bottom_sheet_elevation"
        app:layout_behavior="com.example.ray.WABottomSheetBehavior" />

अब तक, यह डिमांड पर बॉटम शीट पर उपयोगकर्ता को खींचने में अक्षम करने के लिए सबसे लगातार व्यवहार करने वाला समाधान है।

अन्य सभी समाधान जो onStateChanged कॉलबैक में एक अन्य सेटस्टैट कॉल को फायर करने पर निर्भर करते थे, उसके परिणामस्वरूप बॉटमशीट खराब स्थिति में आ गई, या महत्वपूर्ण UX समस्याएँ (रनस्टेट कॉल को रननेबल में पोस्ट करने के मामले में) का कारण बनती हैं।

आशा है कि यह किसी की मदद करता है :)

रे


4
यह बहुत साफ है
ओडीस

3
फ्रेमवर्क के बजाय @BeeingJk, NestedScrollView का उपयोग करें, और सेट करेंbottomSheetFragContainer.setNestedScrollingEnabled(false);
AfzalivE

1
SOLVED: कॉलबैक समन्वयकलेयआउट
LOG_TAG

3
यह मेरे लिए नहीं जागता है! पुनश्च: मेरे पास बॉटमशीट में एक स्क्रॉल करने योग्य पाठ है
थोरवाल्ड ओलावेंस

6
आरंभीकरण के दौरान आपने इसे कैसे डाला? यह मुझे चेतावनी देता है WABottomSheetBehavior <दृश्य> व्यवहार = (WABottomSheetBehavior) BottomSheetBehavior.from (sheetView);
लियो डायरोडकर

8

देर से जवाब, लेकिन, यह वही है जो मेरे लिए काम करता है, जो कि दूसरों ने जो सुझाव दिया है उससे थोड़ा अलग है।

आप cancelableसंपत्ति को असत्य पर सेट करने का प्रयास कर सकते हैं, अर्थात

setCancelable(false);

और फिर मैन्युअल रूप से उन घटनाओं को संभालना जहां आप संवाद को setupDialogविधि में खारिज करना चाहते हैं ।

@Override
public void setupDialog(final Dialog dialog, final int style) {

    // handle back button
    dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(final DialogInterface dialog, final int keyCode, final KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                dialog.dismiss();
            }
            return true;
        }
    });

    // handle touching outside of the dialog
    final View touchOutsideView = getDialog().getWindow().getDecorView().findViewById(android.support.design.R.id.touch_outside);
    touchOutsideView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            dialog.dismiss();
        }
    });
}

यह संवाद खंड के अंदर एक सूची दृश्य के साथ काम करता है, जो कि मैं अन्य समाधानों के साथ थोड़ा अटक रहा था।


अच्छा संक्षिप्त समाधान। इसे पढ़ने वाले किसी व्यक्ति के लिए, आप (संभवतः) संवाद को खारिज करने से पहले event.isCanceled()और event.getAction() == MotionEvent.ACTION_UPउसके लिए अतिरिक्त जांच चाहते हैं - इससे गलत क्लिकों को खारिज करने से रोका जा सकेगा।
एरिक बछुबर

इसके लिए धन्यवाद। यह ड्रैगिंग को डिसेबल करने का सबसे सरल उपाय है।
AVJ

7

स्वीकृत उत्तर मेरे द्वारा उपयोग किए जाने वाले पहले परीक्षण उपकरण पर काम नहीं करता है। और उछाल वापस चिकनी नहीं है। उपयोगकर्ता द्वारा ड्रैगिंग जारी करने के बाद ही स्टेट को STATE_EXPANDED पर सेट करना बेहतर लगता है। निम्नलिखित मेरा संस्करण है:

    final BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheet));
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState > BottomSheetBehavior.STATE_DRAGGING)
                bottomSheet.post(new Runnable() {
                    @Override public void run() {
                        behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                    }
                });
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        }
    });

1
जब तक आप चाहते हैं, तब तक आप इसे एक बेकार में फेंकने के साथ समस्या बता सकते हैं। आप इसे एक बटन के साथ खारिज नहीं कर सकते क्योंकि, इसे खारिज करने के लिए खींचने की आवश्यकता है। और, यह हमेशा खींचने पर प्रतिक्रिया देगा, बस यह कि यह उपयोगकर्ता को बर्खास्तगी को रोकने से रोक देगा
Tonespy

7

इस कोड को bottomSheetBehavior ऑब्जेक्ट में जोड़ें । खींचने को अक्षम कर दिया जाएगा। मेरे लिए ठीक काम करता है।

final BottomSheetBehavior behavior = BottomSheetBehavior.from((View) view.getParent());
    behavior.setHideable(false);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {

      @Override
      public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if (newState == BottomSheetBehavior.STATE_DRAGGING) {
          behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        }

      }
      @Override
      public void onSlide(@NonNull View bottomSheet, float slideOffset) {

      }
});

1
यह स्वाइप करना अक्षम नहीं करता है। यह नीचे की चादर को पूरी तरह से ध्वस्त कर देता है।
एडम हर्विट्ज

7

अपेक्षित् व्यवहार:

  • बॉटमशीट ड्रैग-डाउन पर बंद नहीं होती है
  • बॉटमशीट बंद हो जाती है अगर संवाद विंडो के बाहर स्पर्श किया जाता है

कोड:

class MyBottomSheet : BottomSheetDialogFragment () {

   override fun onActivityCreated(savedInstanceState: Bundle?) {
       super.onActivityCreated(savedInstanceState)
       disableBottomSheetDraggableBehavior()
   }

   private fun disableBottomSheetDraggableBehavior() {
      this.isCancelable = false
      this.dialog?.setCanceledOnTouchOutside(true)
   }

 }

किसी कारण से, मैं संवाद को बाहर छूने से बंद नहीं कर सकता, लेकिन यह ड्रैग को निष्क्रिय करने का काम करता है
गैस्टोन सेलेन

5

बॉटमशीट को लॉक करने और उपयोगकर्ता को इसे स्वाइप करने से बचने के लिए मैंने यही किया

public void showBottomSheet() {
    bsb.setHideable(false);
    bsb.setState(BottomSheetBehavior.STATE_EXPANDED);
}

public void hideBottomSheet() {
    bsb.setHideable(true);
    bsb.setState(BottomSheetBehavior.STATE_COLLAPSED);
}

यह मेरे लिए काफी अच्छा काम करता है।


यह समाधान अपील कर रहा था लेकिन विचित्र रूप से नीचे की शीट को नीचे के बजाय स्क्रीन के ऊपर से दिखाई देता है! हालांकि यह सामान्य तरीके से गायब हो जाता है। यह बहुत स्टार ट्रेक है।
तुंगा

मुझे एक दृष्टि संशोधन करने और इसके बजाय उपयोग करने की आवश्यकता थी BottomSheetBehavior.STATE_HIDDEN। ऐसे में आपको फोन भी नहीं करना चाहिए setPeekHeight()। यह यहां अन्य समाधानों की तुलना में बहुत कम जटिल है।
पवित्रसमोसा

4

ड्रैगिंग को लॉक करने का आसान तरीका दृश्य ऊंचाई के समान सेटेकाइट है। उदाहरण के लिए:

private LinearLayout bottomSheet;
private BottomSheetBehavior bottomBehavior;

@Override
public void onResume() {
    super.onResume();
    bottomBehavior = BottomSheetBehavior.from((bottomSheet);
    bottomBehavior.setPeekHeight(bottomSheet.getHeight());
    bottomBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}

4

बॉटमशीटडायलॉगफ्रैगमेंट के साथ एक नमूना। यह पूरी तरह से काम करता है।

संपादित करें 09/04/2020: केsetBottomSheetCallback() साथ पुन: प्रतिस्थापित मूल्यaddBottomSheetCallback()

class FragMenuBDrawer : BottomSheetDialogFragment() {

    ...

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog

        dialog.setOnShowListener {
            val bottomSheet = (it as BottomSheetDialog).findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout?
            val behavior = BottomSheetBehavior.from(bottomSheet!!)
            behavior.state = BottomSheetBehavior.STATE_EXPANDED

            behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                        behavior.state = BottomSheetBehavior.STATE_EXPANDED
                    }
                }

                override fun onSlide(bottomSheet: View, slideOffset: Float) {}
            })
        }

        // Do something with your dialog like setContentView() or whatever
        return dialog
    }

    ...
}

3

जब नीचे की शीट अक्षम हो जाए तो आपको सभी घटनाओं को ब्लॉक करने की आवश्यकता नहीं है। आप केवल ACTION_MOVE ईवेंट ब्लॉक कर सकते हैं। इसीलिए इस तरह से कस्टम बॉटम शीट व्यवहार का उपयोग करें

public class BottomSheetBehaviorWithDisabledState<V extends View> extends BottomSheetBehavior<V> {
    private boolean enable = true;

    /**
     * Default constructor for instantiating BottomSheetBehaviors.
     */
    public BottomSheetBehaviorWithDisabledState() {
        super();
    }

    /**
     * Default constructor for inflating BottomSheetBehaviors from layout.
     *
     * @param context The {@link Context}.
     * @param attrs   The {@link AttributeSet}.
     */
    public BottomSheetBehaviorWithDisabledState(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setEnable(boolean enable){
        this.enable = enable;
    }

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        if (!enable && event.getAction() == MotionEvent.ACTION_MOVE){
            return false;
        }
        return super.onInterceptTouchEvent(parent, child, event);
    }
}

आप इस वर्ग का उपयोग कैसे करते हैं? मुझे एक IllegalArgumentException मिल रही है: यह दृश्य बॉटमशीट के साथ नहीं जुड़ा है। व्यवहार
user3144836

3

यहाँ कोटलिन में शीर्ष समाधान का एक कार्यशील संस्करण है:

import android.support.design.widget.BottomSheetBehavior
import android.support.design.widget.CoordinatorLayout
import android.view.MotionEvent
import android.view.View

class CustomBottomSheetBehavior<V : View> : BottomSheetBehavior<V>() {

    @Suppress("UNCHECKED_CAST")
    companion object {
        fun <V : View> from(view: V): CustomBottomSheetBehavior<V> {
            val params = view.layoutParams as? CoordinatorLayout.LayoutParams ?:
                throw IllegalArgumentException("The view is not a child of CoordinatorLayout")
                params.behavior as? BottomSheetBehavior<V> ?:
                    throw IllegalArgumentException("The view is not associated with BottomSheetBehavior")
                params.behavior = CustomBottomSheetBehavior<V>()
            return params.behavior as CustomBottomSheetBehavior<V>
        }
    }

    override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
        return false
    }

    override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
        return false
    }

    override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int): Boolean {
        return false
    }

    override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {}

    override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) {}

    override fun onNestedPreFling(coordinatorLayout: CoordinatorLayout, child: V, target: View, velocityX: Float, velocityY: Float): Boolean {
        return false
    }
}

फिर जब भी आप उपयोग करना चाहते हैं:

val bottomSheetBehavior by lazy {
    CustomBottomSheetBehavior.from(bottom_sheet_main)
}

bottom_sheet_mainका उपयोग करते हुए वास्तविक दृश्य है Kotlin एंड्रॉयड एक्सटेंशन


3

निचला सेट करें onClickListener को शून्य करने के लिए।

bottomSheet.setOnClickListener(null);

यह पंक्ति केवल बॉटमशीट के बारे में सभी कार्रवाई को अक्षम करती है और आंतरिक दृश्य पर प्रभाव नहीं डालती है।


1
यह अनपेक्षित एनीमेशन का कारण बनता है जब बॉटम शीट को बंद करने का प्रयास किया जाता है।
एडम हर्विट्ज

3
implementation 'com.google.android.material:material:1.2.0-alpha05'

आप इस तरह से बॉटमशीट को ड्रैग कर सकते हैं।

import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED

//another code

this.bottomSheetBehavior = BottomSheetBehavior.from(view)
this.bottomSheetBehavior.state = STATE_EXPANDED
this.bottomSheetBehavior.isDraggable = false // disable dragging

//another code
this.bottomSheetbehavior.isDraggable = true //draggable

(kotlin), मुझे उम्मीद है कि यह उत्तर आपके मुद्दे को हल कर सकता है।


1
ये अल्फा संस्करण पागलपन से व्यवहार करता है। मैं अनुशंसा नहीं करता :(
एडम स्टायरक 10

2

मुझे अद्भुत समाधान मिला है। प्रारंभिक समस्या एक बार बॉटमशीट हिडेन स्टेट में जा रही थी तब यह बॉटमशीटडॉगलॉग.शो () पर दिखाई नहीं दे रहा था। लेकिन मैं शो () विधि पर संवाद को प्राप्त करना चाहता था और उपयोगकर्ता को इसे नीचे स्वाइप करने में सक्षम करना चाहता था ताकि यह नीचे की शीट जैसा महसूस हो। नीचे मैंने क्या किया है ..

    BottomSheetDialog itemTypeDialog = new BottomSheetDialog(this);
    View bottomSheetView = getLayoutInflater().inflate(R.layout.dialog_bottomsheet, null);
    itemTypeDialog.setContentView(bottomSheetView);
    BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from((View) bottomSheetView.getParent());
    bottomSheetBehavior.setBottomSheetCallback(bottomSheetCallback); // You can also attach the listener here itself.

    BottomSheetBehavior.BottomSheetCallback bottomSheetCallback =  new BottomSheetBehavior.BottomSheetCallback() {
    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        Log.d(TAG, "BottomSheetCallback: " + newState);
        if (newState == BottomSheetBehavior.STATE_HIDDEN) {
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            itemTypeDialog.dismiss();
        } 
    }

    @Override
    public void onSlide(@NonNull View bottomSheet, float slideOffset) {

    }
};

यह एक सटीक जवाब है
विवेक कुमार श्रीवास्तव

2
  1. BottomSheetDialogअपनी परियोजना की प्रतिलिपि बनाएँ और उसका नाम बदलेंMyBottomSheetDialog
  2. जोड़ने getBottomSheetBehaviorके लिएMyBottomSheetDialog
  3. उपयोग MyBottomSheetDialogइसके बजाय काBottomSheetDialog
  4. bottomSheetBehavior.setBottomSheetCallback

इस तरह कोड

public class MyBottomSheetDialog extends AppCompatDialog {

    // some code

    public BottomSheetBehavior<FrameLayout> getBottomSheetBehavior() {
        return mBehavior;
    }

    // more code

आपके कोड में

    final BottomSheetBehavior<FrameLayout> bottomSheetBehavior = myBottomSheetDialog.getBottomSheetBehavior();
    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {

        }

2

यह मूल रूप से शीर्ष पर सही उत्तर का कोटलिन संस्करण है:

    class LockedBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) :
        BottomSheetBehavior<V>(context, attrs) {

    companion object {
        fun <V : View> from(view: V): LockedBottomSheetBehavior<*> {
            val params = view.layoutParams as? CoordinatorLayout.LayoutParams
                    ?: throw IllegalArgumentException("The view is not a child of CoordinatorLayout")
            return params.behavior as? LockedBottomSheetBehavior<*>
                    ?: throw IllegalArgumentException(
                            "The view is not associated with BottomSheetBehavior")
        }
    }

    override fun onInterceptTouchEvent(
            parent: CoordinatorLayout,
            child: V, event: MotionEvent
    ) = false

    override fun onTouchEvent(
            parent: CoordinatorLayout,
            child: V,
            event: MotionEvent
    ) = false

    override fun onStartNestedScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            directTargetChild: View,
            target: View,
            axes: Int,
            type: Int) = false

    override fun onNestedPreScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            dx: Int,
            dy: Int,
            consumed: IntArray,
            type: Int) {
    }

    override fun onStopNestedScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            type: Int) {
    }

    override fun onNestedPreFling(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            velocityX: Float,
            velocityY: Float
    ) = false
}

आप इस वर्ग का उपयोग कैसे करते हैं? मुझे एक IllegalArgumentException मिल रही है: यह दृश्य बॉटमशीट के साथ नहीं जुड़ा है। व्यवहार
user3144836

1
app: layout_behavior = "UserLockBottomSheetBehavior"> xml में और फिर कोड में आप निम्न कार्य करते हैं। // नीचे शीट दृश्य प्राप्त करें LinearLayout llBottomSheet = (LinearLayout) findViewById (R.id.bottom_sheet); // इनविट बॉटम शीट बिहेवियर बॉटमशीटबहेवियर बॉटमशीटबहेवियर = बॉटमशीटबेहेवियर.फ्रॉम (llBottomSheet);
जमाल

1

इसे इस्तेमाल करे।

1) नीचे की शीट बनाएं और अपने जावा वर्ग में चर की तरह घोषित करें

private BottomSheetBehavior sheetBehavior;

2) sheetBehavior = BottomSheetBehavior.from(bottomSheet);

3) नीचे की शीट कॉलबैक फ़ंक्शन में निम्न पंक्तियाँ जोड़ें।

sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                switch (newState) {
                    case BottomSheetBehavior.STATE_HIDDEN:
                        Log.d(TAG, "--------------  STATE_HIDDEN");
                        break;
                    case BottomSheetBehavior.STATE_EXPANDED: {
                        Log.d(TAG, "--------------  STATE_EXPANDED");
                    }
                    break;
                    case BottomSheetBehavior.STATE_COLLAPSED: {
                        Log.d(TAG, "--------------  STATE_COLLAPSED");
                    }
                    break;
                    case BottomSheetBehavior.STATE_DRAGGING:
                        sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                        break;
                    case BottomSheetBehavior.STATE_SETTLING:
                        Log.d(TAG, "--------------  STATE_SETTLING");
                        break;
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });

1

सबसे पहले, मैं सिर्फ आप सभी को धन्यवाद देना चाहता हूं जिन्होंने जवाब देने की कोशिश की। मैं सिर्फ इस समस्या को हल करके यह उत्तर लिख रहा हूं जैसा मैं चाहता हूं। मैं वर्णन करने जा रहा हूं कि मैं कैसे यहां से मदद लेकर कदम से कदम मिलाता हूं।

विज़ुअलाइज़ेशन: बटन पर क्लिक करने के बाद Show BottomSheetआपको दूसरी स्क्रीन दिखाई देगी । अब आप देखेंगे कि बॉटमशीट सिर्फ खींचने के लिए बंद है । लेकिन अगर आप कंट्री लिस्ट पर क्लिक करेंगे तो बॉटमशीट छिप जाएगी। यह विवरण था अब कोड में खुदाई करते हैं।

  • सबसे पहले, अपने build.gradle फ़ाइल में डिज़ाइन समर्थन लाइब्रेरी जोड़ें :

    कार्यान्वयन 'com.android.support:design:28.0.0'

  • UserLockBottomSheetBehavior.java : क्रेडिट: जेम्स डेविस (धन्यवाद आदमी)

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

    public UserLockBottomSheetBehavior() {
        super();
    }

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

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        return false;
    }

    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
        return false;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
        return false;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) {
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY) {
        return false;
    }

}
  • bottomsheet.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bottomSheet"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:layout_behavior="com.samsolution.custombottomsheet.UserLockBottomSheetBehavior">

 <RelativeLayout
     android:id="@+id/minimizeLayout"
     android:background="@color/colorPrimary"
     android:layout_width="match_parent"
     android:layout_height="?android:attr/actionBarSize">

     <TextView
         android:layout_centerHorizontal="true"
         android:padding="16dp"
         android:layout_width="wrap_content"
         android:layout_height="?android:attr/actionBarSize"
         android:gravity="center_horizontal|center"
         android:text="Country List"
         android:textColor="#FFFFFF"
         android:textStyle="bold" />
 </RelativeLayout>

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ListView
            android:id="@+id/homeCountryList"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </android.support.v7.widget.CardView>

</LinearLayout>
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center"
        android:onClick="showCountryListFromBottomSheet">

        <Button
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_light"
            android:onClick="showCountryListFromBottomSheet"
            android:padding="16dp"
            android:text="Show BottomSheet"
            android:textAllCaps="false"
            android:textColor="#ffffff" />

    </LinearLayout>

    <include layout="@layout/bootomsheet" />

</android.support.design.widget.CoordinatorLayout>
  • MainActivity.java
public class MainActivity extends AppCompatActivity {

    private BottomSheetBehavior<LinearLayout> bottomSheetBehavior;                                  // BottomSheet Instance
    LinearLayout bottomsheetlayout;
    String[] list = {"A", "B", "C", "D", "A", "B", "C", "D","A", "B", "C", "D","A", "B", "C", "D","A", "B", "C", "D"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomsheetlayout = findViewById(R.id.bottomSheet);
        bottomSheetBehavior = BottomSheetBehavior.from(bottomsheetlayout);

        ListView listView = findViewById(R.id.homeCountryList);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,list);
        listView.setAdapter(adapter);

        bottomSheetHide();                                                                          //BottomSheet get hide first time

        RelativeLayout minimizeLayoutIV;                                                            // It will hide the bottomSheet Layout
        minimizeLayoutIV = findViewById(R.id.minimizeLayout);
        minimizeLayoutIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               bottomSheetHide();
            }
        });
    }

    public void showCountryListFromBottomSheet(View view) {
        bottomSheetBehavior.setHideable(false);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    }

    public void bottomSheetHide(){
        bottomSheetBehavior.setHideable(true);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
    }
}

पहली स्क्रीन दूसरी स्क्रीन


1

स्वीकृत उत्तर से समाधान ज्यादातर मेरे लिए काम करता था, लेकिन एक मुद्दे के साथ: दृश्य, जो नीचे शीट दृश्य के पीछे हैं, स्पर्श घटनाओं पर प्रतिक्रिया करना शुरू कर दिया, अगर स्पर्श घटना नीचे की शीट के क्षेत्र पर हो रही है, जो कि बच्चे के विचारों से मुक्त है। दूसरे शब्दों में, जैसा कि आप नीचे दी गई छवि में देख सकते हैं, जब उपयोगकर्ता नीचे की शीट के अंदर उंगली स्लाइड करता है, तो मैप उस पर प्रतिक्रिया करना शुरू कर देता है।

नीचे की चादर स्पर्श क्षेत्र

समस्या को ठीक करने के लिए, मैंने नीचे शीट दृश्य पर onInterceptTouchEventसेट करके विधि संशोधित की है touchListener(बाकी कोड स्वीकृत समाधान के समान है)।

override fun onInterceptTouchEvent(
        parent: CoordinatorLayout,
        child: V, event: MotionEvent
    ): Boolean {
        child.setOnTouchListener { v, event ->
            true
        }
        return false
    }

1

साथ में 'com.google.android.material:material:1.2.0-alpha06'

NestedScrollViewऔर के साथ महान काम करता हैRecyclerView

उदाहरण कोड:

    LinearLayout contentLayout = findViewById(R.id.contentLayout);
    sheetBehavior = BottomSheetBehavior.from(contentLayout);
    sheetBehavior.setDraggable(false);

0

peakHeightमेरे लिए काम किया मूल्य समायोजित करना ।

यदि यह विस्तारित है, तो मैं पीक की ऊंचाई को बॉटमशीट की तरह निर्धारित करता हूं।

    private val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
    override fun onSlide(bottomSheet: View, slideOffset: Float) {

    }

    override fun onStateChanged(bottomSheet: View, newState: Int) {
        if (newState == BottomSheetBehavior.STATE_EXPANDED)
            bottomSheetBehavior.peekHeight = bottomSheet.height
    }
}

1
यह आदर्श नहीं है क्योंकि यह अप्रत्याशित एनिमेशन पैदा कर सकता है।
एडम हर्विट्ज

मेरे मामले में। यह किसी भी एनिमेशन मुद्दे का कारण नहीं बना। यह कार्ड के विस्तार के बाद बस नहीं चलता है। यह आदर्श नहीं है, लेकिन यह उम्मीद के मुताबिक काम किया है!
pz64_

दिलचस्प है, यह मामला हो सकता है। मैंने अपने बॉटम शीट को अप्रत्याशित रूप से CollapsingToolbarLayout के टूलबार को इनविजिबल या गोन पर सेट करके अनपेक्षित रूप से बंद कर दिया था, जब बॉटम शीट खुली होती है। टूलबार से संबंधित एक स्पर्श बातचीत, भले ही वह नीचे थी, नीचे की शीट को अप्रत्याशित रूप से बंद करने का कारण बन रही थी। मुद्दा अब तय हो गया है।
एडम हर्वित्ज

0
    LayoutInflater inflater = LayoutInflater.from(context);
            View view = inflater.inflate(R.layout.bottomsheet_view_profile_image, null);
            BottomSheetDialog dialog = new BottomSheetDialog(context);
            dialog.setContentView(view);
            dialog.setCancelable(false);


            BottomSheetBehavior behavior = BottomSheetBehavior
                    .from(((View) view.getParent()));
            behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                @Override
                public void onStateChanged(@NonNull View bottomSheet, int newState) {
                    if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                        behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                    }
                }

                @Override
                public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                }
            });
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            behavior.setSkipCollapsed(true);
            dialog.show();

0

यह Google में पहला परिणाम है, इसलिए मेरा मानना ​​है कि इसका एकमात्र समाधान यहां सरल समाधान डालना है:

   private fun disableDragToDismiss() {
    if (dialog is BottomSheetDialog) {
        val bsDialog = dialog as BottomSheetDialog
        bsDialog.behavior.isHideable = false
    } else {
        Log.d(TAG, " BottomSheetDialog with dialog that is not BottomSheetDialog")
    }
}

और बस से इसे कहते से onCreateView()में BottomSheetDialogFragmentकार्यान्वयन


0

मैं में एक ही मुद्दा है BottomSheetDialogFragmentऔर का उपयोग कर कई समाधान लागू behaviorकी dialog, लेकिन उन में से कोई भी मेरी समस्या का समाधान हो और उसके बाद मैं इसे लेकिन सेटिंग हल setCancelable(false);के प्रारंभ के समय में dialog

DialogEndRide dialogCompleteRide = new DialogEndRide();
dialogCompleteRide.setCancelable(false);
dialogCompleteRide.show(getChildFragmentManager(), "");

यह इशारे को अक्षम कर देगा BottomSheetDialogFragmentऔर आप फ़ंक्शन dialogका उपयोग करके प्रोग्रामेटिक रूप से खारिज कर सकते हैं dismiss();


-1

मेरे पास एक ही मुद्दा था, मैंने इसे कोड द्वारा हल किया। यह उपयोगकर्ता को बॉटमशीट को खींचने की अनुमति नहीं देगा। आपको राज्य को प्रोग्रामेटिक रूप से संभालने की आवश्यकता है।

 mBottomSheetBehavior.isDraggable = false

-2

बस उपयोग करें: bottomSheet.dismissOnDraggingDownSheet = false

Material.io वेबसाइट से कॉपी किया गया:

let viewController: ViewController = ViewController() let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)

// **** यह रेखा नीचे की ओर खींचकर खारिज करने से रोकता है ****

bottomSheet.dismissOnDraggingDownSheet = false

present(bottomSheet, animated: true, completion: nil)


यह यहाँ iOS के लिए नहीं है
बैक पैकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.