简体   繁体   English

如何实现具有固定高度的BottomSheetDialogFragment

[英]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 请尝试以下代码

在此输入图像描述

  1. Create layout xml file for bottomsheet dialog fragment 为底部对话框片段创建布局xml文件

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>

  1. Create class for bottom sheet fragment that should extends BottomSheetDialogFragment 为底部工作表片段创建应扩展BottomSheetDialogFragment的类

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();
}}
  1. Add these lines in your styles.xml. 在styles.xml中添加这些行。 styles.xml styles.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/rounded_dialog</item> </style> 

  1. Rounded shaped drawable for your bottom sheet. 圆形可拉式底板。 Add this file in your drawables folder. 在drawables文件夹中添加此文件。

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> 

  1. Finally in your activity call this dialog fragment as follows. 最后在您的活动中调用此对话框片段如下。 Here i have called fragment onClick of bottomNavigationView item onClick listener. 在这里,我已经调用了onClick listener上的bottomNavigationView项的片段onClick。

  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.

相关问题 如何保持 BottomSheetDialogFragment 高度始终匹配父级? - How can I keep a BottomSheetDialogFragment height to always match_parent? 如何在 BottomSheetDialogFragment 中设置最大高度? - How to set max height in BottomSheetDialogFragment? 如何使BottomSheetDialogFragment非模态? - How can I make a BottomSheetDialogFragment non-modal? 我可以在 BottomSheetDialogFragment 上修复键盘吗? - Can I fix keyboard on BottomSheetDialogFragment? 如何降低BottomSheetDialogFragment的进入和退出动画速度? - How can I reduce the entry and exit animation speed of BottomSheetDialogFragment? 如何在 Android XML 中创建具有固定高度的垂直线? - How can I create a vertical line with fixed height in Android XML? 如何在android 2.2中实现固定位置搜索栏? - How can I implement a fixed position search bar in android 2.2? BottomSheetDialogFragment 如何与其宿主片段通信? - How can a BottomSheetDialogFragment communicate with its host fragment? 如何向BottomSheetDialogFragment添加动画 - How do I add animation to BottomSheetDialogFragment BottomSheetDialogFragment - 如何设置展开高度(或最小顶部偏移) - BottomSheetDialogFragment - How to set expanded height (or min top offset)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM