Android: BottomSheetDialog does not expand completely with ConstraintLayout - android

I am using ConstraintLayout for my layout. I am creating a BottomSheetDialog and setting the layout to it which uses the ConstraintLayout at top.
Note: If i use LinearLayout everything works fine and BottomSheetDialog takes proper height but when i am using
ConstraintLayout, it shows only one option.
Please find the screenshot below when i am using ConstraintLayout:
My xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:orientation="vertical"
android:background="#color/white">
<TextView
android:id="#+id/tv_other_methods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/from_other_methods"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17" />
<View
android:id="#+id/view_other_methods"
android:layout_width="match_parent"
android:layout_height="#dimen/dip_1"
android:background="#color/light_grey"
app:layout_constraintBottom_toBottomOf="#id/tv_other_methods" />
<TextView
android:id="#+id/tv_FromChinaUnionPay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/from_china_union_pay"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17"
app:layout_constraintBottom_toBottomOf="#id/view_other_methods"
app:layout_constraintTop_toTopOf="#id/view_FromChinaUnionPay" />
<View
android:id="#+id/view_FromChinaUnionPay"
android:layout_width="match_parent"
android:layout_height="#dimen/dip_1"
android:background="#color/light_grey"
app:layout_constraintBottom_toBottomOf="#id/tv_FromChinaUnionPay" />
<TextView
android:id="#+id/tv_Cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/cancel"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17"
app:layout_constraintTop_toBottomOf="#+id/view_FromChinaUnionPay" />
</android.support.constraint.ConstraintLayout>
My java code for BottomSheetDialog:
final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(mContext);
bottomSheetDialog.setContentView(R.layout.dialog_web_view_options);
// dialog.setCancelable(false);
final Window window = bottomSheetDialog.getWindow();
assert window != null;
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setLayout(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT);
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
window.getDecorView().setPadding(20, 0, 20, 0);
bottomSheetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
FrameLayout bottomSheet = bottomSheetDialog.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setSkipCollapsed(true);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
In my layout if i replaceConstraintLayout with LinearLayout then it works fine and takes full height. Please let me know if i am doing something wrong.
I have tried these solutions but nothing worked:
Set state of BottomSheetDialogFragment to expanded
BottomSheetDialogFragment - How to set expanded height (or min top offset)
Android BottomSheetDialogFragment does not expand completely
Any help will be appreciated. Thanks!

You haven't constrained all the views - the first TextView has no constraints whatsoever . The constraints you added aren't properly specified to correctly display the views in vertical order. I suggest creating a vertical chain of all the views with the parent ConstraintLayout's layout_height set to wrap_content. The XML should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:background="#color/white">
<TextView
android:id="#+id/tv_other_methods"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/from_other_methods"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17"
app:layout_constraintBottom_toTopmOf="#id/view_other_methods"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/view_other_methods"
android:layout_width="0dp"
android:layout_height="#dimen/dip_1"
android:background="#color/light_grey"
app:layout_constraintBottom_toTopOf="#id/tv_FromChinaUnionPay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_other_methods" />
<TextView
android:id="#+id/tv_FromChinaUnionPay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/from_china_union_pay"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17"
app:layout_constraintBottom_toTopOf="#id/view_FromChinaUnionPay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view_other_methods" />
<View
android:id="#+id/view_FromChinaUnionPay"
android:layout_width="0dp"
android:layout_height="#dimen/dip_1"
android:background="#color/light_grey"
app:layout_constraintBottom_toTopOf="#id/tv_Cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_FromChinaUnionPay" />
<TextView
android:id="#+id/tv_Cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/ripple"
android:gravity="center_horizontal"
android:padding="#dimen/dp_12"
android:text="#string/cancel"
android:textColor="#color/blue"
android:textSize="#dimen/sp_17"
app:layout_constraintTop_toBottomOf="#+id/view_FromChinaUnionPay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
As a side note, it is not advised to use match_parent for any views inside a ConstraintLayout as the documentation suggests:
Important: MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent".

Related

Make top of view to be before end of other view ConstraintLayout

I want to achieve A UI where I have Two views VIEW1, VIEW2 with these constraints
VIEW1 has height of wrap_content
VIEW2 should it's top to be before end of VIEW1 with 10dp for example.
Final UI i want with Code
Another solution by using
a view with fixed height that equal to how many dp VIEW2 should start before end of VIEW1.
full code(also has same ending corners to bottom) ::
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<TextView
android:id="#+id/mainContent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/faded_orange"
android:text="TextView"
android:translationY="0dp"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="#id/space"
app:layout_constraintBottom_toBottomOf="#id/space2"
app:layout_constraintStart_toStartOf="#id/space" />
<Space
android:id="#+id/space"
android:layout_width="match_parent"
android:layout_height="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#id/topLayout"
/>
<Space
android:id="#+id/space2"
android:layout_width="match_parent"
android:layout_height="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/bottomLayout"
/>
<TextView
android:id="#+id/topLayout"
android:layout_width="0dp"
android:layout_height="#dimen/_100sdp"
android:background="#drawable/header_bg"
android:text="TextView"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/bottomLayout"
android:layout_width="0dp"
android:layout_height="#dimen/_100sdp"
android:background="#drawable/bg_bottom_view"
android:text="TextView"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
As you know, setting layout_marginTop="-10dp" will not work too.
You can try setting translationY="-10dp" to VIEW2 then it will work.
You can do something like this.
A Top View ( View 1 ) with constraints of top, start and end of parent.
A Bottom ( View 2 ) with constraints topToBottomOf = View 1.
Add a rounded rectangle ( View 3 ) with topToBottomOf = View 1 and height = 10dp or whatever the overlap height you want to have.
As I understand you want view same as you added UI Image. This UI can be achieved using Guideline.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<TextView
android:id="#+id/textview9"
android:layout_width="0dp"
android:layout_height="#dimen/_100sdp"
android:background="#color/bg_counter"
android:text="textview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.13" />
<TextView
android:id="#+id/textview10"
android:layout_width="#dimen/_80sdp"
android:layout_height="0dp"
android:background="#color/colorAccent"
android:text="textview"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>

Align 2 views bottoms but one is pushed lower further

If I have a constraint layout like this
<android.support.constraint.ConstraintLayout >
<TextView
android:layout_width="200dp"
android:layout_height="50dp"
android:text = "Some text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/preview"
app:layout_constraintTop_toTopOf="#+id/parent">
/>
<Button
android:layout_width="57dp"
android:layout_height="281dp"
app:layout_constraintBottom_toBottomOf="#+id/textview"
app:layout_constraintEnd_toEndOf="#+id/textview"
app:layout_constraintStart_toStartOf="#+id/textview">
/>
</android.support.constraint.ConstraintLayout>
Where textview is another widget. then this will make the button and the textview bottom boundaries aligned.
Is there anyway where I can push button 10dp lower? So I want the button bottom to be anchored to the bottom of the textview however I wanted to be pushed a bit lower by 10dp. I tried to set the android:layout_marginBottom="-10dp" but that didn't work!
Any idea?
use android:layout_marginTop="10dp" in your button layout
Put them in a FrameLayout, with layout_height="wrap_content". Then, set layout_gravity="bottom" on both the child Views. Give your TextView layout_marginBottom="10dp".
The result should be something like (this is a skeleton with only the relevant attrs):
<ConstraintLayout>
<FrameLayout
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_marginBottom="10dp"
android:layout_gravity="bottom"
/>
<Button
android:layout_gravity="bottom"
/>
</FrameLayout>
</ConstraintLayout>
in java or kotlin seet textview.bringToFront();
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="#+id/button"
android:layout_width="157dp"
android:layout_height="140dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/textview"
android:layout_width="150dp"
android:layout_height="50dp"
android:text = "Some text"
android:gravity="center"
android:textSize="15sp"
android:textColor="#05afaf"
app:layout_constraintBottom_toBottomOf="#id/button"
app:layout_constraintStart_toStartOf="#id/button"
app:layout_constraintEnd_toEndOf="#id/button"
android:layout_marginBottom="20dp"
/>
</android.support.constraint.ConstraintLayout>

Margin below <TextView/> in <ConstraintLayout/> not working

There is a simple layout with TextView and RecyclerView inside a ConstraintLayout.
<android.support.constraint.ConstraintLayout
android:id="#+id/clSelectedPatient"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvSelectPatient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lifcare"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="100dp"
app:layout_constraintBottom_toTopOf="#+id/rvPatients"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvPatients"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintTop_toBottomOf="#+id/tvSelectPatient"/>
</android.support.constraint.ConstraintLayout>
android:layout_marginBottom="100dp" below TextView is not working.
There are a few mistakes in your layout:
You use match_parent for width and using match_parent is prohibited for ConstraintLayout subviews.
Build a Responsive UI with ConstraintLayout - Adjust the view size
Note: You cannot use match_parent for any view in a ConstraintLayout.
Instead use "match constraints" (0dp)
In order to display vertical margins properly, you have to define vertical constraints for TextView and RecyclerView.
Your fixed layout code would look like:
<android.support.constraint.ConstraintLayout
android:id="#+id/clSelectedPatient"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvSelectPatient"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:text="Lifcare"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#+id/rvPatients" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvPatients"
android:layout_width="0dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvSelectPatient"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
And this is how it looks on device:
Add
app:layout_constraintBottom_toBottomOf="parent"
to your RecyclerView

Using ConstraintLayout with custom Android Dialog

I'm creating a custom Dialog by extending Dialog and using setContentView(). The problem is when I try to show the Dialog it only shows the background shadow instead of my custom layout. I've managed to get the custom layout to show by wrapping it in a RelativeLayout, but I'm wondering if there is a better solution or something I'm doing wrong. Using constraintLayout version 1.0.2. Thanks!
Here is my Custom Dialog:
class EventsFilterDialog(context: Context): Dialog(context) {
init {
setContentView(R.layout.dialog_events_filter)
setCancelable(true)
}
}
Here is a simplified version of my R.layout.dialog_events_filter that has the exact same result:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/headerTv"
android:text="#string/events_filters"
android:textColor="#color/white"
android:textSize="18sp"
android:textStyle="bold"
android:gravity="center"
android:background="#color/colorPrimaryLight"
android:padding="16dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<View
android:id="#+id/middleView"
android:layout_width="0dp"
android:layout_height="256dp"
app:layout_constraintTop_toBottomOf="#+id/headerTv"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="#+id/closeTv"
android:text="#string/close"
android:textColor="#color/white"
android:textAllCaps="true"
android:textStyle="bold"
android:gravity="center"
android:background="#color/colorPrimaryLight"
android:layout_width="0dp"
android:layout_height="48dp"
app:layout_constraintTop_toBottomOf="#+id/middleView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/applyTv" />
<TextView
android:id="#+id/applyTv"
android:text="#string/apply_filter"
android:textColor="#color/white"
android:textAllCaps="true"
android:textStyle="bold"
android:gravity="center"
android:background="#color/colorAccent"
android:layout_width="0dp"
android:layout_height="48dp"
app:layout_constraintTop_toBottomOf="#+id/middleView"
app:layout_constraintLeft_toRightOf="#+id/closeTv"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
Set LayoutParams of window of the dialog at run time. This one worked for me.
dialog.setContentView(R.layout.dialog_select_location);
Window window = dialog.getWindow();
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
window.setGravity(Gravity.CENTER);
Best of luck!
It seems to be working if you set a width on the parent ConstraintLayout instead of using match_parent. That's the best solution I was able to find.

app:layout_marginBottom is not working well with android constraint layout

Is there any reason why the following layout_marginBottom is not working?
However, if I use layout_marginTop on the second view it does work well
<android.support.constraint.ConstraintLayout
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:background="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
android:background="#000"/>
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
app:layout_constraintTop_toBottomOf="#+id/first"/>
</android.support.constraint.ConstraintLayout>
In order to
android:layout_marginBottom="20dp"
work well, you should use
app:layout_constraintBottom_toBottomOf="parent"
Layout top/bottom margin works only when:
constraints in the same direction need to connect with their next neighbor child, like a unidirectional linked list.
last constraint in the direction must be set.
In your case, you need to set "layout_constraintBottom_toXXXXX" for each view in the chain, and last view set bottom to parent.
<android.support.constraint.ConstraintLayout
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:background="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="#+id/second"
android:background="#000"/>
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="#+id/third"
android:background="#fff"/>
<TextView
android:id="#+id/third"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
Moreover, reverse dependency is not required except you want "layout_marginTop" works.
you can use that trick, create a space bellow, align to parent bottom
<Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
and align your view on top of the space
app:layout_constraintBottom_toTopOf="#+id/space"
like so
<TextView
android:id="#+id/howNext"
style="#style/white_action_btn_no_border"
android:layout_width="344dp"
android:layout_height="60dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="#string/got_it_next"
app:layout_constraintBottom_toTopOf="#+id/space"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
This is not LinearLayout or RelativeLayout, its ConstraintLayout so you have to give Left, Right, Bottom, Top Constraint to Relevant Layout, in your case You have to give TextView first Bottom_Top Constraint to TextView second. so you can get Margin between Two TextView.
Your layout should be like below.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="#+id/first"
app:layout_constraintLeft_toLeftOf="#+id/first"
app:layout_constraintRight_toRightOf="#+id/first" />
</android.support.constraint.ConstraintLayout>

Categories

Resources