มุมมนสำหรับ BottomSheetDialogFragment


126

ฉันมี BttomSheetDialogFragment ที่กำหนดเองและฉันต้องการให้มีมุมกลมที่ด้านบนของมุมมองด้านล่าง

นี่คือคลาสกำหนดเองของฉันที่ขยายเลย์เอาต์ของฉันที่ฉันต้องการให้ปรากฏจากด้านล่าง

View mView;

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

และฉันมีไฟล์ทรัพยากร xml นี้เป็นพื้นหลัง:

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

แต่ปัญหาคือเมื่อฉันตั้งค่าไฟล์ทรัพยากรนี้เป็นพื้นหลังขององค์ประกอบรูทของ Layout ของฉันมุมจะยังไม่ถูกปัดเศษ

และฉันไม่สามารถใช้รหัสด้านล่าง:

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

เพราะมันจะแทนที่พื้นหลังเริ่มต้นของ BottomSheetDialog และจะไม่มีสีเทากึ่งโปร่งใสเหนือมุมมองด้านล่างของฉัน


5
@RasoolGhana - ลองดูที่ลิงค์นี้: medium.com/halcyon-mobile/…
Mohit Charadva

คำตอบ:


264

สร้างสิ่งที่วาดได้เอง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>

แล้วแทนที่bottomSheetDialogThemeในstyles.xmlการใช้ drawable เป็นพื้นหลัง:

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

สิ่งนี้จะเปลี่ยน BottomSheetDialogs ทั้งหมดของแอปของคุณ


2
มันใช้ได้กับฉัน นอกจากนี้ฉันสังเกตว่ามันขึ้นอยู่กับองค์ประกอบรูทของเค้าโครง ประการแรกฉันมี cardview เป็นรูท (สาเหตุที่ฉันลองวิธีอื่นในการปัดมุม) จากนั้นฉันก็เปลี่ยนเป็นเลย์เอาต์เชิงเส้นและตอนนี้มันทำงานได้อย่างสมบูรณ์
Ivan Shafran

1
เกิดปัญหาบน Android api 17
Morteza Rastgoo

1
ฉันจะไม่ใช้rounded_dialog& AppModalStyleตั้งชื่อที่มีพื้นหลังโดยที่มุมด้านบนเท่านั้นที่จะถูกปัดเศษเนื่องจากคุณคาดหวังว่าจะใช้พื้นหลังที่มีลักษณะแผ่นงานด้านล่างเท่านั้น How about bottomsheet_rounded_background&AppBottomSheetStyle
hmac

3
โปรดทราบว่าหากคุณระบุพื้นหลังในมุมมองรูทสิ่งนี้จะแทนที่การตั้งค่านี้
hmac

3
ตรวจสอบให้แน่ใจว่าคุณไม่มีพื้นหลังเกี่ยวกับองค์ประกอบรูทของเค้าโครงแผ่นงานของคุณ!
MMK

96

ด้วยไลบรารีMaterial Componentใหม่คุณสามารถปรับแต่งรูปร่างของส่วนประกอบโดยใช้shapeAppearanceOverlayแอตทริบิวต์ในสไตล์ของคุณ ( หมายเหตุ:ต้องใช้เวอร์ชัน1.1.0 )

เพียงใช้วิธีการBottomSheetDialogFragmentลบล้างonCreateViewจากนั้นกำหนดรูปแบบที่คุณกำหนดเองสำหรับกล่องโต้ตอบด้านล่าง

กำหนดbottomSheetDialogThemeแอตทริบิวต์ในstyles.xmlธีมแอปของคุณ:

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

จากนั้นกำหนดรูปร่างที่คุณชื่นชอบด้วย 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>

ใส่คำอธิบายภาพที่นี่


คุณสามารถได้รับพฤติกรรมเดียวกันที่แทนที่วิธีนี้ในของคุณBottomSheetDialogFragment(แทนที่จะเพิ่มbottomSheetDialogThemeในธีมแอปของคุณ):

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

ในกรณีนี้คุณกำลังใช้ธีมนี้โอเวอร์เลย์เฉพาะในแอพเดียวBottomSheetDialogFragmentและไม่ได้อยู่ในแอพทั้งหมด


หมายเหตุสำคัญเกี่ยวกับสถานะที่ขยาย :

ในรัฐขยายตัวที่ BottomSheet มีมุมแบน คุณสามารถตรวจสอบความคิดเห็นอย่างเป็นทางการในgithub repo :

ทีมออกแบบของเรามีความเห็นเป็นอย่างยิ่งว่ามุมโค้งมนบ่งบอกถึงเนื้อหาที่เลื่อนได้ในขณะที่มุมแบนแสดงว่าไม่มีเนื้อหาเพิ่มเติม ด้วยเหตุนี้พวกเขาจึงไม่ต้องการให้เราเพิ่มการเปลี่ยนแปลงนี้ด้วย fitToContents

พฤติกรรมนี้จัดทำขึ้นโดยBottomSheetBehaviorและเป็นไปไม่ได้ที่จะลบล้างพฤติกรรมนี้
อย่างไรก็ตามมีวิธีแก้ไขเบื้องต้น -> การปฏิเสธความรับผิด:สามารถหยุดทำงานได้ในรุ่นถัดไป !!

คุณสามารถเพิ่มBottomSheetCallbackใน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 โดยใช้เทคนิคนี้ถ้าฉันแตะที่ใดที่หนึ่งบนแผ่นงานและมันไม่ถูกปิดมุมจะเคลื่อนไหวออกไป ฉันไม่แน่ใจว่าคุณพัฒนาบนส่วนประกอบวัสดุของ Android หรือไม่ แต่ถ้าเป็นคุณคุณรู้ปัญหานี้หรือไม่ ฉันใช้ 1.1.0-alpha10 แต่ฉันเพิ่งตรวจสอบ beta2 ด้วย ฉันไม่แน่ใจว่าขึ้นอยู่กับมุมมองที่แน่นอนที่ฉันใส่ไว้ในแผ่นงานหรือไม่
androidguy

1
ฉันได้รายงานปัญหานี้แล้ว: issueetracker.google.com/issues/144859239หากใครมีข้อค้นพบหรือวิธีแก้ปัญหาเพิ่มเติมโปรดตอบกลับ ขอบคุณ!
androidguy

4
ฉันได้รับข้อผิดพลาดนี้และขัดข้องใน v1.1.0-beta02Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior
hkchakladar

3
จะไม่ทำงานหากกล่องโต้ตอบแผ่นงานด้านล่างถูกขยาย ความคิดใด ๆ ?
José Carlos

5
นี่คือคำตอบที่สมบูรณ์แบบและล่าสุด ฉันต้องทำเครื่องหมายนี้เป็นคำตอบ
Vikas Acharya

41

คือการตั้งค่าสีพื้นหลังสีขาวเริ่มต้นนี้คือเหตุผลที่มุมมองไม่เห็นเพื่อที่จะแสดงให้พวกเขาที่คุณต้องทำให้พื้นหลังของความโปร่งใสโต้ตอบโดยการเอาชนะรูปแบบของBottomSheetDialogBottomSheetDialog

กำหนดสไตล์นี้ในไฟล์ 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>

และตั้งค่าลักษณะนี้เป็น 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
ดีกว่าคำตอบที่ยอมรับเพราะวิธีนี้คุณสามารถมีภูมิหลังที่แตกต่างกันใน BottomSheetDialogs ที่แตกต่างกัน
ลุค

ตอนนี้มองเห็นเส้นโค้ง แต่สีโปร่งใสทั่วทั้งหน้าจอเมื่อสัมผัสเฉพาะสีขาวที่กล่องโต้ตอบด้านล่างเท่านั้นที่มองเห็นได้ @ แก้ไขการแก้ไขใด ๆ ?
Arnold Brown

นั่นคือวิธีแก้ปัญหาที่ฉันกำลังมองหาแฮ็คฟรีโดยสิ้นเชิง
Prateek Gupta

27

สร้างรูปร่างที่ชื่อว่า 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>

กำหนดสไตล์

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

ใช้สไตล์นี้บน BottomSheetDialogFragment ที่คุณกำหนดเองแบบนี้ก็ใช้ได้!

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

      ...
    }

จะเป็นประโยชน์หากคุณเพิ่มคำชี้แจงพร้อมกับรหัส
UditS

นี่คือสถานที่ที่เหมาะสมในการตั้งธีมสำหรับFragments
DYS

10

หากคุณใช้ส่วนประกอบวัสดุเวอร์ชันล่าสุดคุณเพียงแค่ต้องลบล้างShapeAppearance.MaterialComponents.LargeComponent(เนื่องจากแผ่นงานด้านล่างใช้รูปร่างนี้) และตั้งค่าที่คุณต้องการ:

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

จากนั้นตั้งค่าในรูปแบบแอปของคุณ:

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

วิธีแก้ปัญหาของ Gabriele Mariottiนั้นคล้ายกันและใช้ได้ผลเช่นกัน แต่วิธีนี้ง่ายกว่า


เมื่อเทียบกับคนอื่น ๆ มันเป็นทางออกที่ดีมากเพราะส่วนใหญ่ของการแก้ปัญหาออกมีเป็นฐานใน drawable ชุดที่กำหนดเอง
D-feverx

1
ดูดี. สิ่งนี้ใช้กับBottomSheetDialog?
Jaden Gu

1
หมายเหตุสำหรับทุกคน: การใช้คำตอบนี้จะทำให้ส่วนประกอบทั้งหมดที่ใช้ShapeAppearance.MaterialComponents.LargeComponentมี cornerSize และตระกูลเดียวกันไม่ใช่แค่แผ่นด้านล่าง ตรวจสอบความต้องการสไตล์ของคุณและตัดสินใจว่าคุณต้องการเปลี่ยนรูปลักษณ์สำหรับส่วนประกอบทั้งหมดหรือเพียงแค่ส่วนประกอบหรือวิดเจ็ตแต่ละรายการ
nitinkumarp

9

คำตอบโดยKoma Yipจากคำถามอื่นที่ใช้ได้ผลสำหรับฉันคุณควรลองดู

สร้าง xml ในรูปวาดได้โดยพูด 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>

ใส่สิ่งนี้ในโหนดรูท xml เลย์เอาต์ของคุณ:

ตั้งเป็นพื้นหลังใน xml เลย์เอาต์ของคุณ

android:background="@drawable/dialog_bg"

และonCreateView()ใส่สิ่งนี้:

ตั้งค่าพื้นหลังของกล่องโต้ตอบของคุณให้โปร่งใส

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

นี่ควรเป็นทางออกที่ถูกต้องเพราะใช้ได้กับ DialogFragments ทั้งหมดโดยไม่ต้องกระโดดข้ามห่วง
jssingh

3
สำหรับฉันแล้วยังมีมุมสีขาวอยู่หลังมุมมนของฉัน ดังนั้นเมื่อฉันเปลี่ยนสีของสิ่งที่วาดได้เป็นสีแดงโค้ดของคุณจะทำงานได้อย่างถูกต้องและสร้างสี่เหลี่ยมผืนผ้าสีแดงที่โค้งมน แต่ด้านหลังนั้นยังคงมีสี่เหลี่ยมผืนผ้าสีขาวเริ่มต้น "dialog.getWindow (). setBackgroundDrawable ..."รหัสที่คุณเขียนการเปลี่ยนแปลงสีของทั้ง "มืด" บริเวณเหนือโต้ตอบของฉันอีกครั้ง แต่พลาดทั้งสองมุมเล็ก ๆ น้อย ๆ คุณรู้หรือไม่ว่าอะไรเป็นสาเหตุของปัญหานี้
Nick Dev

เมื่อเพิ่มความคิดเห็นของฉันข้างต้นฉันควรทราบว่าฉันต้องเปลี่ยนรหัสในonCreateView ()เป็น" getDialog () .getWindow () ... "เพื่อให้โค้ดของฉันทำงานได้ บางทีนี่อาจเป็นสาเหตุที่ไม่ได้ผลสำหรับฉัน
Nick Dev

1
@NickDev โพสต์คำถามใหม่หากคุณคิดว่าวิธีนี้ใช้ไม่ได้กับรหัสของคุณเราอาจจะหาทางแก้ไข
Variag

@Variag ขอบคุณสำหรับการติดต่อ; จริงๆแล้วฉันได้หาวิธีแก้ปัญหาราคาถูกที่ฉันครอบคลุมกล่องโต้ตอบโมดอลแผ่นงานด้านล่างเริ่มต้นด้วยสี่เหลี่ยมผืนผ้าที่มีสีเดียวกับพื้นที่มืดด้านหลัง จากนั้นฉันก็เพิ่มสี่เหลี่ยมผืนผ้าที่สองโดยมีมุมโค้งมนอยู่ด้านบน ไม่เหมาะ แต่ดูดีมาก! ฉันขอขอบคุณสำหรับความช่วยเหลืออย่างไรก็ตาม
Nick Dev

8

วันนี้ฉันกำลังตรวจสอบสิ่งเดียวกันและใช่คุณพูดถูกเกี่ยวกับรหัสต่อไปนี้

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

สิ่งนี้ใช้กับพื้นหลังส่วนดังนั้นคุณควรได้รับมุมมองด้านล่างจากหน้าต่างโต้ตอบและเปลี่ยนพื้นหลังที่นี่คือรหัส

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

นี่คือมุมมองจริงที่คุณต้องการเปลี่ยน


วิธีเดียวที่ฉันทำให้มันได้ผล Btw ฉันใช้BottomSheetDialogFragmentเพื่อให้ตรรกะอยู่ในonCreateDialogวิธีการ
Kirill Starostin

8

มันได้ผลสำหรับฉัน

สร้างรูปร่างชื่อ 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" />

เพิ่มรูปแบบด้านล่าง

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

ในคลาส DialogFragment เมธอด override getTheme ยังส่งคืนสไตล์ Yourself

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

6
  1. สร้างรูปร่างที่วาดได้ .. ซึ่งเราจะใช้เป็นพื้นหลังสำหรับแผ่นงานด้านล่าง ระบุค่าที่เหมาะสมสำหรับรัศมีของมุมบนซ้ายและขวา

    <?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. ตอนนี้สร้างสไตล์สำหรับ "ชิ้นส่วนกล่องโต้ตอบด้านล่างของแผ่นงาน"

    <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. ตอนนี้สร้างคลาสแบบกำหนดเองที่จะขยาย BottomSheetDilogFragment ซึ่งคุณระบุสไตล์ของคุณ

    open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
    
        override fun getTheme(): Int = R.style.BottomSheetDialogTheme
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
    
    }
    
  4. ตอนนี้ใช้คลาสนี้ทุกที่ที่คุณต้องการให้มีแผ่นกลมด้านล่าง เช่น

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

4

คำตอบนี้ใช้สำหรับปัญหาการตั้งค่าสีพื้นหลังเป็นเท่านั้น Color.TRANSPARENTหลังจากตั้งค่าพื้นหลังแบบวาดได้โดยมีพื้นหลังโค้งมนเข้ากับเค้าโครง

ไม่มีคำตอบใดที่ใช้ได้ผลสำหรับฉันในการตั้งค่าสีพื้นหลังColor.TRANSPARENTยกเว้นsetupDialog()วิธีการแก้ไข:

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

แต่contentViewคุณตั้งไว้สำหรับการโต้ตอบที่นี่ไม่ได้เป็นviewคุณได้รับในเมื่อพองในonViewCreated() onCreateView()จะแบ่งการไหลมาตรฐานดังนั้นอาจออกปัญหาเช่นคุณไม่สามารถใช้View Bindings-Kotlin Android ExtensionsในonViewCreated()

ดังนั้นฉันจึงปรับแต่งเล็กน้อยเพื่อตั้งค่าพื้นหลังในonActivityCreated():

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

หวังว่าจะช่วยให้ผู้ที่ประสบปัญหาเดียวกันนี้


2

ฉันรู้ว่าคำถามนี้มีคำตอบที่ยอมรับแล้ว ฉันต้องการบันทึกปัญหาที่ฉันประสบและในที่สุดฉันก็ทำงานได้อย่างไรจึงเป็นประโยชน์สำหรับใครบางคนในอนาคต

ประการแรกฉันใช้Theme.AppCompat.Light.DarkActionBarเป็นผู้ปกครองสำหรับAppThemeไฟล์. วิธีการแก้ปัญหา @Gabriele Mariotti Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehaviorนี่หมายความว่ายังคงล้มเหลวกับข้อผิดพลาด Theme.MaterialComponents.Light.DarkActionBarฉันคงนี้โดยเพียงแค่การเปลี่ยนแม่เพื่อ สิ่งนี้ไม่ส่งผลกระทบต่อธีมของเรา แต่อย่างใด แต่ RTE หายไป คุณยังสามารถแก้ไขปัญหานี้ได้โดยเพียงแค่ใส่ไอเท็มที่ต้องการเข้ากับสไตล์ของคุณ แต่ฉันไม่ได้กังวลว่า BottomSheetBehavior ต้องการสไตล์ใด

ประการที่สองลองตามที่ฉันทำได้ แต่ฉันไม่สามารถรับเค้าโครงเฟรมจริง (ซึ่งก็คือ BottomSheetDialogFragment) ใช้เพื่อให้มีมุมกลม ฉันตระหนักว่าการตั้งค่านี้เป็นรูปภาพที่วาดได้นั้นใช้งานได้ แต่ไม่สามารถใช้กับรูปร่างหรือไฟล์@null. ปรากฎว่าเป็นเพราะไฟล์LinearLayoutฉันใช้มีพื้นหลังที่กำหนดไว้ นี่เป็นการลบล้างพื้นหลังในสไตล์ การลบออกทำให้เกิดมุมโค้งมนในที่สุด

นอกจากนี้ฉันไม่ต้องการให้มีการตั้งค่ารูปทรงพื้นหลังให้ปัดเศษมุม โซลูชันของ @Gabriele Mariotti ทำงานได้ทันทีที่ฉันทำการเปลี่ยนแปลงข้างต้น อย่างไรก็ตามในการกำหนดสีพื้นหลังตามที่ฉันต้องการให้เป็นฉันต้องลบล้างรายการ "backgroundTint"

PS: ฉันเพิ่งเริ่มใช้ Android dev และกำลังบำรุงรักษาแอปเก่าที่สร้างขึ้นเพื่อใช้ภายในวิทยาลัยของเรา ฉันไม่คุ้นเคยกับระบบเลย์เอาต์ของ Android หรือไลบรารีวัสดุทั้งหมด ฉันเดาว่านั่นเป็นสาเหตุที่ฉันใช้เวลา 3 วันในการคิดออก ฉันหวังว่านี่จะเป็นประโยชน์กับใครบางคนในอนาคต


1

เพิ่มสองวิธีการนี้ในคลาส 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();
        }
    }

ตอนนี้เรียกsetDialogBorder(dialog)method ในsetupDialog()method ของคลาส BottomsheetDialogFragment

ตอนนี้สร้างไฟล์รูปร่างในโฟลเดอร์ที่วาดได้ของคุณ

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

ตอนนี้ตั้งค่าพื้นหลังสำหรับมุมมองไดอะล็อกวิวกรุ๊ปหลักในไฟล์ xml

android:background="@drawable/round_border_white"

เรียบร้อย !!


คุณใช้มุมมองใดกับ setMargins
tmm1

FrameLayout bottomSheet; อันนี้กำหนดไว้ในเมธอด setDialogBorder () นี่เป็นมุมมองเริ่มต้นสำหรับกล่องโต้ตอบด้านล่างใน Android มันจะทำงานได้ดี
DalveerSinghDaiya

1

เพิ่มรูปร่างด้วยมุมโค้งมนทำให้เป็นพื้นหลังสำหรับเค้าโครงรากของคุณ

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

ทำให้พื้นหลังโปร่งใสบน BottomSheetDialogFragment ของคุณ

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

มันทำงานสำหรับ Contraintlayout, Framelyaout, Linearlayout, Relativelayout


1

โซลูชันที่เรียบง่าย:

class TopRoundedCornersFragment : BottomSheetDialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setStyle(STYLE_NORMAL, R.style.AppBottomSheetDialogTheme)
    }
}

ใน styles.xml

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

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

สุดท้ายสร้างทรัพยากรที่วาดได้มุมโค้งมนด้านบน (bottom_sheet_dialog_bg.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@android:color/white" />
    <corners
        android:topLeftRadius="4dp"
        android:topRightRadius="4dp" />

</shape>

0

อีกวิธีหนึ่งในการแก้ไขปัญหานี้คือการขยาย BottomSheetDialog และสร้างคลาสแบบกำหนดเองที่เหมาะกับความต้องการของคุณ คุณสามารถทำเช่นเดียวกันสำหรับไฟล์ xml เค้าโครงและเพิ่มพื้นหลังหรือการปรับแต่งอื่น ๆ ที่จำเป็น นอกจากนี้ยังมีประโยชน์ที่คุณจะไม่ต้องขึ้นอยู่กับชื่อ id ที่ Android ใช้ (android.support.design.R.id.design_bottom_sheet) ในขณะที่เปลี่ยนพื้นหลัง (แม้ว่าการเปลี่ยนชื่อ id จะไม่ค่อยเกิดขึ้น AFAIK ก็ตาม)


0

สร้างแบบกำหนดเองที่วาดได้ด้วยมุมโค้งมนและตั้งเป็นพื้นหลังของรูทเค้าโครงของ 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>

จากนั้นเพิ่มโค้ดด้านล่างลงในคลาส 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));
}

คุณยังสามารถเล่นกับพารามิเตอร์เพื่อกำหนดระยะขอบตามด้านล่าง

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

0

คุณต้องเปลี่ยนbottom sheet themeเพื่อให้ได้เค้าโครงรอบด้านบน

สร้าง 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>

จากนั้นแทนที่ bottomSheetDialogTheme บน styles.xml โดยใช้ drawable เป็นพื้นหลัง:

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

ซึ่งจะเปลี่ยนเค้าโครงพื้นหลังของแผ่นงานด้านล่างของคุณ

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
}

0

โซลูชั่นที่สมบูรณ์:

เพิ่มแอตทริบิวต์ style ด้านล่างใน style.xml

<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/bottom_sheet_background</item>
</style>

จากนั้นใช้AppBottomSheetDialogThemeเพื่อสร้างกล่องโต้ตอบด้านล่างจากรหัสของคุณ

private fun openBottomSheetTermsCondition() {
    val mBottomSheetDialog = BottomSheetDialog(requireContext(),R.style.AppBottomSheetDialogTheme)
    val sheetView = layoutInflater.inflate(R.layout.bottom_sheet_travel_advice_terms, null)
    mBottomSheetDialog.setContentView(sheetView)
    sheetView.tv_head.setOnClickListener {
        mBottomSheetDialog.dismiss()
    }

    sheetView.webView.loadDataWithBaseURL(null,getString(R.string.privacy_policy_body_html),"text/html", "utf-8", null)
    mBottomSheetDialog.show()
}

ฉันใช้ด้านล่างที่วาดได้เพื่อปัดเศษพื้นหลังแผ่นงานด้านล่าง

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

แผ่นงานด้านล่าง xml bottom_sheet_travel_advice_terms.xml

    <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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"
    app:behavior_hideable="false"
    app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
    app:cardCornerRadius="@dimen/spacing_normal"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/spacing_small">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/begin_horizontal_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="@dimen/activity_vertical_margin" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/begin_vertical_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="@dimen/activity_horizontal_margin" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/end_vertical_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_end="@dimen/activity_horizontal_margin" />

        <View
            android:id="@+id/sheet_header_shadow"
            android:layout_width="match_parent"
            android:layout_height="@dimen/spacing_tiny"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:background="@drawable/bottom_sheet_header_shadow"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/tv_head"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:drawablePadding="@dimen/spacing_normal"
            android:fontFamily="sans-serif-medium"
            android:gravity="start"
            android:padding="@dimen/spacing_small"
            android:text="@string/term_and_condition"
            android:textColor="@color/greyish_brown"
            android:textSize="20sp"
            app:drawableLeftCompat="@drawable/ic_close_black_24dp"
            app:layout_constraintEnd_toEndOf="@id/end_vertical_guideline"
            app:layout_constraintStart_toStartOf="@id/begin_vertical_guideline"
            app:layout_constraintTop_toBottomOf="@+id/begin_horizontal_guideline" />

        <View
            android:id="@+id/line_separation"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="@dimen/spacing_small"
            android:background="@color/blue_gray"
            app:layout_constraintTop_toBottomOf="@+id/tv_head" />

        <WebView
            android:id="@+id/webView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="@id/end_vertical_guideline"
            app:layout_constraintStart_toStartOf="@id/begin_vertical_guideline"
            app:layout_constraintTop_toBottomOf="@id/line_separation" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

0

setupDialog()เป็น RestrictedApi วิธีที่ง่ายที่สุดที่ใช้งานได้material:1.3.0-beta01โดยไม่ต้องแตะธีม:

res/drawable/bs_background:

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

@Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ((View) view.getParent()).setBackgroundResource(R.drawable.bs_background);
  }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.