カスタムの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"/>
しかし、問題は、このリソースファイルをレイアウトのルート要素の背景として設定すると、角が丸くならないことです
そして、私は以下のコードを使用することはできません:
this.getDialog().getWindow().setBackgroundDrawableResource(R.drawable.charge_layout_background);
なぜなら、BottomSheetDialogのデフォルトの背景をオーバーライドし、Bottom Viewの上に半透明のグレー色が表示されないからです。
カスタムドローアブル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>
次に、ドローアブルを背景として使用して、styles.xml
のbottomSheetDialogTheme
をオーバーライドします。
<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が変更されます。
BottomSheetDialog
はデフォルトの白い背景色を設定しているため、コーナーは表示されません。それらを表示するには、BottomSheetDialog
のスタイルをオーバーライドしてダイアログの背景を透明にする必要があります。
このスタイルを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();
私は今日同じことをチェックしていました
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);
}
ここで、ボトムシートは、変更する実際のビューです。
Koma Yip from 別の質問 で答えてくれたので、試してみてください。
Drawableに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));
_
public class CustomDialogFragment extends BottomSheetDialogFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NORMAL, R.style. AppBottomSheetDialogTheme);
}
...
}
<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/rail_bottom_sheet_dialog_bg</item>
</style>
新しい Material Component ライブラリを使用すると、次のようにshapeAppearanceOverlay
属性を使用してコンポーネントの 形状をカスタマイズ できます。あなたのスタイル。
BottomSheetDialogFragment
を使用してonCreateView
メソッドをオーバーライドしてから、ボトムシートダイアログのカスタムスタイルを定義します。
アプリテーマのstyles.xml
でbottomSheetDialogTheme
属性を定義します。
<!-- 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>
ボトムシートの背景として使用するシェイプドローアブルを作成します。左上および右隅の半径に適切な値を指定します。
<?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>
「ボトムシートダイアログフラグメント」のスタイルを作成します
<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" />
次に、スタイルを指定するBottomSheetDilogFragmentを拡張するカスタムクラスを作成します。
open class CustomRoundBottomSheet : BottomSheetDialogFragment() {
override fun getTheme(): Int = R.style.BottomSheetDialogTheme
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
}
丸い角のボトムシートが必要な場合は、このクラスを使用してください。例えば
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)
}
}
BottomsheetDialogFragmentクラスにこれらの2つのメソッドを追加します。
_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();
}
}
_
次に、BottomsheetDialogFragmentクラスのsetDialogBorder(dialog)
メソッドでsetupDialog()
メソッドを呼び出します。
次に、描画可能フォルダーに形状ファイルを作成します。
_<?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"
_
できた!!
この問題を修正するもう1つの方法は、BottomSheetDialogを拡張し、ニーズに合ったカスタムクラスを作成することです。レイアウトxmlファイルについても同じことができ、背景やその他の必要なカスタマイズを追加できます。これには、Androidが使用するID名(android.support.design.R.id.design_bottom_sheet)に依存しないという利点もありますが、背景を変更します(ただし、ID名の変更はほとんど行われません)。
この回答は、レイアウトに丸みを帯びた背景を持つドロアブルを設定した後、背景色を_Color.TRANSPARENT
_に設定する問題についてのみです。
setupDialog()
ソリューションをオーバーライドすることを除いて、背景色を_Color.TRANSPARENT
_に設定するための答えはありませんでした:
_@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));
}
_
[〜#〜] but [〜#〜]ここでダイアログに設定するcontentView
は、onViewCreated()
で取得するview
ではありませんonCreateView()
の膨張。標準フローを壊すため、onViewCreated()
で_View Bindings
_-_Kotlin Android Extensions
_を使用できないなどの問題が発生する可能性があります
そこで、onActivityCreated()
で背景を設定するために少し調整します。
_override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(view?.parent as View).setBackgroundColor(Color.TRANSPARENT)
}
_
同じトラブルを抱えたこの助けを願っています
角が丸いカスタムDrawableを作成し、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で遊ぶこともできます
params.setMargins(50, 0, 50, 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>
次に、drawableを背景として使用して、styles.xmlのbottomSheetDialogThemeをオーバーライドします。
<!--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
}