LinearLayout suitable to another LinearLayout - android

I have two linear layout inside constrainLayout,
The bottom linear layout includes buttons and its height is wrap_content and must be wrap, because sometimes I keep only 1 button and sometimes 2 buttons.
I would like to set height of the top linearLayout to max but without covering the 2nd layout.
So I decided to set match_parent to the first, but after that it covers the 2nd layout.
I can't use weight/weightsum
<androidx.constraintlayout.widget.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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button2"
android:visibility="gone" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="11"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="9"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:padding="16dp"
android:weightSum="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button2"
" />
</LinearLayout>
try this added weight sum and weight to make layout in prportion

Since you are using ConstraintLayout, you can set the height of the first LinearLayout to 0dp. The ConstraintLayout interprets it as "match constraints".
The next step would be to properly define the constraints of the first LinearLayout (which you did).
You can read more about ConstraintLayout here.
<androidx.constraintlayout.widget.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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button2"
android:visibility="gone" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

To do this you have to use a combination of linearlayout as parent and attribute layoutWeight ,If you use a constant value for layoutWeight for both top layout and button's container , then this will lead to some problem on different screen height devices , instead this solution make you able to set your buttons height as big as enough by setting its container's height to wrapContent and give all top area for the layout content .
You can also make the top linearLayout scrollable to get the best experience possible :
<?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">
<LinearLayout
android:id="#+id/this_layout_will_fil_all_space_except_the_bottom_layout_space"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#000000"
android:layout_weight="1">
</LinearLayout>
<LinearLayout
android:id="#+id/button_layout_at_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:padding="10dp">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:layout_marginEnd="50dp"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
For Buttons , you can set its width to wrapContent and add gravity attribute to its parent as above , in this way even if one buttons was gone , the other will fit perfectly in the center of the container .
Enjoy !

The main advantage of using ConstraintLayout is to avoid using any other nested ViewGroups, The more you add more hierarchy in layout, the less performance you'll have. You can check documentation for more.
So for performance wise it's better to add widgets/views directly within the ConstraintLayout.
So, here I removed the bottom LinearLayout, and kept only the buttons directly within the ConstraintLayout, you can do the same for the top LinearLayout, you can just add any underlying views directly to the ConstraintLayout
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="Button1"
app:layout_constraintBottom_toTopOf="#id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="Button2"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Related

Android ConstraintLayout: extending inner Scrollview with respect to vertical neighbor-views

what I want to achive
A scrollView which expends the free vertical space only if needed and a button which is appended on bottom of that scrollView but not hidden by the footer when the amount of the items in the scroll view increases.
whats the problem
scrollView android:layout_height = wrap content:
the button stays at the bottom of the scrollView. But then, if the ScrollView extends, the button is hidden behind the footer.
scrollView android:layout_height = 0dp:
the button stays visible while the scrollView extends the screen height. But then the button position is fixed because the scrollView is not resizing according to the amount of items.
But I didn't find a way to meet both criterias.
question
how do I set the constraints of this Layout to get the expected behaviour (see first image below)?
design to achive
current XML Layout
<?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"
android:theme="#style/Theme.AppCompat.Light">
<TextView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/shadeOfGrey2"
android:gravity="center"
android:text="header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/addItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/header"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.core.widget.NestedScrollView>
<Button
android:id="#+id/addItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button 01"
app:layout_constraintBottom_toTopOf="#id/footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/nestedScrollView" />
<TextView
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/shadeOfGrey2"
android:gravity="center"
android:text="footer"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
current Android layout
I think I got it down to what you're expecting now. Could you verify?
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/Theme.AppCompat.Light">
<TextView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/shadeOfGrey2"
android:gravity="center"
android:text="header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#+id/addItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/header"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:itemCount="8"
tools:listitem="#android:layout/simple_list_item_2" />
</androidx.core.widget.NestedScrollView>
<Button
android:id="#+id/addItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button 01"
app:layout_constraintBottom_toTopOf="#+id/footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/nestedScrollView"
app:layout_constraintVertical_bias="0" />
<TextView
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/shadeOfGrey2"
android:gravity="center"
android:text="footer"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Just keep in mind that your approach above won't be recycling any views in the RecyclerView adapter, so if the data is big then performance might become a concern.
Screenshots from Android Studio:

Android Studio layer below each other while orientation is horizontal

doing this layer work and can't figure out how to put layers below ones I made when the android orientation is horizontal, it keeps pushing my layer to the outsidie I have a pics what I have done and how it has to look, if you have any ideas would be nice to hear, thank you in advance.How it has to look
and What I have done
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#FA0000" />
<TextView
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#03ED0F" />
<TextView
android:id="#+id/blue"
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#0027C3"
/>
<TextView
android:layout_below="#id/blue"
android:layout_width="100dp"
android:layout_height="10dp"
android:background="#000000" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
If you are using
you should use these attribute to control the position
app:layout_constraintTop_toBottomOf
app:layout_constraintTop_toTopOf
app:layout_constraintTop_toStartOf
app:layout_constraintTop_toRightOf
based on what it should look like, you can try
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/ll_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#FA0000" />
<TextView
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#03ED0F" />
<TextView
android:layout_width="140dp"
android:layout_height="300dp"
android:background="#0027C3"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/ll_horizontal"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#FA0000" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#03ED0F" />
<TextView
android:id="#+id/blue"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#0027C3"
/>
</LinearLayout>
it should look like this
Use 2 seperate LinearLayout one below other in root.
One for horigontal views. Second for vertical views.
And use weight_sum property in LinearLayout, along with weight property in child views to distribute child views eqally.

MPAndroid chart in ConstraintLayout with additional widgets (they are not visible)

I am trying to add PieChart from MPAndroidChart and seekBar under it.
But still no luck, chart is visible, but other content is noT visible, despite it visible when I open design tab during xml configuration.
I already have tried to set a barrier and with groups with weights but still.
Could please anyone give any advice how to properly align chart to be able to see other widgets on view.
Here is my xml example:
<?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:id="#+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/pieChart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toTopOf="#+id/seekBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
ANSWER
The first and correct version of answer from Ashish Kudale is: Use LinearLayout with weight:
<LinearLayout
android:id="#+id/chartContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/pieChart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"/>
<android.support.v7.widget.AppCompatSeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
Use LinearLayout Insted of ConstraintLayout.
Try this.
<?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:id="#+id/linearLayout3"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/pieChart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text" />
</LinearLayout>
</LinearLayout>
What it does is places all items in the screen and remaining place is occupied by item which has android:layout_weight="1"

align view on top and buttons in bottom

I need to achieve the following view
I tried using constraint layout:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#id/segmentedButton">
</FrameLayout>
<Buttons
android:id="#+id/segmentedButton"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
</Buttons>
</android.support.constraint.ConstraintLayout>
It works well when there are many items, but when there are just 2-3, it shows them in the middle.
Also, I tried using LinearLayout but no luck.
you can use RelativeLayouttoo to get your desired results. By using the below code you can show the items on top if they are 2 or 3 left.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/segmentedButton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/segmentedButton"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
try with linear layout, weight property should push the button to align at the end of parent
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_weight="1"
>
</FrameLayout>
<Buttons
android:id="#+id/segmentedButton"
android:layout_width="wrap_content"
android:layout_height="50dp"
>
</Buttons>
</LinearLayout>
I supposed here that Buttons stand for a custom Button you made
Just add Top Constraint to your FrameLayout, should fix your issue.
Your final layout will be 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="match_parent">
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/segmentedButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"></FrameLayout>
<Buttons
android:id="#+id/segmentedButton"
android:layout_width="0dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"></Buttons>
</android.support.constraint.ConstraintLayout>
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/segmentedFrame"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/segmentedButton"
android:background="#drawable/bg_scan_edittext">
</FrameLayout>
<Button
android:id="#+id/segmentedButton"
android:layout_width="wrap_content"
android:layout_height="50dp"
app:layout_constraintTop_toBottomOf="#+id/segmentedFrame"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
</Button>
</android.support.constraint.ConstraintLayout>

Bottom of ScrollView clipped when using ConstraintLayout

I have an issue using a ScrollView inside ConstraintLayout (constraint-layout:1.0.0-beta3)
The content of my ScrollView isn't showed entirely.
Here is my layout:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_test"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#212121">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Constraint Layout"
android:textSize="45sp"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BUTTON"
android:layout_marginTop="800dp"/>
</LinearLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
And here is the result
As you can see the button isn't visible and I reached the bottom of my ScrollView.
It seems to works well with LinearLayout with layout below
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#212121">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Linear Layout"
android:textSize="45sp"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BUTTON"
android:layout_marginTop="800dp"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
And result is
With LinearLayout end of ScrollView is reachable.
Is there a bug with ConstraintLayout or do I made something wrong?
The way I would have done it is:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_test"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#212121"
android:text="Constraint Layout"
android:textSize="45sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/header">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="BUTTON"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
Which gives:
A few things to keep in mind:
you don't need a linearlayout for the header, you can just use the textview directly.
don't use match_parent, it might seem to work, but is undefined. Use 0dp instead with the correct constraints to stretch the view as you want.
clearly, don't use a 800dp margin. It might look ok on your particular screen, but won't give you what you want on different devices.
scrollview by default will wrap its content -- the fillViewport attribute is here to make it takes the indicated space
you can use nested ConstraintLayout when it makes sense. In the future, we might also take advantage of it to do some performance improvements
I changed the height of the ScrollView to match_parent and added a bottom constraint. This seemed to make it work correctly.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
Note: Having a height of wrap_content on a vertically scrolling view usually doesn't end well, in any layout.

Categories

Resources