6
votes

Comment autoriser le contact extérieur pour BottomSheetDialog?

Je travaille sur BottomSheetDialogFragment mon exigence est de créer le menu du bas, Où si je clique en dehors de la zone de fragment , cela ne doit pas annuler la boîte de dialogue et doit persister.

PROBLÈME: Et l'événement en dehors du fragment doit se propager vers la vue / le fragment inférieur.

J'ai déjà essayé ci-dessous (ne fonctionne pas pour BottomDialogFragment): Autoriser le toucher extérieur pour DialogFragment

Pour arrêter la boîte de dialogue, annuler i essayé ci-dessous (j'appelle setCancelable (boolean) dans onStart () de BottomDialogFragment):

@Override
    public void setCancelable(boolean cancelable) {
        super.setCancelable(cancelable);

        BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
        dialog.setCanceledOnTouchOutside(cancelable);

        View bottomSheetView = dialog.getWindow().getDecorView().findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior.from(bottomSheetView).setHideable(cancelable);
    }

référence

EDIT: Je l'ai trouvé à la dure, il n'y a pas d'autre solution que d'utiliser la disposition des coordonnées. La meilleure solution pour BottomSheetDialog est ici

  • Cette solution résout le problème, mais en apporte une plus de problème. c'est-à-dire que tous les événements actionMode ne sont pas parcourus alors que tous les autres événements d'application le sont.
  • Et c'est ma meilleure solution au problème


3 commentaires

Est-ce que [ce lien] [1] vous aide? [1]: medium.com/@betakuang/…


@StavroXhardha J'ai déjà essayé cela, cela me permet d'arrêter l'annulation de Dialog mais les événements sont également bloqués pour les vues ci-dessous.


J'ai trouvé la solution et appliqué dans ce projet de démonstration github.com/andor201995/PersistIt


5 Réponses :


-1
votes

essayez ceci

setCanceledOnTouchOutside(false);


0 commentaires

5
votes

Essayez le code ci-dessous dans votre BottomSheetDialog:

 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
     return (super.onCreateDialog(savedInstanceState) as BottomSheetDialog).apply {
         setCanceledOnTouchOutside(false)
     }
 }

ou encapsulez par par exemple votre et implémentez et attachez-le à BottomSheetBehavior.


5 commentaires

Bonjour, j'ai essayé cela, mais lorsque je clique en dehors de la vue, la boîte de dialogue n'est pas annulée mais en même temps, tous les événements sont bloqués, ce que je veux pour une vue inférieure. Je veux savoir un moyen de faire baisser la visibilité des événements. Merci pour votre réponse.


essayez de ne pas utiliser une boîte de dialogue. incluez simplement et attachez-le à BottomSheetBehavior , cela fonctionnera bien.


Pour cela, je pense que je suis obligé d'utiliser la disposition des coordonnées en tant que racine afin d'ajouter BottomSheetBehavior en tant que layout_behaviour.Mais j'essayais juste de savoir si je peux utiliser le dialogue et contourner la région tactile extérieure.


hmm, essayez de désactiver dim et appliquez dans styles certains attributs. Peut-être sera utile


Je pense que vous devez juste envelopper par par exemple votre et implémenter et attacher à BottomSheetBehavior .



2
votes

Cela n'est possible que lorsque vous utilisez BottomSheetDialogFragment . BottomSheetDialogFragment est une boîte de dialogue et en tant que comportement de chaque boîte de dialogue, elle n'autorise pas l'interception de l'utilisateur sur une vue derrière la boîte de dialogue, bien que cela soit visible par l'utilisateur.

Pour y parvenir, vous devez utiliser Fragment au lieu de BottomSheetDialogFragment . Et oui, cela nécessitera beaucoup de changements de code :) et vous devez vivre sans BottomSheetDialogFragment si vous voulez intercepter les vues derrière.


2 commentaires

Le problème majeur est (en utilisant Fragment) est que mon application / activité n'utilise pas Ajuster le redimensionnement mais, selon les exigences, le menu du bas doit se déplacer vers le haut si le clavier est affiché (exemple). les appels de redimensionnement du système.Je ne peux pas implémenter le même comportement dans MyCustomFragment.Je suis donc enclin à utiliser BottomSheetDialogFragment


Je pense que si c'est la seule tâche qui reste, c'est faisable. Il vous suffit de concevoir la disposition du conteneur comme pour gérer le clavier. vous pouvez consulter code.luasoftware.com/tutorials/android /… ou des fils similaires



2
votes

vous devriez utiliser android.support.design.widget.BottomSheetBehavior .

mais si vous voulez avoir un bottomSheet dans une autre classe, je vous suggère d'utiliser un Fragment et dans ce fragment ouvrez votre bottomSheet

ouvrez votre fragment de cette manière .

Et dans votre fragment, ouvrez votre bottomSheet dans le code suivant:

dans onInitViews

<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:layoutDirection="ltr">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/bottomSheetCoordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:behavior_hideable="true"
        app:behavior_peekHeight="55dp"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/top_radius_primary_color"
            android:paddingStart="@dimen/material_size_32"
            android:paddingEnd="@dimen/material_size_32">

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

Et votre mise en page devrait être comme ceci:

var mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetCoordinatorLayout)
mBottomSheetBehavior!!.state = BottomSheetBehavior.STATE_HIDDEN

mBottomSheetBehavior!!.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
     override fun onStateChanged(bottomSheet: View, newState: Int) {
          when (newState) {
             BottomSheetBehavior.STATE_HIDDEN -> {
                  fragmentManager?.popBackStack()
             }
             //BottomSheetBehavior.STATE_COLLAPSED -> "Collapsed"
             //BottomSheetBehavior.STATE_DRAGGING -> "Dragging..."
             //BottomSheetBehavior.STATE_EXPANDED -> "Expanded"
             //BottomSheetBehavior.STATE_SETTLING -> "Settling..."
           }
      }

      override fun onSlide(bottomSheet: View, slideOffset: Float) {
          //text_view_state!!.text = "Sliding..."
      }
})


1 commentaires

github.com/andor201995/PersistIt il y a d'autres défis si vous utilisez des composants de navigation. t utiliser des transactions fragmentées. Essayez ce projet de démonstration pour une amélioration supplémentaire. Mais la portée de cette question est la bonne réponse.



2
votes

Comme l'a dit Pankaj Kumar, ce n'est pas possible par défaut. Cependant, j'ai trouvé une solution de contournement qui fonctionne et permet de toucher les vues en dehors de la feuille du bas tout en gardant la feuille du bas ouverte

Vous pouvez remplacer la disposition du BottomSheetDialog comme ceci:

valeurs / refs.xml
override fun onStart() {
        super.onStart()

        // Set layout for custom bottom sheet by allowing background touches
        dialog?.window?.apply {
            setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
            
            attributes = attributes.apply {
                gravity = Gravity.BOTTOM
            }
            setDimAmount(0.0f)
        }
    }

layout / custom_design_bottom_sheet_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ This is an override of the design_bottom_sheet_dialog from material library
-->
<FrameLayout
    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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

  <androidx.coordinatorlayout.widget.CoordinatorLayout
      android:id="@+id/coordinator"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

    <View
        android:id="@+id/touch_outside"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:visibility="gone"
        android:importantForAccessibility="no"
        android:soundEffectsEnabled="false"
        tools:ignore="UnusedAttribute"/>

    <FrameLayout
        android:id="@+id/design_bottom_sheet"
        style="?attr/bottomSheetStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|top"
        app:layout_behavior="@string/bottom_sheet_behavior"/>

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

</FrameLayout>


1 commentaires

Finalement! Quelque chose de propre et facile à utiliser. Cela a parfaitement fonctionné pour moi, je suis si heureuse de pouvoir vous embrasser: D! Je vous remercie!!