I'm trying to create a layout of a list which starts on the bottom of a button and it's 3/4 of screen's width.
Just like this:
First, I used nested Linear layouts a horizonal and a vertical one, but then I read here that Constraint layouts are more responsive and I was impressed and gave it a try.
So, I tried to replace the outer layout to a constraint layout but now, I can't constraint the list to start at the bottom of the button and it starts at top of the screen.
I tried to see what would happen if I replaced the whole linear layout with a button just to see that the attributes are correctly implemented and it worked, so I understood that the Constraint layout does'nt effect the sons of the Linear layout although it should be effecting the whole layout (as I see it).
my code is the following:
<?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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
My current layout looks like this:
I really appriciate the helpers!
You need to change layout height of linear layout to 0dp, I will put here the layout for you. Also consider migrating to androidx :)
<?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">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I think, that using match_parent as width or height of child and adding any constraint is wrong here.
Edited xml (change margins if you want):
<?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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="24dp"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="24dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button"
app:layout_constraintWidth_percent="0.75">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
Related
I tried this answer.
But I get Nested weights are bad for performance. Is there anyway to solve this or should I continue with this warning?
Here is the layout necessary to solve this with 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">
<View
android:id="#+id/one"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#333"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/two"
app:layout_constraintBottom_toTopOf="#id/three"/>
<View
android:id="#+id/two"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#444"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/one"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/four"/>
<View
android:id="#+id/three"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#555"
app:layout_constraintTop_toBottomOf="#id/one"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/four"
app:layout_constraintBottom_toBottomOf="parent"/>
<View
android:id="#+id/four"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#666"
app:layout_constraintTop_toBottomOf="#id/two"
app:layout_constraintStart_toEndOf="#id/three"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
However, that performance warning is safe to ignore. Nested weights are bad for performance, but this will only be noticeable when you have lots of nested weights on many views all being updated frequently (e.g., flinging a RecyclerView where each item uses nested weights).
You can try this bunch of xml code below: (I've tested it no warning...)
Here is the main content xml file, test.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:weightSum="2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/test_1"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
<include
layout="#layout/test_2"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
</LinearLayout>
As I used same xml code for the two nested files test_1.xml and test_2.xml; I am sharing the common code below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:weightSum="2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#color/colorAccent"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#android:color/holo_purple"/>
</LinearLayout>
And guess what, I found a responsive layout as you want to achieve.
Here is the output:
You can use ConstraintLayout with guidelines. For example, if you want the layout split into 4 equal parts horizontally, you'd use 3 vertical guidelines, one set at 0.25, one set at 0.50 and one set at 0.75. If you want it split vertically, you'd use the same guideline percents but with horizontal guidelines.
You would then position your views with constraints to the guidelines and the parent.
I have two constraint layouts in a linear layout. I want the constraint layouts to occupy 30% and 70% of the screen respectively on all devices. What attribute inside the Linear Layout do I need to set in order to achieve this?
This should give the desired result. Setting a weightSum attribute to the parent linear layout and then accordingly giving the weights helps
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1" >
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"/>
</LinearLayout>
You have to take Parent Layout as ConstraintLayout and then after you have to use GuideLine to set 30 and 70 percent of screen.
<?xml version="1.0" encoding="utf-8"?><?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">
<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.3" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_green_light"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
Output
Use WeightSum attribute on LinearLayout to achieve the Output you are expecting, Which is more easier than other methods.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3" >
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3">
//Child layouts on 30% of layout
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7">
//Child layouts on 70% of layout
</android.support.constraint.ConstraintLayout>
If you want make something like that use
android:layout_weight="any number"
but you must make the same height for the both of them it doesn't matter if the height wrap_content or match_parent
The layout will occupy more form screen if the number less than the other one
I have a list of card views which has the flag of the country and name of it. The CardView has a ConstraintLayout as a child for aligning the views inside, and has a LinearLayout as parent.
The RecyclerView in MainActivity has a ConstraintLayout as Parent(which is the parent view by default created by AndroidStudio when doing a new project)
<?xml version="1.0" encoding="utf-8"?> <!-- MAIN ACTIVITY XML-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="#dimen/card_view_item_main_width"
android:layout_height="#dimen/card_view_item_main_height">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/countryCardImage"
android:layout_width="match_parent"
android:layout_height="128dp"
android:contentDescription="#string/imagen_pais"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="#+id/countryCardText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintVertical_bias="1"
/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <!-- ITEMMAIN.XML -->
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".main.ui.main.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/listMain"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_weight="0"
/>
</android.support.constraint.ConstraintLayout>
In your item root view, the layout_gravity="center" is not going to work on LinearLayout with layout_width="wrap_content: on a RecyclerView, so you could try changing its width to match_parent, and either change the gravity to android:gravity="center" or move android:layout_gravity="center" to its child view:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="10dp"
android:layout_width=“match_parent”
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="#dimen/card_view_item_main_width"
android:layout_height="#dimen/card_view_item_main_height"
android:layout_gravity="center">
The problem is in layout item, you set the layout_width="wrap_content" in LinearLayout, and in main layout, layout_width in Recyclerview is 0dp (must be match_parent) so it's not center in main layout because the main layout depend on item layout => wrong with this case.
In your layout item, change like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
I have a form which has around 12/13 fields. I used a Scrollview inside a constraint layout. Below is the hierarchy of the XML layout. The problem is, it doesn't scroll to the bottom instead scrolls only to the first initial 10 views. The last 3 fields gets hidden as the view does not scroll any further.
PARENT LAYOUT
<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:id="#+id/activity_register"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">
<!-- Textview and a button -->
<ScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp">
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Child Views (12/13 views of the fields)-->
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
This layout works in my app.
The trick is to set these two attributes in ScrollView:
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
The simplified layout from my app:
<?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"
android:theme="#style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:id="#+id/linear"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="#color/title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/linear">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/titleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="#string/title"
android:textSize="14sp"
app:layout_constraintBaseline_toBaselineOf="#+id/title"
app:layout_constraintLeft_toLeftOf="parent" />
<EditText
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:hint="toilet title"
android:inputType="text"
android:textColor="#android:color/holo_red_dark"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="#+id/open_hour"
app:layout_constraintLeft_toRightOf="#+id/titleView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
...
Other Views in ScrollView
...
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
In my case NestedScrollView worked instead of ScrollView. Following is the snippet of my working layout:
<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">
<!-- Some Views Here -->
<android.support.v4.widget.NestedScrollView
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/view">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Some Views That can be Scrolled Here -->
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.constraint.ConstraintLayout>
You have two solutions for this problem (the same solution but in two ways to do it):
If you put the Design mode in Android Studio, select your ScrollView and open attributes tab and in the layout_height, select "match_constraint".
If you use the Text mode in Android Studio, use this:
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#id/tb_details">
See that the ScrollView height is set to 0dp. Both of this ways resolve the same problem but these are the different ways to do it.
The ScrollView is not the root view, I have a Constraint layout wrapping the ScrollView as you.
Two Steps
Keep layout height for scroll view zero
android:layout_height="0dp"
Again for scroll view
android:fillViewport="true"
Try adding bottom constraint to scrollview (eg: app:layout_constraintBottom_toBottomOf="parent")
and change android:layout_height="wrap_content" to android:layout_height="0dp"
In my case NestedScrollView worked instead of ScrollView.
Following is the snippet of my working layout:
Please make sure that you haven't make any childview height to match parent(0 dp) inside constrianlayout also for scroll view android:fillViewport="true;
Ask me if any doubt Occur.
<android.support.v4.widget.NestedScrollView
android:id="#+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/_90sdp"
android:fillViewport="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/cvLayout"
android:animateLayoutChanges="true">
Just Put android:fillViewport="true" in Parent Layout
In my case, I had a tall TextView (height set to wrap_content) inside a ScrollView (height set to 0dp and being constraint on the top and bottom). No suggestions worked, but I solved the problem by wrapping the TextView inside a FrameLayout (height set to wrap_content).
Never keep 0dp height of childs of ConstraintLayout if it is inside SV/NestedSV
wrap_content works because in this case ScrollView knows its childens height.
For me, I needed to add a LinearLayout inside my ScrollView in order to constrain it
<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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="1dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View....</View>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
I have resolve this issue. Inside ScrollView you can not use constraint Layout.
for using constrain inside scroll u have to use Relative layout is parent of constraint Layout..
so ur sequence should be:
ScrollView ---> Relative Layout ---> Constraint Layout
If you came here after searching "Soft Keyboard Hides the View elements"!
Then you just have to add a scrollView and the same layout element again.
Before
<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">
<ImageView
android:id="#+id/imageView3"
android:layout_width="246dp"
android:layout_height="168dp"
android:layout_marginTop="20dp"
android:src="#drawable/img"/>
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
After
<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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView3"
android:layout_width="246dp"
android:layout_height="168dp"
android:layout_marginTop="20dp"
android:src="#drawable/img"/>
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
For the horizontal scroll view case (parent is ConstraintLayout, immediate child is LinearLayout), I found that setting the four constraints, layout_width=0dp, and fillViewport=true was not enough. It still didn't scroll.
What did work in my case was to set the four constraints and change the element from ScrollView to HorizontalScrollView. In that case layout_width can be set to "wrap_content" and fillViewport can be omitted.
Additionally, I added a padding at the end of the immediate child of the HorizontalScrollView, to make the scrolling experience and the look better.
I faced another issue where i had nestedscrollview which has constrainlayout which has linearlayout. This linearlayout has child get added programatically. So scroll was not working. Solved by replacing CL with LL with vertical orientation
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#+id/separatr"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:fillViewport="true"
android:fitsSystemWindows="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:background="#color/yellow_highlight"
android:paddingBottom="#dimen/box96">
<TextView
android:id="#+id/qansTv"
style="#style/BodyText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/box200"
android:layout_marginTop="#dimen/box32"
android:layout_marginEnd="#dimen/box200"
android:text="Lorem ipsum dofdfd fsd fdfsd sdf sdfsd fsdfsd fd sdfd fsdfsdf sdfsd df sdfd fsdfsd fsdf sdfsd dflors fdfdf."
android:textColor="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/ansImageContainerLL"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="#color/red"
android:layout_marginEnd="#dimen/box64"
android:orientation="vertical"
android:layout_marginStart="#dimen/box64"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/qansTv" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
in my case I had to use 2 recyclerviews and since it didn't want to scroll all the way I found a way to set to which length of the scrollview to scroll, the length is set by changing the width of the TextView.
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ProjectsFragment"
android:background="#color/blue">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="#+id/scrollViewLength"
android:layout_width="2000dp"
android:layout_height="match_parent"
android:text="Change the width above"
android:visibility="invisible"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="exampletag"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView1"
android:tag="exampletag"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="28dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</FrameLayout>
</HorizontalScrollView>
I know I'm late little bit ,I was facing the same issue what I did wrapped my RecyclerView Inside Linear or Relative layout and it worked like a charm,
I have a vertical RecyclerView using a GridLayoutManager. I want each column to be centered, but the columns begin all the way on the left. In the following picture you can see what I'm talking about. I used the ugly color scheme to illustrate the columns and background. The green is the background for each item in the RecyclerView, the red is the background of the RecyclerView itself:
http://imgur.com/a/J3HtF
I'm setting it up with:
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
Here's the column_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="120dp"
android:layout_height="180dp"
android:orientation="vertical"
android:padding="4dp">
<ImageView
android:id="#+id/movie_column_photo"
android:layout_width="80dp"
android:layout_height="120dp"/>
<TextView
android:id="#+id/movie_column_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Here's the recyclerview xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/company_details_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Try letting the column item fill the width of the column while centering everything inside:
<?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="180dp"
android:orientation="vertical"
android:padding="4dp">
<ImageView
android:id="#+id/movie_column_photo"
android:layout_width="80dp"
android:layout_height="120dp"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="#+id/movie_column_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
To restate #kris larson's answer;
If you are using ConstraintLayout, adding android:layout_gravity="center" or android:layout_gravity="center_horizontal" to the parent layout in item's XML would be enough (the first parent in hierarchy).
In your case, the codes would be something similar to this:
<android.support.constraint.ConstraintLayout
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="180dp"
android:orientation="vertical"
android:padding="4dp"
android:layout_gravity="center">
<ImageView
android:id="#+id/movie_column_photo"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="80dp"
android:layout_height="120dp"/>
<TextView
android:id="#+id/movie_column_title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
Simply set the width of the root layout for your column_item.xml to match_parent will center RecyclerView items horizontally.
Wrap your recyclerview inside the constraintlayout, 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:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/book_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2" />
Hope it helps!!