Reputation: 5374
I want to try BottomSheetDialog introduced in Android Support Library 23.2 but it doesn't seem to work correctly. Here is what the doc says:
While BottomSheetBehavior captures the persistent bottom sheet case, this release also provides a BottomSheetDialog and BottomSheetDialogFragment to fill the modal bottom sheets use case. Simply replace AppCompatDialog or AppCompatDialogFragment with their bottom sheet equivalents to have your dialog styled as a bottom sheet."
So I changed my AppCompatDialog
to BottomSheetDialog
:
package my.package.ui.dialog;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.BottomSheetDialog;
import my.package.R;
public class AccountActionsDialog extends BottomSheetDialog {
public AccountActionsDialog(Context context) {
super(context);
if (context instanceof Activity) {
setOwnerActivity((Activity) context);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutInflater().inflate(R.layout.dialog_account_actions, null));
}
}
Here is my layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000"
android:padding="16dp"
android:text="Delete account"
android:textColor="#ffffff" />
</LinearLayout>
Then I use the following code in my Activity:
new AccountActionsDialog(this).show();
My screen becomes dimmed but the content of my dialog is not visible. Any thoughts on what might be missing? It works fine when I use AppCompatDialog instead.
Upvotes: 38
Views: 50821
Reputation: 379
To open bottom sheet dialog use following code.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:orientation="vertical">
<TextView
android:id="@+id/choosetxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Please verify your SIM Card."
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20dp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/layoutEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="8dp">
<TextView
android:id="@+id/tv_bottom_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>
<ProgressBar
android:id="@+id/loadingBottom_progress_xml"
style="?android:attr/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:visibility="gone" />
<TextView
android:id="@+id/tv_inProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="Verification in progress."
android:textColor="@color/black"
android:textSize="15dp"
android:textStyle="bold"
android:visibility="invisible" />
<Button
android:id="@+id/btn_verifyss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/roundbutton"
android:text="START SIM VERIFICATION"
android:textColor="@color/white" />
<LinearLayout
android:id="@+id/linear_congrats"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/tv_verifys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="Congratulations. Given Number Successfully Verified."
android:textColor="@color/black"
android:textSize="15dp"
android:textStyle="bold" />
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:src="@drawable/success" />
</LinearLayout>
</LinearLayout>
Upvotes: 0
Reputation: 15535
Instead of having a separate class, you can simply create an instance for BottomSheetDialog in your Activity/Fragment like following and you can use it. It is very easier and simpler I think.
val dialog = BottomSheetDialog(this)
val bottomSheet = layoutInflater.inflate(R.layout.bottom_sheet, null)
bottomSheet.buttonSubmit.setOnClickListener { dialog.dismiss() }
dialog.setContentView(bottomSheet)
dialog.show()
Upvotes: 14
Reputation: 50578
I was expriencing the same issue, dimmed background and content not visible. Here is how I managed to workaround it by setting the content view in setupDialog()
hidden method.
public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {
private TextView mOffsetText;
private TextView mStateText;
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
setStateText(newState);
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
setOffsetText(slideOffset);
}
};
private LinearLayoutManager mLinearLayoutManager;
private ApplicationAdapter mAdapter;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
@Override
public void onViewCreated(View contentView, @Nullable Bundle savedInstanceState) {
super.onViewCreated(contentView, savedInstanceState);
}
@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);
mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
if (mBottomSheetBehavior != null) {
mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
mOffsetText = (TextView) contentView.findViewById(R.id.offsetText);
mStateText = (TextView) contentView.findViewById(R.id.stateText);
}
}
And the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/offsetText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black" />
<TextView
android:id="@+id/stateText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Upvotes: 2
Reputation: 5374
It started to work when I set fixed height for my TextView (200dp), although for some height values it still behaves incorrectly. Obviously it's an issue of support lib. There are already few reports related to BottomSheetDialog in the bug tracker:
https://code.google.com/p/android/issues/detail?id=201826
Upvotes: 1
Reputation: 96
Here's the issue on code.google.com https://code.google.com/p/android/issues/detail?id=201793
An issue some users are seeing boils down to the FrameLayout that wraps our content view being centered vertically. The BottomSheetBehavior only works if this view is top aligned. I haven't figured out what causes the FrameLayout to become centered vertically yet, but here's a possible workaround:
View contentView = ...
// You may have to measure your content view first.
dialog.setContentView(contentView);
// Change this to a percentage or a constant, whatever you want to do.
// The default is 1024 - any views smaller than this will be pulled off
// the bottom of the screen.
float peekHeight = contentView.getMeasuredHeight();
View parent = (View)contentView.getParent();
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
behavior.setPeekHeight(peekHeight);
CoordinatorLayout.LayoutParams layoutParams =
(CoordinatorLayout.LayoutParams)parent.getLayoutParams();
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
Upvotes: 2
Reputation: 51
This is the layout file of BottomSheetDialog.
<android.support.design.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"
android:soundEffectsEnabled="false">
<FrameLayout
android:id="@+id/design_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:layout_behavior="@string/bottom_sheet_behavior"
style="?attr/bottomSheetStyle"/>
</android.support.design.widget.CoordinatorLayout>
Your content view is inside the view design_bottom_sheet
, it will be positioned center vertically by CoordinatorLayout
, and BottomSheetBehavior
will offset it.
mParentHeight = parent.getHeight();
mMinOffset = Math.max(0, mParentHeight - child.getHeight());
mMaxOffset = mParentHeight - mPeekHeight;
if (mState == STATE_EXPANDED) {
ViewCompat.offsetTopAndBottom(child, mMinOffset);
} else if (mHideable && mState == STATE_HIDDEN) {
ViewCompat.offsetTopAndBottom(child, mParentHeight);
} else if (mState == STATE_COLLAPSED) {
ViewCompat.offsetTopAndBottom(child, mMaxOffset);
}
It intented to positon design_bottom_sheet
at mMaxOffset
, but actually the initial getTop of the child view is not 0, but (mParentHeight - childHeight) / 2
, so you view if offset more than the desired offset.
Find the view design_bottom_sheet
and set its gravity to Gravity.TOP | Gravity.CENTER_HORIZONTAL
will fix it. But, if the childHeight is less than mPeekHeight, there will be blank area below you content view.
However, if peekHeight > childHeight
, the mMaxOffset
will less than mMinOffset
, which will cause weird behavior.
Maybe the code should be changed to
mMaxOffset = Math.max((mParentHeight - mPeekHeight), mMinOffset);
insted of
mMaxOffset = mParentHeight - child.getHeight();
Upvotes: 4