Okrągły róg dla BottomSheetDialogFragment

114

Mam niestandardowy BttomSheetDialogFragment i chcę mieć zaokrąglone rogi w górnej części widoku od dołu

to jest moja niestandardowa klasa, która zawyża mój układ, który chcę wyświetlać od dołu

View mView;

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

a także mam ten plik zasobów xml jako tło:

<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"/>

ale problem polega na tym, że kiedy ustawię ten plik zasobów jako tło elementu głównego mojego układu, rogi nadal nie są zaokrąglone

i nie mogę użyć poniższego kodu:

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

ponieważ zastępuje domyślne tło BottomSheetDialog i nie będzie żadnego półprzezroczystego szarego koloru nad moim widokiem z dołu

Rasool Ghana
źródło
5
@RasoolGhana - Spójrz na ten link: medium.com/halcyon-mobile/…
Mohit Charadva

Odpowiedzi:

237

Utwórz niestandardowy element do rysowania 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>

Następnie nadpisać bottomSheetDialogThemena styles.xmlkorzystania z rozciągliwej jako tło:

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

Spowoduje to zmianę wszystkich BottomSheetDialogs Twojej aplikacji.

javiCabanas
źródło
2
Mi to pasuje. Zauważyłem też, że zależy to od elementu głównego układu. Najpierw miałem cardview jako root (bo próbowałem innego sposobu na zaokrąglanie rogów), potem zmieniłem go na układ liniowy i teraz działa idealnie
Ivan Shafran
1
Awarie na
Androidzie
1
Nie użyłbym rounded_dialog& AppModalStylenames z tłem, w którym tylko górne rogi są zaokrąglone, ponieważ spodziewałbyś się użyć takiego tła tylko ze stylem dolnego arkusza. Co powiesz na bottomsheet_rounded_background&AppBottomSheetStyle
hmac
3
Zwróć uwagę, że jeśli określisz tło w widoku głównym, zastąpi to to ustawienie
hmac
2
upewnij się, że nie masz tła w głównym elemencie układu arkusza!
MMK
81

Dzięki nowej bibliotece komponentów materiałowych możesz dostosować kształt komponentu za pomocą shapeAppearanceOverlayatrybutu w swoim stylu ( uwaga: wymaga wersji 1.1.0 )

Po prostu użyj BottomSheetDialogFragmentnadpisywania onCreateViewmetody, a następnie zdefiniuj własny styl dla okien dialogowych dolnego arkusza.

Zdefiniuj bottomSheetDialogThemeatrybut w styles.xmlmotywie aplikacji:

  <!-- 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>

Następnie po prostu zdefiniuj swój ulubiony kształt za pomocą 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>

wprowadź opis obrazu tutaj


Możesz uzyskać to samo zachowanie, zastępując tę ​​metodę w swoim BottomSheetDialogFragment(zamiast dodawać bottomSheetDialogThemew motywie aplikacji):

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

W tym przypadku używasz tego motywu Nakładaj tylko w pojedynczej aplikacji, BottomSheetDialogFragmenta nie w całej aplikacji.


Ważna uwaga na temat STANU ROZSZERZONEGO :

W stanie rozwiniętym BottomSheet ma płaskie rogi . Możesz sprawdzić oficjalny komentarz w repozytorium github :

Nasz zespół projektantów jest głęboko przekonany, że zaokrąglone rogi wskazują zawartość przewijalną, a płaskie rogi wskazują, że nie ma dodatkowej zawartości. W związku z tym nie chcą, abyśmy dodawali tę zmianę za pomocą fitToContents.

To zachowanie jest zapewniane przez BottomSheetBehaviori nie można go zastąpić.
Istnieje jednak obejście -> ZRZECZENIE SIĘ: może przestać działać w następnych wersjach !!

Możesz dodać BottomSheetCallbackw 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;
  }
Gabriele Mariotti
źródło
2
@GabrieleMariotti używając tej techniki, jeśli stuknę gdzieś na arkuszu i nie zostanie on odrzucony, rogi się ożywią. Nie jestem pewien, czy tworzysz na materialnych komponentach Androida, ale jeśli tak, czy wiesz o tym problemie? Używałem wersji 1.1.0-alpha10, ale też właśnie sprawdziłem beta2. Nie jestem pewien, czy zależy to od dokładnych widoków, które umieściłem w arkuszu, czy nie.
androidguy
1
Zgłosiłem ten problem: issuetracker.google.com/issues/144859239 Jeśli ktoś ma dalsze ustalenia lub rozwiązanie problemu, prosimy o odpowiedź. Dzięki!
androidguy
4
Otrzymuję ten błąd i zawieszam się w wersji 1.1.0-beta02Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior
hkchakladar
3
Nie działa, jeśli okno dialogowe dolnego arkusza jest rozwinięte. Dowolny pomysł?
José Carlos
4
To była doskonała i najnowsza odpowiedź. Muszę zaznaczyć to jako odpowiedź
Vikas Acharya
38

BottomSheetDialogJest ustawienie domyślne Kolor biały, to dlaczego rogi nie są widoczne, w celu pokazania ich trzeba dokonać tle dialogowe przejrzysty nadrzędnymi stylu BottomSheetDialog.

Zdefiniuj ten styl w swoim 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>

I ustaw ten styl w oknie dialogowym 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();
Badr
źródło
2
Lepsza niż zaakceptowana odpowiedź, ponieważ w ten sposób możesz mieć różne tła na różnych dolnych arkuszach dialogowych
Łukasz
Teraz krzywa widoczna, ale przezroczysty kolor na całym ekranie po dotknięciu tylko biały kolor na dole okna dialogowego jest widoczny @Badr jakieś poprawki?
Arnold Brown
To jest rozwiązanie, którego szukałem, całkowicie wolne od hackowania.
Prateek Gupta
26

utwórz kształt o nazwie rounded_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>

zdefiniować styl

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

użyj tego stylu na swoim niestandardowym BottomSheetDialogFragment w ten sposób, będzie działać!

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

      ...
    }
zhimin
źródło
Byłoby pomocne, gdybyś dołączył do kodu wyjaśnienia.
UditS
To jest właściwe miejsce, aby ustawić motyw dla Fragments.
DYS,
10

Jeśli używasz ostatniej wersji komponentu materiałowego , wystarczy nadpisać ShapeAppearance.MaterialComponents.LargeComponent(ponieważ dolny arkusz używa tego kształtu) i ustawić żądaną wartość, taką jak:

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

A następnie ustaw w stylu swojej aplikacji:

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

Rozwiązanie Gabriele Mariotti jest podobne i też działa, ale to jest prostsze.

Benjamin Ledet
źródło
W porównaniu do innych jest to znacznie lepsze rozwiązanie, ponieważ większość dostępnych rozwiązań bazuje na zestawie do rysowania na zamówienie
d-feverx
1
Wygląda dobrze. Czy dotyczy to również BottomSheetDialog?
Jaden Gu
1
Uwaga dla wszystkich: użycie tej odpowiedzi spowoduje, że wszystkie komponenty ShapeAppearance.MaterialComponents.LargeComponentbędą miały ten sam rozmiar narożnika i rodzinę, a nie tylko arkusz dolny. Sprawdź wymagania dotyczące stylu i zdecyduj, czy chcesz zmienić wygląd wszystkich komponentów, czy tylko pojedynczych komponentów lub widżetów.
nitinkumarp
9

Odpowiedź Koma Yip z innego pytania zadziałała dla mnie, powinieneś spróbować.

Utwórz plik XML do rysowania, powiedzmy 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>

umieść to w węźle głównym XML układu:

ustaw go jako tło w pliku xml układu

android:background="@drawable/dialog_bg"

a w onCreateView()skrócie:

ustaw przezroczyste tło okna dialogowego

dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Variag
źródło
To powinno być właściwe rozwiązanie, ponieważ działa dla wszystkich DialogFragments bez przeskakiwania przez obręcze.
jssingh
3
Dla mnie nadal są białe rogi za moimi zaokrąglonymi rogami. Więc kiedy zmieniam kolor mojego rysowalnego na czerwony, twój kod działa poprawnie i tworzy zaokrąglony czerwony prostokąt, ale za nim nadal jest domyślny biały prostokąt. „Dialog.getWindow (). SetBackgroundDrawable ...” Kod napisałeś zmienia kolor całego „zaciemnionym” obszar powyżej mojego okna, ale znowu, to nie zdobywa te dwa małe rogi. Czy wiesz, co może powodować ten problem?
Nick Dev
Dodając do mojego komentarza powyżej, powinienem zauważyć, że musiałem zmienić kod w onCreateView () na " getDialog () .getWindow () ..." , aby mój kod działał. Być może dlatego to nie działa dla mnie.
Nick Dev
1
@NickDev Opublikuj nowe pytanie, jeśli uważasz, że to rozwiązanie nie dotyczy Twojego kodu, a może znajdziemy rozwiązanie.
Variag
@Variag Dzięki za kontakt; Właściwie wymyśliłem tanie obejście, w którym zakrywam domyślne okno dialogowe dolnego arkusza prostokątem w tym samym kolorze co przyciemniony obszar za nim. Następnie dodałem drugi prostokąt z zaokrąglonymi rogami. Nie jest idealny, ale wygląda świetnie! Mimo to doceniam pomoc.
Nick Dev
8

Sprawdzałem dzisiaj to samo i tak, miałeś rację co do śledzenia kodu

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

dotyczy to tła fragmentu, więc zamiast tego powinieneś pobrać widok dolnego arkusza z okna dialogowego i zmienić tło tutaj jest kod

 @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);
    }

tutaj arkusz dolny to rzeczywisty widok, który chcesz zmienić.

Aashish Bhatnagar
źródło
Jedyny sposób, żeby to zadziałało. Btw używam BottomSheetDialogFragmentwięc logiki w onCreateDialogmetodzie
Kirill Starostin
6
  1. Utwórz kształt, który można narysować ..., który użyjemy jako tła dla dolnego arkusza. Podaj odpowiednią wartość promienia górnego lewego i prawego rogu.

    <?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. Teraz utwórz styl dla „Fragment okna dialogowego dolnego arkusza”

    <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. Teraz utwórz niestandardową klasę, która rozszerzy BottomSheetDilogFragment, w którym określisz swój styl.

    open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
    
        override fun getTheme(): Int = R.style.BottomSheetDialogTheme
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
    
    }
    
  4. Teraz użyj tej klasy wszędzie tam, gdzie chcesz mieć zaokrąglony dolny arkusz. na przykład

    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)
        }
    
    } 
    
Mini Chip
źródło
5

U mnie to zadziałało

utwórz kształt o nazwie 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" />

dodaj poniższe style

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

W klasie DialogFragment przesłanianie metody getTheme również zwraca styl Yourself.

@Override
public int getTheme() {
    return R.style.AppBottomSheetDialogTheme;
}
Mohamad
źródło
4

Ta odpowiedź dotyczy tylko kwestii ustawienia koloru tła Color.TRANSPARENTpo ustawieniu rysowalnego z zaokrąglonym tłem do układu.

Żadna z odpowiedzi nie działała dla mnie, aby ustawić kolor tła, z Color.TRANSPARENTwyjątkiem setupDialog()rozwiązania zastępującego :

@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));
}

ALEcontentView ustawić na oknie o to nie viewmożna dostać w onViewCreated()przypadku pompowania w onCreateView(). Łamie standardowy przepływ, więc może wydać problemy jak nie można korzystać View Bindings- Kotlin Android ExtensionswonViewCreated()

Więc trochę poprawiam, żeby ustawić tło w onActivityCreated():

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

Mam nadzieję, że ta pomoc, która ma te same problemy

DuDu
źródło
2

Wiem, że to pytanie ma już zaakceptowaną odpowiedź. Chciałbym udokumentować problemy, przez które przeszedłem i jak to w końcu działało, aby było to przydatne dla kogoś w przyszłości.

Po pierwsze, Theme.AppCompat.Light.DarkActionBarjako rodzic dla naszego AppTheme. Oznaczało to, że rozwiązanie @Gabriele Mariotti ciągle ulegało awarii z błędem Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior. Naprawiłem to, po prostu zmieniając rodzica na Theme.MaterialComponents.Light.DarkActionBar. Nie wpłynęło to w żaden sposób na nasz motyw, ale RTE zniknęło. Możesz również rozwiązać ten problem, po prostu dołączając wymagane elementy do swojego stylu. Ale nie zawracałem sobie głowy ustalaniem, które style były wymagane przez BottomSheetBehavior.

Po drugie, spróbuj, jak mogłem, ale nie mogłem uzyskać rzeczywistego układu ramki (którym był BottomSheetDialogFragment), którego używa, aby mieć zaokrąglone rogi. Zdałem sobie sprawę, że ustawienie tego na obraz do rysowania działało, ale nie w przypadku kształtu lub @null. Okazało się, że to dlatego, LinearLayoutże używany przeze mnie miał zdefiniowane tło. To przesłaniało wszelkie tło w stylu. Usunięcie tego ostatecznie zaowocowało zaokrąglonymi narożnikami.

Nie wymagałem też, aby kształt tła był zaokrąglany w rogach. Rozwiązanie @Gabriele Mariotti działało, gdy tylko wprowadziłem powyższe zmiany. Jednak aby ustawić kolor tła na taki, jaki chciałem, musiałem nadpisać element „backgroundTint”.

PS: Jestem nowy w programowaniu Android i utrzymuję starą aplikację, która została stworzona do użytku wewnętrznego w naszej uczelni. Nie jestem zbyt zaznajomiony z układem Androida ani z biblioteką materiałów. Myślę, że dlatego zajęło mi to 3 dni. Mam nadzieję, że przyda się to komuś w przyszłości.

abhijeetviswa
źródło
1

Dodaj te dwie metody do swojej klasy 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();
        }
    }

Teraz wywołaj setDialogBorder(dialog)metodę w setupDialog()metodzie klasy BottomsheetDialogFragment.

Teraz utwórz plik kształtu w folderze do rysowania.

<?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>

Teraz ustaw tło dla widoku okna dialogowego nadrzędnej grupy widoków w pliku xml.

android:background="@drawable/round_border_white"

Gotowe!!

DalveerSinghDaiya
źródło
Którego widoku używasz z setMargins?
tmm1
FrameLayout bottomSheet; Ten zdefiniowany w metodzie setDialogBorder (). W rzeczywistości jest to domyślny widok okna dialogowego dolnego arkusza w systemie Android. Będzie działać dobrze.
DalveerSinghDaiya
1

dodaj kształt z zaokrąglonym rogiem, ustaw go jako tło dla układu głównego

<?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>

ustaw przezroczystość tła w Twoim BottomSheetDialogFragment

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

jego praca dla Contraintlayout, Framelyaout, Linearlayout, Relativelayout.

Indra As Lesmana
źródło
0

Innym sposobem rozwiązania tego problemu jest rozszerzenie BottomSheetDialog i utworzenie niestandardowej klasy, która odpowiada Twoim potrzebom. Możesz zrobić to samo dla pliku xml układu i dodać tło lub inne potrzebne dostosowania. Ma to również tę zaletę, że nie będziesz zależny od nazw identyfikatorów używanych przez Androida (android.support.design.R.id.design_bottom_sheet) podczas zmiany tła (choć zmiana nazwy identyfikatora rzadko się zdarza AFAIK).

gaurav jain
źródło
0

Utwórz niestandardowy element do rysowania z zaokrąglonym rogiem i ustaw go jako tło katalogu głównego układu 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>

A następnie po prostu dodaj poniższy kod do swojej klasy 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));
}

Możesz nawet grać z parametrami, aby ustawić margines, jak poniżej

params.setMargins(50, 0, 50, 0);
Darshna Desai
źródło
0

Musisz zmienić bottom sheet theme aby uzyskać górny układ rundy

Utwórz niestandardowy do rysowania background_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>

Następnie nadpisz bottomSheetDialogTheme na styles.xml, używając jako tła do rysowania:

<!--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" />

Spowoduje to zmianę układu tła dolnego arkusza

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
}
Atul
źródło