Angolo arrotondato per BottomSheetDialogFragment


114

ho un BttomSheetDialogFragment personalizzato e voglio avere angoli arrotondati nella parte superiore della vista dal basso

questa è la mia classe personalizzata che gonfia il mio layout che voglio che appaia dal basso

View mView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mView = inflater.inflate(R.layout.charge_layout, container, false);
    initChargeLayoutViews();
    return mView;
}

e ho anche questo file di risorse xml come sfondo:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners android:topRightRadius="35dp"
    android:topLeftRadius="35dp"
    />
<solid android:color="@color/white"/>

<padding android:top="10dp"
    android:bottom="10dp"
    android:right="16dp"
    android:left="16dp"/>

ma il problema è che, quando imposto questo file di risorse come sfondo dell'elemento radice del mio layout, gli angoli non sono ancora arrotondati

e non posso usare il codice seguente:

    this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);

perché ha la priorità sullo sfondo predefinito di BottomSheetDialog e non ci sarà alcun colore grigio semitrasparente sopra la mia vista dal basso


5
@RasoolGhana - Dai un'occhiata a questo link: medium.com/halcyon-mobile/…
Mohit Charadva

Risposte:


238

Crea un disegno personalizzato rounded_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white"/>
    <corners android:topLeftRadius="16dp"
        android:topRightRadius="16dp"/>

</shape>

Quindi ignora bottomSheetDialogThemel' styles.xmlutilizzo del disegnabile come sfondo:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">       
    <item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
</style>

<style name="AppBottomSheetDialogTheme"
    parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/AppModalStyle</item>
</style>

<style name="AppModalStyle"
    parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@drawable/rounded_dialog</item>
</style>

Questo cambierà tutti i BottomSheetDialog della tua app.


2
Per me funziona. Inoltre ho notato che dipende dall'elemento radice del layout. In primo luogo avevo cardview come root (perché ho provato un altro modo per arrotondare gli angoli), poi l'ho cambiato in layout lineare e ora funziona perfettamente
Ivan Shafran

1
Si blocca su Android api 17
Morteza Rastgoo,

1
Non userei i nomi rounded_dialog& AppModalStylecon uno sfondo in cui solo gli angoli superiori sono arrotondati, poiché ti aspetteresti di utilizzare uno sfondo del genere solo con uno stile di foglio inferiore. Che ne dici di bottomsheet_rounded_background&AppBottomSheetStyle
hmac

3
Nota se specifichi uno sfondo nella vista root, questo sovrascriverà questa impostazione
hmac

2
assicurati di non avere alcuno sfondo sull'elemento radice del layout del tuo foglio!
MMK

81

Con la nuova libreria Material Component puoi personalizzare la forma del tuo componente utilizzando l' shapeAppearanceOverlayattributo nel tuo stile ( Nota: richiede la versione 1.1.0 )

Basta usare l' BottomSheetDialogFragmentoverride del onCreateViewmetodo e quindi definire lo stile personalizzato per le finestre di dialogo del foglio inferiore.

Definisci l' bottomSheetDialogThemeattributo nel styles.xmltema della tua app:

  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.MaterialComponents.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    ....
    <item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
  </style>

Quindi definisci la tua forma preferita con shapeAppearanceOverlay

  <style name="CustomBottomSheetDialog" parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheet</item>
  </style>

  <style name="CustomBottomSheet" parent="Widget.MaterialComponents.BottomSheet">
    <item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
  </style>

  <style name="CustomShapeAppearanceBottomSheetDialog" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">16dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomRight">0dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
  </style>

inserisci qui la descrizione dell'immagine


Puoi ottenere lo stesso comportamento sovrascrivendo questo metodo nel tuo BottomSheetDialogFragment(invece di aggiungere il bottomSheetDialogThemetema della tua app):

@Override public int getTheme() {
    return R.style.CustomBottomSheetDialog;
  }

In questo caso stai usando questo tema Overlay solo nella singola BottomSheetDialogFragmente non in tutte le app.


Nota importante sullo STATO ESPANSO :

Nello stato espanso, BottomSheet ha angoli piatti . Puoi controllare il commento ufficiale nel repository github :

Il nostro team di progettazione è fortemente convinto che gli angoli arrotondati indicano contenuto scorrevole mentre gli angoli piatti indicano che non ci sono contenuti aggiuntivi. In quanto tali, non vogliono che aggiungiamo questa modifica con fitToContents.

Questo comportamento è fornito da BottomSheetBehaviored è impossibile sovrascriverlo.
Tuttavia c'è una soluzione alternativa -> DISCLAIMER: può smettere di funzionare nelle prossime versioni !!

Puoi aggiungere un BottomSheetCallbackin BottomSheetDialogFragment:

  @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);


    ((BottomSheetDialog)dialog).getBehavior().addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {

      @Override public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if (newState == BottomSheetBehavior.STATE_EXPANDED) {
          //In the EXPANDED STATE apply a new MaterialShapeDrawable with rounded cornes
          MaterialShapeDrawable newMaterialShapeDrawable = createMaterialShapeDrawable(bottomSheet);
          ViewCompat.setBackground(bottomSheet, newMaterialShapeDrawable);
        }
      }

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

      }
    });

    return dialog;
  }

  @NotNull private MaterialShapeDrawable createMaterialShapeDrawable(@NonNull View bottomSheet) {
    ShapeAppearanceModel shapeAppearanceModel =

      //Create a ShapeAppearanceModel with the same shapeAppearanceOverlay used in the style
      ShapeAppearanceModel.builder(getContext(), 0, R.style.CustomShapeAppearanceBottomSheetDialog)
        .build();

      //Create a new MaterialShapeDrawable (you can't use the original MaterialShapeDrawable in the BottoSheet)
      MaterialShapeDrawable currentMaterialShapeDrawable = (MaterialShapeDrawable) bottomSheet.getBackground();
      MaterialShapeDrawable newMaterialShapeDrawable = new MaterialShapeDrawable((shapeAppearanceModel));
      //Copy the attributes in the new MaterialShapeDrawable
      newMaterialShapeDrawable.initializeElevationOverlay(getContext());
      newMaterialShapeDrawable.setFillColor(currentMaterialShapeDrawable.getFillColor());
      newMaterialShapeDrawable.setTintList(currentMaterialShapeDrawable.getTintList());
      newMaterialShapeDrawable.setElevation(currentMaterialShapeDrawable.getElevation());
      newMaterialShapeDrawable.setStrokeWidth(currentMaterialShapeDrawable.getStrokeWidth());
      newMaterialShapeDrawable.setStrokeColor(currentMaterialShapeDrawable.getStrokeColor());
      return newMaterialShapeDrawable;
  }

2
@GabrieleMariotti usando questa tecnica, se tocco da qualche parte sul foglio e non viene respinto, gli angoli si animano. Non sono sicuro se sviluppi sui componenti materiali Android, ma se lo sei, sapevi di questo problema? Stavo usando 1.1.0-alpha10, ma ho anche appena controllato beta2. Non sono sicuro se dipenda dalle viste esatte che ho inserito nel foglio o meno.
androidguy

1
Ho segnalato questo problema: issuetracker.google.com/issues/144859239 Se qualcuno ha ulteriori scoperte o soluzioni per il problema, rispondi. Grazie!
androidguy

4
Ricevo questo errore e si blocca su v1.1.0-beta02Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior
hkchakladar

3
Non funziona se la finestra di dialogo del foglio inferiore è espansa. Qualche idea?
José Carlos

4
Questa è stata la risposta perfetta e più recente. Devo contrassegnare questo come risposta
Vikas Acharya il

38

Si BottomSheetDialogsta impostando un colore di sfondo bianco predefinito, ecco perché gli angoli non sono visibili, Per mostrarli è necessario rendere trasparente lo sfondo della finestra di dialogo sovrascrivendo lo stile del file BottomSheetDialog.

Definisci questo stile nel tuo res/values/styles/styles.xml

<style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/bottomSheetStyleWrapper</item>
</style>

<style name="bottomSheetStyleWrapper" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@android:color/transparent</item>
</style>

E imposta questo stile al tuo BottomSheetDialog

View view = getLayoutInflater().inflate(R.layout.chooser_bottom_sheet, null);
BottomSheetDialog dialog = new BottomSheetDialog(this,R.style.BottomSheetDialog); // Style here
dialog.setContentView(view);
dialog.show();

2
Meglio della risposta accettata, perché in questo modo puoi avere sfondi diversi su BottomSheetDialogs diversi
Luca

Ora la curva è visibile, ma un colore trasparente in tutto lo schermo al tocco è visibile solo il colore bianco nella finestra di dialogo in basso @Badr qualsiasi correzione?
Arnold Brown,

Questa è la soluzione che stavo cercando, completamente priva di hack.
Prateek Gupta

26

crea una forma chiamata round_corners_shape

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <corners
        android:topLeftRadius="8dp"
        android:topRightRadius="8dp"/>
    <solid android:color="@color/white"/>

</shape>

definire uno stile

  <style name="AppBottomSheetDialogTheme"
           parent="Theme.Design.Light.BottomSheetDialog">
        <item name="bottomSheetStyle">@style/AppModalStyle</item>
    </style>

    <style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
        <item name="android:background">@drawable/rounded_corners_shape</item>
    </style>

usa questo stile sul tuo BottomSheetDialogFragment personalizzato in questo modo, funzionerà!

 public class CustomDialogFragment extends BottomSheetDialogFragment {
      @Override
      public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NORMAL, R.style. AppBottomSheetDialogTheme);
      }

      ...
    }

Sarebbe utile aggiungere qualche chiarimento insieme al codice.
UditS

Questo è il posto giusto per impostare il tema per Fragments.
DYS

10

Se usi l' ultima versione del componente materiale devi solo sovrascrivere ShapeAppearance.MaterialComponents.LargeComponent(poiché il foglio inferiore usa questa forma) e impostare il valore che desideri come:

 <style name="ShapeAppearance.YourApp.LargeComponent" parent="ShapeAppearance.MaterialComponents.LargeComponent">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSize">12dp</item>
 </style>

Quindi imposta lo stile della tua app:

<item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.YourApp.LargeComponent</item>

La soluzione di Gabriele Mariotti è simile e funziona anche questa ma più semplice.


Rispetto ad altre è una soluzione molto migliore, perché la maggior parte della soluzione disponibile è basata sul set personalizzato disegnabile
d-feverx

1
Sembra bello. Questo vale anche per BottomSheetDialog?
Jaden Gu

1
Nota per tutti: l'utilizzo di questa risposta farà sì che tutti i componenti che utilizzano ShapeAppearance.MaterialComponents.LargeComponentavranno lo stesso cornerSize e la stessa famiglia, non solo il Bottom Sheet. Controlla i tuoi requisiti di stile e decidi se desideri modificare l'aspetto di tutti i componenti o solo dei singoli componenti o widget.
nitinkumarp,

9

La risposta di Koma Yip da un'altra domanda ha funzionato per me, dovresti provarla.

Crea un xml in drawable, ad esempio dialog_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white"/>
    <corners android:radius="30dp" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
</shape>

mettilo nel tuo nodo radice xml del layout:

impostalo come sfondo nel tuo layout xml

android:background="@drawable/dialog_bg"

e in onCreateView()mettere questo:

imposta lo sfondo della finestra di dialogo su trasparente

dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

Questa dovrebbe essere la soluzione giusta perché funziona per tutti i DialogFragments senza saltare attraverso i cerchi.
jssingh

3
Per me, ci sono ancora angoli bianchi dietro i miei angoli arrotondati. Quindi, quando cambio il colore del mio drawable in rosso, il tuo codice funziona correttamente e crea un rettangolo rosso arrotondato, ma dietro c'è ancora un rettangolo bianco predefinito. Il codice "dialog.getWindow (). SetBackgroundDrawable ..." che hai scritto cambia il colore dell'intera area "oscurata" sopra la mia finestra di dialogo, ma ancora una volta manca quei due piccoli angoli. Sai cosa potrebbe causare questo problema?
Nick Dev

Aggiungendo al mio commento sopra, dovrei notare che ho dovuto cambiare il codice in onCreateView () in " getDialog () .getWindow () ..." affinché il mio codice potesse essere eseguito. Forse è per questo che non funziona per me.
Nick Dev

1
@NickDev Pubblica una nuova domanda se pensi che questa soluzione non si applichi al tuo codice e forse troveremo una soluzione.
Variag

@Variag Grazie per averci contattato; In realtà ho trovato una soluzione economica in cui copro la finestra di dialogo modale del foglio inferiore predefinito con un rettangolo dello stesso colore dell'area oscurata dietro di esso. Quindi ho aggiunto un secondo rettangolo con gli angoli arrotondati sopra. Non è l'ideale, ma sembra fantastico! Apprezzo comunque l'aiuto.
Nick Dev

8

Oggi stavo controllando la stessa cosa e sì, avevi ragione riguardo al codice

this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);

questo si applica allo sfondo del frammento, quindi dovresti invece ottenere la vista del foglio inferiore dalla finestra di dialogo e cambiare lo sfondo ecco il codice

 @SuppressLint("RestrictedApi")
    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View rootView = getActivity().getLayoutInflater().inflate(R.layout.view_member_info,null,false);
        unbinder = ButterKnife.bind(this, rootView);
        adjustUIComponents();
        dialog.setContentView(rootView);
        FrameLayout bottomSheet = (FrameLayout) dialog.getWindow().findViewById(android.support.design.R.id.design_bottom_sheet);
        bottomSheet.setBackgroundResource(R.drawable.container_background);
    }

qui il foglio inferiore è la visualizzazione effettiva che desideri modificare.


L'unico modo in cui ho funzionato. A proposito, sto usando in BottomSheetDialogFragmentmodo che la logica sia nel onCreateDialogmetodo
Kirill Starostin

6
  1. Crea una forma disegnabile .. che useremo come sfondo per il foglio inferiore. Fornire il valore appropriato per il raggio dell'angolo superiore sinistro e destro.

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners
            android:topLeftRadius="24dp"
            android:topRightRadius="24dp" />
        <padding android:top="2dp" />
        <solid android:color="@color/white" />
    </shape>
    
  2. Ora crea uno stile per "Frammento di dialogo del foglio inferiore"

    <style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
            <item name="android:background">@drawable/drawable_bottomsheet_background</item>
        </style>
    
        <style name="BaseBottomSheetDialog" parent="@style/Theme.Design.Light.BottomSheetDialog">
            <item name="android:windowIsFloating">false</item>
            <item name="bottomSheetStyle">@style/BottomSheet</item>
        </style>
    
        <style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />
    
  3. Ora crea una classe personalizzata che estenderà BottomSheetDilogFragment, dove fornisci il tuo stile.

    open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
    
        override fun getTheme(): Int = R.style.BottomSheetDialogTheme
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
    
    }
    
  4. Ora usa questa classe ovunque tu voglia avere un foglio inferiore con angoli arrotondati. per esempio

    class BottomSheetSuccess : CustomRoundBottomSheet() {
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(R.layout.bottomsheet_shopcreate_success, container, false)
        }
    
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
        }
    
    } 
    

5

Ha funzionato per me

crea una forma denominata shape_rounded_dialog

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_white" />
<corners
    android:topLeftRadius="16dp"
    android:topRightRadius="16dp" />

aggiungi sotto gli stili

<style name="AppBottomSheetDialogTheme" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheetStyle</item>
</style>

<style name="CustomBottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@drawable/shape_rounded_dialog</item>
</style>

Nella classe DialogFragment, il metodo override getTheme restituisce anche lo stile Yourself.

@Override
public int getTheme() {
    return R.style.AppBottomSheetDialogTheme;
}

4

Questa risposta è solo per il problema di impostare il colore di sfondo Color.TRANSPARENTdopo aver impostato un disegnabile con sfondo arrotondato per il layout.

Nessuna delle risposte ha funzionato per me per impostare il colore di sfondo ad Color.TRANSPARENTeccezione della setupDialog()soluzione di sovrascrittura :

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View contentView = View.inflate(getContext(), 
R.layout.fragment_bottom_sheet, null);
    dialog.setContentView(contentView);
    ...
    ((View) contentView.getParent()).setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
}

MA quello che contentViewhai impostato per il dialogo qui non è quello viewche entri onViewCreated()quando gonfi onCreateView(). Si interrompe il flusso standard, quindi potrebbe causare problemi come non è possibile utilizzare View Bindings- Kotlin Android ExtensionsinonViewCreated()

Quindi aggiusto un po 'per impostare lo sfondo in onActivityCreated():

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    (view?.parent as View).setBackgroundColor(Color.TRANSPARENT)
  }

Spero che questo aiuto che ha avuto lo stesso problema


2

So che questa domanda ha già una risposta accettata. Vorrei documentare i problemi che ho affrontato e come finalmente ho funzionato, quindi è utile per qualcuno in futuro.

In primo luogo, stavo usando Theme.AppCompat.Light.DarkActionBarcome genitore per il nostro AppTheme. Ciò significava che la soluzione di @Gabriele Mariotti continuava a bloccarsi con l'errore Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior. Ho risolto questo problema semplicemente cambiando il genitore in Theme.MaterialComponents.Light.DarkActionBar. Ciò non ha influenzato in alcun modo il nostro tema, ma l'RTE era sparito. Puoi anche risolvere questo problema includendo semplicemente gli elementi richiesti nel tuo stile. Ma non mi sono preoccupato di capire quali stili erano richiesti da BottomSheetBehavior.

In secondo luogo, prova come potrei, ma non sono riuscito a ottenere il layout effettivo del Frame (che era BottomSheetDialogFragment) utilizzato per avere angoli arrotondati. Mi sono reso conto che l'impostazione di questo su un'immagine Drawable ha funzionato ma non con una forma o un file @null. Si è scoperto che era perché quello LinearLayoutche stavo usando aveva uno sfondo definito. Questo sovrascriveva qualsiasi sfondo nello stile. La rimozione di quello alla fine ha portato ad angoli arrotondati.

Inoltre, non avevo bisogno di impostare alcuna forma di sfondo per arrotondare gli angoli. La soluzione di @Gabriele Mariotti ha funzionato non appena ho apportato le modifiche di cui sopra. Tuttavia, per impostare il colore di sfondo come volevo che fosse, ho dovuto sovrascrivere l'elemento "backgroundTint".

PS: sono un nuovo sviluppatore Android e mantengo una vecchia app creata per uso interno nel nostro college. Non ho molta familiarità con il sistema di layout di Android o con la libreria dei materiali. Immagino sia per questo che mi ci sono voluti 3 giorni per capirlo. Spero che questo sia utile a qualcuno in futuro.


1

Aggiungi questi due metodi nella classe BottomsheetDialogFragment.

public void setDialogBorder(Dialog dialog) {
        FrameLayout bottomSheet = (FrameLayout) dialog.getWindow().findViewById(android.support.design.R.id.design_bottom_sheet);
        bottomSheet.setBackground(new ColorDrawable(Color.TRANSPARENT));
        setMargins(bottomSheet, 10, 0, 10, 20);
    }

    private void setMargins(View view, int left, int top, int right, int bottom) {
        if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
            p.setMargins(left, top, right, bottom);
            view.requestLayout();
        }
    }

Ora chiama il setDialogBorder(dialog)metodo nel setupDialog()metodo della tua classe BottomsheetDialogFragment.

Ora crea un file di forma nella tua cartella disegnabile.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="20dp" />

    <solid android:color="@color/white" />
    <stroke
        android:width="1dp"
        android:color="@color/transparent" />
</shape>

Ora imposta lo sfondo per la visualizzazione della finestra di dialogo del gruppo di visualizzazione padre nel file xml.

android:background="@drawable/round_border_white"

Fatto!!


Quale vista usi con setMargins?
tmm1

FrameLayout bottomSheet; Questo definito nel metodo setDialogBorder (). Questa è in realtà la visualizzazione predefinita per la finestra di dialogo del foglio inferiore in Android. Funzionerà bene.
DalveerSinghDaiya

1

aggiungi la forma con l'angolo arrotondato, rendilo sfondo per il layout della tua radice

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
 <corners
    android:topLeftRadius="@dimen/padding_margin_16_dp"
    android:topRightRadius="@dimen/padding_margin_16_dp" />
 <solid android:color="@color/white" />
</shape>

rendi lo sfondo trasparente sul tuo BottomSheetDialogFragment

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    (view?.parent as View).setBackgroundColor(Color.TRANSPARENT)
}

il suo lavoro per Contraintlayout, Framelyaout, Linearlayout, Relativelayout.


0

Un altro modo per risolvere questo problema è estendere BottomSheetDialog e creare una classe personalizzata che si adatta alle tue esigenze. Puoi fare lo stesso per il file xml di layout e aggiungere lo sfondo o qualsiasi altra personalizzazione necessaria. Questo ha anche il vantaggio che non dipenderai dai nomi degli ID usati da Android (android.support.design.R.id.design_bottom_sheet), mentre cambi lo sfondo (sebbene il cambio del nome dell'ID avvenga raramente AFAIK).


0

Crea un disegnabile personalizzato con l'angolo arrotondato e impostalo come sfondo della radice del layout di BottomSheetDialogFragment

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@color/colorPrimary" />

<corners
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    android:topLeftRadius="12dp"
    android:topRightRadius="12dp" />

</shape>

Quindi aggiungi semplicemente il codice seguente alla tua classe BottomSheetDialogFragment

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View contentView = View.inflate(getContext(), 
R.layout.fragment_bottom_sheet, null);
    dialog.setContentView(contentView);

    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent())
            .getLayoutParams();
    CoordinatorLayout.Behavior behavior = params.getBehavior();
    ((View) contentView.getParent()).setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
}

Puoi anche giocare con i parametri per impostare il margine come sotto

params.setMargins(50, 0, 50, 0);

0

È necessario modificare il bottom sheet themeper ottenere il layout rotondo superiore

Crea uno sfondo disegnabile personalizzato_bottom_sheet_dialog_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
    <corners
       android:topLeftRadius="8dp"
        android:topRightRadius="8dp" />
    <padding android:top="0dp" />
    <solid android:color="@color/white" />
</shape>

Quindi sovrascrivi bottomSheetDialogTheme su styles.xml utilizzando il drawable come sfondo:

<!--Bottom sheet-->
<style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
    <item 
    name="android:background">@drawable/background_bottom_sheet_dialog_fragment
    </item>
</style>

<style name="BaseBottomSheetDialog" 
    parent="@style/Theme.Design.Light.BottomSheetDialog">
    <item name="android:windowIsFloating">false</item>
    <item name="bottomSheetStyle">@style/BottomSheet</item>
</style>

<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />

Questo cambierà il layout di sfondo del tuo foglio inferiore

BottomSheetDialog

class SheetFragment() : BottomSheetDialogFragment() {

    lateinit var binding: SheetFragmentBinding;

  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog;
    val view = View.inflate(context, R.layout.fragment_bottom_sheet, null);

    binding = DataBindingUtil.bind(view)!!;
    binding.viewModel = SheetFragmentVM();

    dialog.setContentView(view);

    var bottomSheetBehavior = BottomSheetBehavior.from(view.parent as View);
    bottomSheetBehavior.setPeekHeight(BottomSheetBehavior.PEEK_HEIGHT_AUTO);

    bottomSheetBehavior.setBottomSheetCallback(object : 
     BottomSheetBehavior.BottomSheetCallback() {
        override fun onStateChanged(bottomSheet: View, newState: Int) {
            if (BottomSheetBehavior.STATE_EXPANDED == newState) {
               // do on STATE_EXPANDED
            }
            if (BottomSheetBehavior.STATE_COLLAPSED == newState) {
                // do on STATE_COLLAPSED
            }

            if (BottomSheetBehavior.STATE_HIDDEN == newState) {
                dismiss()

            }
        }

        override fun onSlide(bottomSheet: View, slideOffset: Float) {
           // do on slide
        }
    })

    return dialog
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.