简体   繁体   中英

How to always align button to screen bottom in a bottom sheet dialog fragment

I have a custom class extending BottomSheetDialogFragment which will be displayed on click of the button. My custom BottomSheetDialogFragment layout has 3 parts.

aA Title text,

bA radio group (to which I add n items dynamically)

c.An OK button at the bottom(which I wanted to display always at the bottom)

This is how it looks on my button click. 在此处输入图像描述

Actually at the first time when my dialog fragment is launched, my OK button is not visible.However when I expand the BottomSheet, it looks like the below and my OK button is visible在此处输入图像描述

But what I need is to show my bottom OK button always, ie when my dialog fragment is launched,my OK button should be present at the bottom irrespective of the number of radio buttons it has and when it is expanded, then also OK button should be at the bottom and my radio buttons should be scrollable .

Below is my dialog fragment layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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="wrap_content"
>

<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/nested_scroll_view"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="25dp"
        android:layout_marginRight="20dp"
        android:layout_alignParentTop="true"
        android:text=""
        />


    <RadioGroup
        android:id="@+id/radiogroup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="15dp"
        android:layout_below="@id/title"
        android:layout_marginBottom="10dp"
        >
    </RadioGroup>


    <android.widget.Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ok"
        android:layout_below="@id/radiogroup"
        android:text="OK"
        android:layout_marginTop="10dp"
        android:layout_alignParentBottom="true"
        ></android.widget.Button>

</RelativeLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

This is my custom BottomSheetDialogFragment

public class BottomSheetExample extends BottomSheetDialogFragment {

@BindView(R.id.title)
TextView title;

@BindView(R.id.ok)
Button ok;

@BindView(R.id.nested_scroll_view)
NestedScrollView nestedScrollView;

@BindView(R.id.radiogroup)
RadioGroup radioGroup;

// TODO: Rename and change types of parameters

public BottomSheetExample() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.bottom_sheet, container, false);

    ButterKnife.bind(this, view);

    ArrayList<String> list = new ArrayList<>();
    for(int i=0;i<15;i++){
        list.add(""+i);
    }

    title.setText("Numbers");

    RadioGroup rg = radioGroup;

    for (int i = 0; i < list.size(); i++) {
        RadioButton rbn = new RadioButton(getContext());
        rbn.setId(View.generateViewId());
        String radioButtonText = list.get(i);
        rbn.setText(radioButtonText);
        rg.addView(rbn);
    }

    return view;
}   
}

This is how I call my bottomsheet:

BottomSheetExample bottomSheet = new BottomSheetExample();
bottomSheet.showNow(this.getSupportFragmentManager(), "tag");

Any inputs will be highly useful.Thanks in advance!

Finally, I have found a fix.

1.Inorder to make use of the bottomsheet properly,Im using coordinatorlayout and the top LinearLayout has a bottom sheet behaviour

2.I have made the radiogroup fit inside a nestedscrollview.I want the max height of nestedscrollview to be fixed.But unfortunately, there is no max height method . So a LinearLayout accomodates the nestedscrollview inside which we have the radiogroup. And now I have set the height of the linearlayout to say 300dp.The layout part is done

3.Now we have to fix the bottomsheet part. Get the BottomSheetBehaviour instance from the top LinearLayout mentioned in 1.So now set the peek height of the bottomsheet to say 300dp.This is done to fix the bottom sheet to a particular height whcih would fit the use case mentioned in the question.

XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout                 
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"
>

<LinearLayout
    android:id="@+id/bottom_sheet_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:textStyle="bold"
            android:textSize="20sp"
            />

        <LinearLayout
            android:layout_below="@id/title"
            android:id="@+id/scroll_layout"
            android:layout_width="match_parent"
            android:layout_height="300dp">

            <androidx.core.widget.NestedScrollView
                android:id="@+id/nested_scroll_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fillViewport="true"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">


                <RadioGroup
                    android:id="@+id/radiogroup"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/title"
                    android:layout_marginBottom="10dp" />

            </androidx.core.widget.NestedScrollView>

        </LinearLayout>

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="OK"
            android:id="@+id/click_btn"
            android:layout_below="@id/scroll_layout"/>

    </RelativeLayout>

</LinearLayout>

JAVA:

public class BottomSheetExample extends BottomSheetDialogFragment {

@BindView(R.id.title)
TextView title;

@BindView(R.id.click_btn)
Button ok;

@BindView(R.id.nested_scroll_view)
NestedScrollView nestedScrollView;

@BindView(R.id.radiogroup)
RadioGroup radioGroup;

@BindView(R.id.bottom_sheet_layout)
LinearLayout bottomSheetLayout;

private BottomSheetBehavior sheetBehavior;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.bottom_sheet, container, false);
    ButterKnife.bind(this, view);
    sheetBehavior = BottomSheetBehavior.from(bottomSheetLayout);
    sheetBehavior.setPeekHeight(R.dimen.peek_height);//put this ub dimens.xml (300dp)
    ArrayList<String> list = new ArrayList<>();
    for (int i = 0; i < 15; i++) {
        list.add("" + i);
    }
    title.setText("Numbers");
    RadioGroup rg = radioGroup;
    for (int i = 0; i < list.size(); i++) {
        RadioButton rbn = new RadioButton(getContext());
        rbn.setId(View.generateViewId());
        String radioButtonText = list.get(i);
        rbn.setText(radioButtonText);
        rg.addView(rbn);
    }
    return view;
}

}

This solution actually works for me.. Any suggestions for improvements are always welcome !!

Can you try this, putting button wrapped in relative layout outside the nested scroll view may do the job.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:orientation="vertical">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nested_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="25dp"
                android:layout_marginRight="20dp"
                android:text="" />


            <RadioGroup
                android:id="@+id/radiogroup"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/title"
                android:layout_marginLeft="15dp"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="10dp"/>

        </RelativeLayout>

    </androidx.core.widget.NestedScrollView>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.widget.Button
            android:id="@+id/ok"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom"
            android:layout_marginTop="10dp"
            android:gravity="bottom"
            android:text="OK" />

    </RelativeLayout>

</LinearLayout>

Check this turial: https://proandroiddev.com/android-bottom-sheet-behavior-and-animated-button-on-top-of-it-da86a9bfe545

You need to create a listener for bottom sheet behavior and change the button position on the fly taking into account if the bottom is slided by the user or not

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM