[英]How can I implement BottomSheetDialogFragment with fixed height
I need to implement BottomSheetDialogFragment
and face with the problem. 我需要实现
BottomSheetDialogFragment
并面对问题。 I need that my BottomSheetDialogFragment
has fixed height. 我需要我的
BottomSheetDialogFragment
具有固定的高度。 Does anyone has an idea how to do it? 有谁知道怎么做?
Here is my xml of fragment content 这是我的片段内容的xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_height"
android:background="@android:color/white"
android:orientation="vertical">
<TextView
android:id="@+id/drag_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="#FF0000"
android:text="Title"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@android:color/white"
android:layout_weight="1"/>
<TextView
android:id="@+id/ok_button"
android:layout_width="match_parent"
android:layout_height="54dp"
android:background="@android:color/holo_blue_dark"
android:gravity="center"
android:text="Hello"
android:textColor="@android:color/white"
android:textSize="24sp"/>
</LinearLayout>
And in the setupDialog()
I am doing this: 在
setupDialog()
我这样做:
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null);
dialog.setContentView(contentView);
CoordinatorLayout.LayoutParams layoutParams = ((CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams());
CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
if (behavior != null && behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(bottomSheetCallback);
((BottomSheetBehavior) behavior).setPeekHeight(getResources().getDimensionPixelSize(R.dimen.bottom_sheet_height));
}
initRecyclerView(contentView);
}
And behavior is quite common: 行为很常见:
private BottomSheetBehavior.BottomSheetCallback bottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
};
UPD: Solved by set the fixed height to RecyclerView. UPD:通过将固定高度设置为RecyclerView来解决。 Does anyone know the better approach?
有谁知道更好的方法?
You can directly give the fix height by Creating it style. 您可以通过创建样式直接给出修复高度。
in styles.xml
在
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="behavior_peekHeight">500dp</item>
</style>
Update : 更新:
BottomSheetDialog dialog = new BottomSheetDialog(this, R.style.BottomSheetDialog);
dialog.setContentView(R.layout.layout_bottom_sheet);
dialog.show();
Or Second Approch : 或第二个Approch:
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if( behavior != null && behavior instanceof BottomSheetBehavior ) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
((BottomSheetBehavior) behavior).setPeekHeight(300);
}
If the RecyclerView
content is filled inside initRecyclerView(contentView);
如果在
initRecyclerView(contentView);
填充RecyclerView
内容initRecyclerView(contentView);
then when showing BottomSheet
it's height is well known. 然后在显示
BottomSheet
它的高度是众所周知的。 To set the height of BottomSheet
dynamically and to wrap the content then add global layout listener inside onResume
function of the BottomSheetDialogFragment
: 要动态设置
BottomSheet
的高度并包装内容,请在BottomSheetDialogFragment
onResume
函数中添加全局布局侦听器:
@Override
public void onResume() {
super.onResume();
addGlobaLayoutListener(getView());
}
private void addGlobaLayoutListener(final View view) {
view.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
setPeekHeight(v.getMeasuredHeight());
v.removeOnLayoutChangeListener(this);
}
});
}
public void setPeekHeight(int peekHeight) {
BottomSheetBehavior behavior = getBottomSheetBehaviour();
if (behavior == null) {
return;
}
behavior.setPeekHeight(peekHeight);
}
private BottomSheetBehavior getBottomSheetBehaviour() {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) ((View) getView().getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
if (behavior != null && behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
return (BottomSheetBehavior) behavior;
}
return null;
}
Try following code 请尝试以下代码
layout_bottom_sheet_dialog_fragment.xml layout_bottom_sheet_dialog_fragment.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_bottomSheetFrag_userProf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:padding="5dp">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_profile_icon_nav_d"
app:civ_border_width="1dp"
app:civ_border_color="@color/main_white"
android:layout_height="70dp"
android:layout_width="70dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:contentDescription="@string/nav_header_desc"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:paddingBottom="@dimen/nav_header_vertical_spacing"
android:id="@+id/iv_bottomSheetFrag_userPic">
</de.hdodenhof.circleimageview.CircleImageView>
<!-- name & email -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_bottomSheetFrag_userName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:gravity="center|start"
android:textSize="20sp"
android:layout_weight="9"
android:theme="@style/styleFontMediumText"
android:text="@string/user_name"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@color/black" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_bottomSheetFrag_closeDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="gone"
android:contentDescription="@string/app_name"
android:src="@drawable/ic_close_black_24dp"
/>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_bottomSheetFrag_userEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|start"
android:textSize="14sp"
android:theme="@style/styleFontRegularText"
android:textColor="@color/primaryLightColor"
android:text="@string/user_email" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/divider_color"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"/>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view_bottomSheetFrag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:elevation="0dp"
app:itemTextAppearance="@style/NavDrawerTextStyle"
app:itemBackground="@android:color/transparent"
app:itemIconTint="@color/nav_drawer_item_color_state"
app:itemTextColor="@color/nav_drawer_item_color_state"
app:menu="@menu/menu_bottom_sheet" />
</androidx.appcompat.widget.LinearLayoutCompat>
BottomSheetFragment.java BottomSheetFragment.java
public class BottomSheetFragment extends BottomSheetDialogFragment{
@BindView(R.id.iv_bottomSheetFrag_closeDialog) AppCompatImageView iv_closeDialog;
@BindView(R.id.nav_view_bottomSheetFrag_salesPerson) NavigationView nav_view;
private Context context;
//public constructor
public BottomSheetFragment() {
}
//create custom theme for your bottom sheet modal
@Override
public int getTheme() {
//return super.getTheme();
return R.style.AppBottomSheetDialogTheme;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//return super.onCreateDialog(savedInstanceState);
return new BottomSheetDialog(requireContext(), getTheme()); //set your created theme here
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void setupDialog(@NonNull Dialog dialog, int style)
{
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.layout_bottom_sheet_dialog_fragment, null);
context = contentView.getContext();
ButterKnife.bind(this, contentView);
dialog.setContentView(contentView);
//tv_title.setText(getString(R.string.app_name)); R.style.AppBottomSheetDialogTheme
DisplayMetrics displayMetrics = getActivity().getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
int maxHeight = (int) (height*0.44); //custom height of bottom sheet
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
((BottomSheetBehavior) behavior).setPeekHeight(maxHeight); //changed default peek height of bottom sheet
if (behavior != null && behavior instanceof BottomSheetBehavior)
{
((BottomSheetBehavior) behavior).setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback()
{
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState)
{
String state = "";
switch (newState)
{
case BottomSheetBehavior.STATE_DRAGGING: {
//imgBtnClose.setVisibility(View.INVISIBLE);
iv_closeDialog.setVisibility(View.GONE);
state = "DRAGGING";
break;
}
case BottomSheetBehavior.STATE_SETTLING: {
// imgBtnClose.setVisibility(View.INVISIBLE);
iv_closeDialog.setVisibility(View.GONE);
state = "SETTLING";
break;
}
case BottomSheetBehavior.STATE_EXPANDED: {
// imgBtnClose.setVisibility(View.VISIBLE);
iv_closeDialog.setVisibility(View.VISIBLE);
state = "EXPANDED";
break;
}
case BottomSheetBehavior.STATE_COLLAPSED: {
//imgBtnClose.setVisibility(View.INVISIBLE);
iv_closeDialog.setVisibility(View.GONE);
state = "COLLAPSED";
break;
}
case BottomSheetBehavior.STATE_HIDDEN: {
// imgBtnClose.setVisibility(View.INVISIBLE);
iv_closeDialog.setVisibility(View.GONE);
dismiss();
state = "HIDDEN";
break;
}
}
Log.i("BottomSheetFrag", "onStateChanged: "+ state);
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
//close dialog
iv_closeDialog.setOnClickListener(view -> dismiss());
}
@Override
public void onDestroyView() {
super.onDestroyView();
}}
<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>
rounded_dialog.xml 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>
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = item -> { Fragment selectedFragment = null; switch (item.getItemId()) { case R.id.bNav_menu: BottomSheetFragment bf = new BottomSheetFragment(); bf.show(getSupportFragmentManager(), bf.getTag()); //bf.setArguments(bundle); return true; } };
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.