I am new to constraint layout and I am trying to add my button below recyclerview, but I am not able to do that in constraint layout.
How I can achieve this functionality in constraint layout.
I am also share image for better understanding.
Try this sample code:
<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">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The important point is that the ListView's height must be 0 and app:layout_constraintBottom_toTopOf="#+id/button" and app:layout_constraintTop_toTopOf="parent" .
Try something like this:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/myButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Related
I want to use vertical bias to view always top but, I want to use guidelines to restrict the height on the screen. But If I used height wrap content it's not working until I set it to height 0dp. Does any better approach for this?
<?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:background="#color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recylerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="#+id/guidelines"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<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.9" />
</androidx.constraintlayout.widget.ConstraintLayout>
After adding #Ivo answer
<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:background="#color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="wrap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<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.9" />
</androidx.constraintlayout.widget.ConstraintLayout>
but the problem is my last view is cutting
I'm not sure if I completely understand it but I think you actually want android:orientation="horizontal" instead of android:orientation="vertical" in your Guideline
EDIT:
try using 0dp and also adding app:layout_constraintHeight_default="wrap" to your recyclerview
I'm trying to put a ConstraintLayout inside a NestedScrollView, but there is a line that separates the ConstraintLayout. I can't place anything underneath that invisible line. I have been trying for hours and can't find the issue.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:tag="layout/fragment_premium"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".PremiumFragment">
<ImageView
android:id="#+id/launcher_id"
android:layout_width="185dp"
android:layout_height="185dp"
android:layout_marginTop="25dp"
android:layout_marginBottom="20dp"
android:contentDescription="TODO"
app:layout_constraintBottom_toTopOf="#+id/premium_text_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/launch_premium" />
<TextView
android:id="#+id/premium_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="220dp"
android:text="#string/launch_to_premium"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="383dp"
android:layout_height="196dp"
android:layout_marginTop="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/premium_text_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
With a little bit of messing around I was able to get what you are looking for. The key is to use android:fillViewport="true" in the NestedScrollView
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:fillViewport="true"
android:tag="layout/fragment_premium">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/launcher_id"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginTop="25dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/launch_premium" />
<TextView
android:id="#+id/premium_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/launch_to_premium"
android:textSize="24sp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/launcher_id" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="383dp"
android:layout_height="196dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/premium_text_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
You need to add a attribute android:fillViewport="true" in your NestedScrollView
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:fillViewport="true" <-- add this
android:tag="layout/fragment_premium">
why?
fillViewport allows NestedScrollView to extend its height equals to the full height of the device screen height in the cases when the child of scroll view has less height.
this blog Will explain more about it.
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:
I have a view constrained to bottom of the parent. I also have text fields on top. how ever when the keyboard shows up, it will push bottom views up which will cover my text fields.
I have everything inside a scroll view, keyboard should cover the bottom view and I should be able to scroll to bottom to reach the bottom view.
Here is a simple example. I manually increased the height to reproduce the problem easier. I actually have more views, this is just for demonstration.
note that fillViewPort is also enabled.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/edit_text_1"
android:layout_width="0dp"
android:layout_height="180dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="#+id/edit_text_2"
android:layout_width="0dp"
android:layout_height="180dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/edit_text_1" />
<View
android:id="#+id/bottom_view"
android:layout_width="0dp"
android:layout_height="160dp"
android:background="#color/grey_500"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
You just simply need to put the ScrollView inside a ConstraintLayout
like this:
<?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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="0dp"
android:layout_height="180dp"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/edit_text_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:layout_width="0dp"
android:layout_height="180dp"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/edit_text_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edit_text_1"/>
<View
android:layout_width="0dp"
android:layout_height="160dp"
android:id="#+id/bottom_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edit_text_2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
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>