Góc tròn cho BottomSheetDialogFragment


114

tôi có một BttomSheetDialogFragment tùy chỉnh và tôi muốn có các góc tròn ở đầu Chế độ xem dưới cùng

đây là lớp Tùy chỉnh của tôi làm phồng bố cục của tôi mà tôi muốn xuất hiện từ dưới lên

View mView;

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

và tôi cũng có tệp tài nguyên xml này làm nền:

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

nhưng vấn đề là, khi tôi đặt tệp tài nguyên này làm nền cho phần tử gốc của Bố cục, các góc vẫn không được làm tròn

và tôi không thể sử dụng mã dưới đây:

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

vì nó ghi đè nền mặc định của BottomSheetDialog và sẽ không có bất kỳ màu xám nửa trong suốt nào phía trên Chế độ xem dưới cùng của tôi


5
@RasoolGhana - Hãy xem liên kết này: medium.com/halcyon-mobile/…
Mohit Charadva

Câu trả lời:


235

Tạo một tùy chỉnh có thể vẽ 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>

Sau đó ghi đè lên bottomSheetDialogThemetrên styles.xmlbằng cách sử dụng drawable làm nền:

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

Điều này sẽ thay đổi tất cả BottomSheetDialogs của ứng dụng của bạn.


2
Nó làm việc cho tôi. Ngoài ra, tôi nhận thấy nó phụ thuộc vào yếu tố gốc bố cục. Thứ nhất tôi đã cardview là root (vì tôi đã cố gắng một cách khác để góc tròn), sau đó tôi thay đổi nó để bố trí tuyến tính và bây giờ nó hoạt động hoàn hảo
Ivan Shafran

1
Sự cố trên android api 17
Morteza Rastgoo

1
Tôi sẽ không sử dụng rounded_dialog& AppModalStyletên với nền mà chỉ có các góc trên cùng được làm tròn, vì bạn chỉ mong đợi sử dụng nền như vậy với kiểu trang tính dưới cùng. Còn về bottomsheet_rounded_background&AppBottomSheetStyle
hmac

3
Lưu ý nếu bạn chỉ định nền trên chế độ xem gốc thì điều này sẽ ghi đè cài đặt này
hmac

2
đảm bảo rằng bạn không có bất kỳ nền nào trên phần tử gốc của bố cục trang tính của bạn!
MMK

81

Với thư viện Thành phần Vật liệu mới, bạn có thể tùy chỉnh hình dạng của thành phần bằng cách sử dụng shapeAppearanceOverlaythuộc tính theo phong cách của bạn ( Lưu ý: nó yêu cầu phiên bản 1.1.0 )

Chỉ cần sử dụng phương pháp ghi BottomSheetDialogFragmentđè onCreateViewvà sau đó xác định kiểu tùy chỉnh của bạn cho Hộp thoại Trang tính Dưới cùng.

Xác định bottomSheetDialogThemethuộc tính trong styles.xmlchủ đề ứng dụng của bạn:

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

Sau đó, chỉ cần xác định hình dạng yêu thích của bạn với 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>

nhập mô tả hình ảnh ở đây


Bạn có thể có được cùng một hành vi ghi đè phương thức này trong của bạn BottomSheetDialogFragment(thay vì thêm bottomSheetDialogThemechủ đề trong ứng dụng của bạn):

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

Trong trường hợp này, bạn đang sử dụng chủ đề này Chỉ phát trong một BottomSheetDialogFragmentvà không phải trong tất cả các ứng dụng.


Lưu ý quan trọng về NHÀ NƯỚC MỞ RỘNG :

Ở trạng thái mở rộng, BottomSheet có các góc phẳng . Bạn có thể kiểm tra nhận xét chính thức trong github repo :

Nhóm thiết kế của chúng tôi rất kiên định rằng các góc tròn cho biết nội dung có thể cuộn được trong khi các góc phẳng cho biết không có nội dung bổ sung. Do đó, họ không muốn chúng tôi thêm thay đổi này với fitToContents.

Hành vi này được cung cấp bởi BottomSheetBehaviorvà không thể ghi đè nó.
Tuy nhiên, có một cách giải quyết -> KHUYẾN CÁO: nó có thể ngừng hoạt động trong các bản phát hành tiếp theo !!

Bạn có thể thêm một BottomSheetCallbacktrong 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 bằng cách sử dụng kỹ thuật này, nếu tôi nhấn vào một nơi nào đó trên trang tính và nó không bị loại bỏ, các góc sẽ hoạt hình đi. Tôi không chắc liệu bạn có phát triển trên các thành phần material của Android hay không, nhưng nếu có, bạn có biết về vấn đề này không? Tôi đang sử dụng 1.1.0-alpha10, nhưng tôi cũng vừa kiểm tra phiên bản beta2. Tôi không chắc liệu nó có phụ thuộc vào các chế độ xem chính xác mà tôi đưa vào trang tính hay không.
androidguy

1
Tôi đã báo cáo vấn đề này: Issuetracker.google.com/issues/144859239 Nếu ai có thêm bất kỳ phát hiện hoặc giải pháp nào cho vấn đề này, vui lòng trả lời. Cảm ơn!
androidguy

4
Tôi gặp lỗi này và gặp sự cố trên v1.1.0-beta02Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior
hkchakladar

3
Nó không hoạt động nếu hộp thoại trang dưới cùng được mở rộng. Bất kỳ ý tưởng?
José Carlos

4
Đây là câu trả lời hoàn hảo và mới nhất. Tôi cần đánh dấu đây là câu trả lời
Vikas Acharya

38

Các BottomSheetDialogđược thiết lập một màu nền trắng mặc định, đây là lý do tại sao các góc không nhìn thấy được, Để cho họ thấy bạn cần phải thực hiện nền của bạch thoại bằng cách ghi đè phong cách của BottomSheetDialog.

Xác định phong cách này trong 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>

Và đặt kiểu này thành BottomSheetDialog của bạn

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
Tốt hơn câu trả lời được chấp nhận, bởi vì bằng cách này, bạn có thể có các nền tảng khác nhau trên các BottomSheetDialogs khác nhau
Luke

Bây giờ đường cong có thể nhìn thấy, nhưng một màu trong suốt trên toàn màn hình khi chạm vào chỉ có màu trắng ở hộp thoại dưới cùng là hiển thị @Badr có bất kỳ sự thay đổi nào không?
Arnold Brown

Nó đã hoạt động ở đây. Cảm ơn!
Michel Fernandes

Đó là giải pháp tôi đang tìm kiếm, Hoàn toàn miễn phí hack.
Prateek Gupta

26

tạo một hình dạng có tên 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>

xác định một phong cách

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

sử dụng kiểu này trên BottomSheetDialogFragment tùy chỉnh của bạn như thế này, nó sẽ hoạt động!

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

      ...
    }

Sẽ rất hữu ích nếu bạn thêm một số làm rõ cùng với mã.
UditS

Đây là nơi thích hợp để đặt chủ đề cho Fragments.
DYS

10

Nếu bạn sử dụng phiên bản cuối cùng của thành phần material, bạn chỉ cần ghi đè ShapeAppearance.MaterialComponents.LargeComponent(vì trang tính dưới cùng sử dụng hình dạng này) và đặt giá trị bạn muốn như:

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

Và sau đó đặt theo kiểu ứng dụng của bạn:

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

Giải pháp của Gabriele Mariotti cũng tương tự và hoạt động nhưng giải pháp này đơn giản hơn.


So với các giải pháp khác, nó là một giải pháp tốt hơn nhiều, bởi vì hầu hết các giải pháp hiện có đều dựa trên bộ có thể vẽ tùy chỉnh
d-saucex

1
Có vẻ tốt đẹp. Điều này cũng áp dụng cho BottomSheetDialog?
Jaden Gu

1
Lưu ý cho tất cả: Sử dụng câu trả lời này sẽ khiến tất cả các thành phần sử dụng ShapeAppearance.MaterialComponents.LargeComponentcó cùng angleSize và family, không chỉ Bottom Sheet. Kiểm tra yêu cầu kiểu dáng của bạn và quyết định xem bạn muốn thay đổi giao diện cho tất cả thành phần hay chỉ thành phần hoặc tiện ích riêng lẻ.
nitinkumarp

9

Câu trả lời của Koma Yip từ một câu hỏi khác phù hợp với tôi, bạn nên thử nó.

Tạo một xml ở dạng có thể vẽ, nói hộp thoại_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>

đặt cái này vào nút gốc xml bố cục của bạn:

đặt nó làm nền trong xml bố cục của bạn

android:background="@drawable/dialog_bg"

onCreateView()đặt điều này:

đặt nền hộp thoại của bạn thành trong suốt

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

Đây phải là giải pháp phù hợp vì nó hoạt động với tất cả các đoạn DialogFragment mà không phải nhảy qua các vòng.
jssingh

3
Đối với tôi, vẫn có những góc trắng đằng sau những góc tròn của tôi. Vì vậy, khi tôi thay đổi màu có thể vẽ của mình thành màu đỏ, mã của bạn hoạt động chính xác và tạo ra một hình chữ nhật tròn màu đỏ, nhưng đằng sau đó vẫn còn một hình chữ nhật màu trắng mặc định. Đoạn mã "hộp thoại.getWindow (). SetBackgroundDrawable ..." mà bạn đã viết sẽ thay đổi màu của toàn bộ vùng "bị tối" phía trên hộp thoại của tôi, nhưng một lần nữa, nó lại bỏ lỡ hai góc nhỏ đó. Bạn có biết điều gì có thể gây ra vấn đề này không?
Nick Dev

Thêm vào nhận xét của tôi ở trên, tôi cần lưu ý rằng tôi đã phải thay đổi mã trong onCreateView () thành " getDialog () .getWindow () ..." để mã của tôi chạy. Có lẽ đây là lý do tại sao nó không hoạt động với tôi.
Nick Dev

1
@NickDev Đăng câu hỏi mới nếu bạn cho rằng giải pháp này không áp dụng cho mã của mình và có thể chúng tôi sẽ tìm ra giải pháp.
Variag

@Variag Cảm ơn bạn đã liên hệ; Tôi thực sự đã nghĩ ra một giải pháp rẻ tiền trong đó tôi che hộp thoại phương thức trang tính phía dưới mặc định bằng một hình chữ nhật có cùng màu với vùng tối đằng sau nó. Sau đó, tôi thêm một hình chữ nhật thứ hai với các góc tròn ở trên đó. Nó không lý tưởng, nhưng nó trông rất tuyệt! Tôi đánh giá cao sự giúp đỡ dù sao.
Nick Dev

8

Hôm nay tôi cũng đang kiểm tra điều tương tự và vâng bạn đã đúng khi làm theo mã

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

điều này áp dụng cho nền phân đoạn, vì vậy thay vào đó, bạn sẽ nhận được chế độ xem biểu đồ dưới cùng từ cửa sổ hộp thoại và thay đổi nền ở đây là mã

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

đây là dạng xem thực tế mà bạn muốn thay đổi.


Cách duy nhất để tôi làm việc này. Btw Tôi đang sử dụng BottomSheetDialogFragmentrất logic đó là trong onCreateDialogphương pháp
Kirill Starostin

6
  1. Tạo một hình dạng có thể vẽ được .. mà chúng tôi sẽ sử dụng làm nền cho trang tính dưới cùng. Cung cấp giá trị thích hợp cho bán kính của góc trên cùng bên trái và bên phải.

    <?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. Bây giờ hãy tạo kiểu cho "Đoạn hộp thoại trang tính dưới cùng"

    <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. Bây giờ, hãy tạo một lớp tùy chỉnh sẽ mở rộng BottomSheetDilogFragment, nơi bạn cung cấp phong cách của mình.

    open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
    
        override fun getTheme(): Int = R.style.BottomSheetDialogTheme
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
    
    }
    
  4. Bây giờ sử dụng lớp này ở bất cứ nơi nào bạn muốn có trang tính ở dưới góc tròn. ví dụ

    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

Nó đã làm việc cho tôi

tạo một hình dạng có tên 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" />

thêm phong cách bên dưới

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

Trong lớp DialogFragment, ghi đè phương thức getTheme cũng trả về kiểu dáng của Chính bạn.

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

4

Câu trả lời này chỉ dành cho vấn đề thiết lập màu nền Color.TRANSPARENTsau khi thiết lập một hình có thể vẽ với nền tròn cho bố cục.

Không có câu trả lời nào phù hợp để tôi đặt màu nền Color.TRANSPARENTngoại trừ setupDialog()giải pháp ghi đè :

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

NHƯNG các contentViewbạn đặt cho hộp thoại ở đây không phải là viewbạn nhận được trong onViewCreated()khi lạm phát trong onCreateView(). Nó phá vỡ quy trình tiêu chuẩn, do đó có thể gây ra sự cố như bạn không thể sử dụng View Bindings- Kotlin Android ExtensionstrongonViewCreated()

Vì vậy, tôi chỉnh sửa một chút để đặt nền trong onActivityCreated():

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

Hy vọng điều này giúp đỡ những người gặp khó khăn tương tự


2

Tôi biết câu hỏi này đã có một câu trả lời được chấp nhận. Tôi muốn ghi lại những vấn đề tôi đã trải qua và cách cuối cùng tôi đã làm cho nó hoạt động để nó hữu ích cho ai đó trong tương lai.

Thứ nhất, tôi đang sử dụng Theme.AppCompat.Light.DarkActionBarvới tư cách là cha mẹ của chúng tôi AppTheme. Điều này có nghĩa là giải pháp @Gabriele Mariotti tiếp tục gặp lỗi Could not inflate Behavior subclass com.google.android.material.bottomsheet.BottomSheetBehavior. Tôi đã sửa lỗi này bằng cách chỉ cần thay đổi cha mẹ thành Theme.MaterialComponents.Light.DarkActionBar. Điều này không ảnh hưởng đến chủ đề của chúng tôi theo bất kỳ cách nào nhưng RTE đã biến mất. Bạn cũng có thể khắc phục sự cố này bằng cách chỉ cần thêm các mục yêu cầu vào phong cách của bạn. Nhưng tôi không bận tâm đến việc tìm ra những kiểu được yêu cầu bởi BottomSheetBehavior.

Thứ hai, cố gắng hết sức có thể, nhưng tôi không thể có được bố cục Khung thực tế (là BottomSheetDialogFragment) sử dụng để có các góc tròn. Tôi nhận ra rằng cài đặt này thành hình ảnh có thể vẽ hoạt động nhưng không hoạt động với hình dạng hoặc a @null. Hóa ra, đó là bởi vì LinearLayouttôi đang sử dụng có nền được xác định. Điều này đã ghi đè lên bất kỳ nền nào trong phong cách. Loại bỏ mà cuối cùng dẫn đến các góc tròn.

Ngoài ra, tôi không yêu cầu bất kỳ hình nền nào được thiết lập để làm tròn các góc. Giải pháp của @Gabriele Mariotti đã hoạt động ngay sau khi tôi thực hiện các thay đổi ở trên. Tuy nhiên, để đặt màu nền như tôi muốn, tôi phải ghi đè mục "backgroundTint".

Tái bút: Tôi mới làm quen với nhà phát triển Android và đang duy trì một Ứng dụng cũ được tạo để sử dụng nội bộ trong trường Cao đẳng của chúng tôi. Tôi không quen thuộc với hệ thống bố cục của Android hoặc với thư viện tài liệu. Tôi đoán đó là lý do tại sao tôi mất 3 ngày để tìm ra điều này. Tôi hy vọng điều này sẽ hữu ích cho ai đó trong tương lai.


1

Thêm hai phương thức này vào lớp BottomsheetDialogFragment của bạn.

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

Bây giờ hãy gọi setDialogBorder(dialog)phương thức trong setupDialog()phương thức của lớp BottomsheetDialogFragment của bạn.

Bây giờ, hãy tạo một tệp hình dạng trong thư mục có thể vẽ của bạn.

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

Bây giờ đặt nền cho chế độ xem hộp thoại nhóm xem chính trong tệp xml.

android:background="@drawable/round_border_white"

Làm xong!!


Bạn sử dụng chế độ xem nào với setMargins?
tmm1

FrameLayout bottomSheet; Cái này được định nghĩa trong phương thức setDialogBorder (). Đây thực sự là chế độ xem mặc định cho hộp thoại trang tính dưới cùng trong Android. Nó sẽ hoạt động tốt.
DalveerSinghDaiya

0

Một cách khác để khắc phục sự cố này là mở rộng BottomSheetDialog và tạo một lớp tùy chỉnh phù hợp với nhu cầu của bạn. Bạn có thể làm tương tự đối với bố cục tệp xml và thêm nền hoặc bất kỳ tùy chỉnh nào khác cần thiết. Điều này cũng có một lợi ích là bạn sẽ không bị phụ thuộc vào tên id được Android sử dụng (android.support.design.R.id.design_bottom_sheet), trong khi thay đổi nền (mặc dù việc thay đổi tên id hiếm khi xảy ra AFAIK).


0

Tạo một tùy chỉnh có thể vẽ với góc tròn và đặt nó làm nền của gốc bố cục BottomSheetDialogFragment của bạn

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

Và sau đó chỉ cần thêm mã bên dưới vào lớp BottomSheetDialogFragment của bạn

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

Bạn thậm chí có thể chơi với các thông số để đặt lợi nhuận như bên dưới

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

0

Bạn phải thay đổi bottom sheet themeđể đạt được bố cục vòng trên cùng

Tạo background_bottom_sheet_dialog_fragment.xml có thể vẽ tùy chỉnh:

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

Sau đó ghi đè bottomSheetDialogTheme trên styles.xml bằng cách sử dụng có thể vẽ làm nền:

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

Điều này sẽ thay đổi bố cục nền của trang tính dưới cùng của bạn

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

thêm hình dạng với góc tròn, làm nền cho bố cục gốc của bạn

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

làm cho nền trong suốt trên BottomSheetDialogFragment của bạn

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

công việc của nó cho Contraintlayout, Framelyaout, Linearlayout, Relativelayout.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.