ConstraintLayout inside ScrollView or NestedScrollView won't scroll - android

I am fairly new to ConstraintLayout and am trying to convert my UI to a responsive layout to support different screen sizes. However, I am having trouble with my ScrollView scrolling when the inner layout is a ConstraintLayout. Even when I change the ScrollView to NestedScrollView it still won't scroll. I tried several solutions of many asking the same question and none of them seemed to have worked.
<android.support.v4.widget.NestedScrollView
android:id="#+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
android:fillViewport="true"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#+id/logo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/refresh_text">
<android.support.constraint.ConstraintLayout
android:id="#+id/innerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/innerLayout2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/light_gray"
app:layout_constraintBottom_toTopOf="#+id/key_constraint_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent=".1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/status_date_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="Status Date"
android:textSize="20sp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/status_date_value"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="-------"
android:gravity="end|center_vertical"
android:textSize="20sp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0.70"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<!--Other inner layouts are children of innerLayout based on innerLayout2 -->
</android.support.constraint.ConstraintLayout>
<android.support.v4.widget.NestedScrollView>
What am I doing wrong?

This jumps out at me as the likely cause of your problem:
<android.support.constraint.ConstraintLayout
android:id="#+id/innerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
The single child of a scrolling view should always have either a fixed height or a wrap_content height.
The idea of scrolling views is that they hold a single child that is too large to fit on the screen by itself. If you are defining the single child to be match_parent height, then there's nothing to scroll, because the child is no larger than the scrolling view.

Related

Bottom item cut in reyclerview in android

Hey I am working in constraint layout with recylerview. My bottom item is cut in the screen. I read this stack overflow post. I don't want to use relative layout or linear layout. Can someone guide me how to fix this in constraint layout.
abc.xml
<?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">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="16dp"
app:closeIcon="#drawable/ic_cancel"
app:layout_constraintBottom_toTopOf="#+id/exploreScroll"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0.0" />
<HorizontalScrollView
android:id="#+id/exploreScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:scrollbars="none"
app:layout_constraintBottom_toTopOf="#+id/exploreList"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchView">
<com.google.android.material.chip.ChipGroup
android:id="#+id/exploreChips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipSpacingHorizontal="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:singleLine="true"
app:singleSelection="true" />
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/exploreList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:paddingTop="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/exploreScroll" />
</androidx.constraintlayout.widget.ConstraintLayout>
My view cut from
UPDATE
#Zain after your suggestion i tried in my xml any my HorizontalScrollView is going behind my RV. I am adding my blueprint and you can see clearly that, HorizontalScrollView is going behind. After removing app:layout_constraintBottom_toTopOf="#+id/exploreList" from the HorizontalScrollView.
2nd suggestion try
Disclaimer Using a wrap_content height with vertical RecyclerView
can have impact on performance in terms of recycling views; specially
if the height is going to change frequently. Check this article
for more illustration.
So, the first step is to designate the RecyclerView height or to constraint it; from the constraints you want it to expand to the bottom; so use 0dp for that. But in order to make the minimum height to wrap content of the RecyclerView (in case that the items don't exceed the screen height); you can set the default height constraint to wrap with app:layout_constraintHeight_default="wrap" constraint.
Then remove app:layout_constraintBottom_toTopOf="#+id/exploreList" from the HorizontalScrollView, this actually made the bottom item of the RV hide (your main issue); because it is an over-constraint; the HorizontalScrollView tends to push the RV to the bottom while the RV tends to push the HorizontalScrollView to the top.
This will solve the main issue; but when the items are fully accommodated by the screen (no scrolling in the RV), then it will be biased in the middle; to fix this use the bias with app:layout_constraintVertical_bias="0.0" to be biased to the top.
Adding this in place into the 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">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="16dp"
app:closeIcon="#drawable/ic_cancel"
app:layout_constraintBottom_toTopOf="#+id/exploreScroll"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed" />
<HorizontalScrollView
android:id="#+id/exploreScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchView">
<com.google.android.material.chip.ChipGroup
android:id="#+id/exploreChips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipSpacingHorizontal="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:singleLine="true"
app:singleSelection="true" />
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/exploreList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
android:paddingTop="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="wrap"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/exploreScroll" />
</androidx.constraintlayout.widget.ConstraintLayout>

Constrain max size of RecyclerView

I'm putting together a screen with 3 controls stacked vertically. Specifically, a RecyclerView sandwiched between two TextView. I have two situations I am trying to address.
When few items are displayed in the RecyclerView the 3 items should be packed towards the top of the screen with blank space BELOW them.
When many items are displayed in the RecyclerView the full screen will be used with the last TextView along the bottom of the screen and scrolling in the center RecyclerView.
I'm struggling to get the position of the last TextView correct as it either gets pushed off the screen or buried behind the RecyclerView if there are many items in the RecyclerView. What I need is a way to tell the RecyclerView to wrap contents, but stop growing when it starts to push the TextView off of the screen.
Below is my layout, any suggestions?
<?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">
<TextView
android:id="#+id/topItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/middleItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/middleItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layout_constraintBottom_toTopOf="#+id/bottomItem"
app:layout_constraintTop_toBottomOf="#+id/topItem" />
<TextView
android:id="#+id/bottomItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|top"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/middleItem" />
</androidx.constraintlayout.widget.ConstraintLayout>
Try the following:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/topItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is the top item."
app:layout_constraintBottom_toTopOf="#+id/middleItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/middleItem"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="none"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#+id/bottomItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topItem"
tools:itemCount="3" />
<TextView
android:id="#+id/bottomItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal|top"
android:text="This is the bottom item."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/middleItem" />
</androidx.constraintlayout.widget.ConstraintLayout>
With three items in the RecyclerView:
With 50 items in the RecyclerView:
The key changes are:
Added app:layout_constraintVertical_bias="0.0" to the top TextView to position the chain always at the top;
Added app:layout_constrainedHeight="true" to the RecyclerView to make sure views don't go off-screen;
Changed match_parent to 0dp and set the horizontal constraints for direct children of the ConstraintLayout.
Changed the RecyclerView's height to '0dp'.
Update: Although the above works, it is a little overdone. As noted in the comments, the same effect can be accomplished by simply setting the height of the RecyclerView to 0dp.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/topItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is the top item."
app:layout_constraintBottom_toTopOf="#+id/middleItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/middleItem"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="none"
app:layout_constraintBottom_toTopOf="#+id/bottomItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topItem"
tools:itemCount="3" />
<TextView
android:id="#+id/bottomItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal|top"
android:text="This is the bottom item."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/middleItem" />
</androidx.constraintlayout.widget.ConstraintLayout>

Bug: Barrier connected with "percent height" in ConstraintLayout is inside a ScrollView

I have a ScrollView which has a ConstraintLayout.
Inside the ConstraintLayout I want to position a View to the bottom of a Barrier.
The Barrier itself has constraints: a Guideline(it can be also a view with height half of parent) which is half of the ConstraintLayout and a TextView.
The issue here is that the ConstraintLayout will expand even more (adds more scrollable area) because of the half of screen percentage calculation.
<?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">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="100dp"
android:layout_height="200dp"
android:background="#39537A4B"
android:fillViewport="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/topHalf"
android:layout_width="10dp"
android:layout_height="0dp"
android:background="#99B146B8"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<View
android:id="#+id/bottomHalf"
android:layout_width="10dp"
android:layout_height="0dp"
android:background="#99B89F46"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Do smth \n\n\n\n\n\n\nasdasda"
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.5" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="guideline, text" />
<View
android:id="#+id/view"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="#651F7878"
app:layout_constraintStart_toStartOf="#id/barrier"
app:layout_constraintTop_toBottomOf="#id/barrier" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Try changing the Barrier constraints to:
app:constraint_referenced_ids="text"
And you understand that Barrier brakes the calculations.
I know how to solve this layout issue from java, I want a solution from xml. It can be this is a bug on ConstraintLayout
This behavior is odd and is definitely related to the barrier and a wrap_content ConstraintLayout Here is a simplified layout that showcases the behavior.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:id="#+id/redBox"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#android:color/holo_red_light"
android:textAppearance="#style/TextAppearance.AppCompat.Body2"
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=".5" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="redBox,guideline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
With the above layout, the following is what is displayed. Although the ConstraintLayout is wrap_content, it expands to twice the height of the red box.
If we remove the red box or the guideline from the barrier, the layout behaves:
The height of the ConstraintLayout can be varied by changing the location of the guideline. Here it is with the guideline set at 30%:
The expected behavior, IMO, is that the ConstraintLayout would size itself based upon the heights of its child views, here just the red box, and the guideline would be set accordingly. That is clearly not what is happening.
Maybe someone can figure out an XML work-around using the simplified layout. I didn't see a similar issue reported from a cursory search, so it may be worth reporting.
(Using ConstraintLayout version 2.1.0)

Android WebView overlaps with other views

I have a simple web view in between image and button. For some reason, if I put a long text, the web view is overlapping with the logo and the button. It works for a short text. I used constraint layout. It seems that the web view is expanding beyond the parent view.
Please see the pictures.
Below is my layout code:
<?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="wrap_content">
<ImageView
android:id="#+id/iv_logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/card_big_margin"
android:src="#drawable/login_cashnetusa_color"
android:tint="#color/white"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<androidx.cardview.widget.CardView
android:id="#+id/cv_splash_screen"
style="#style/CardTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/card_normal_outer_margin"
android:layout_marginTop="#dimen/card_normal_outer_margin"
android:layout_marginRight="#dimen/card_normal_outer_margin"
android:layout_marginBottom="#dimen/card_normal_outer_margin"
app:layout_constraintBottom_toTopOf="#id/btn_cta"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/iv_logo">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv_header"
style="#style/CardContent.CustomBlack.Bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/card_normal_margin"
android:text="#string/dummy_full_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<WebView
android:id="#+id/wv_update_text"
style="#style/CardContent.White"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="#dimen/card_normal_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_header" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<Button
android:id="#+id/btn_cta"
style="#style/Button.OrangeGradient"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/card_normal_margin"
android:layout_marginRight="#dimen/card_normal_margin"
android:layout_marginBottom="#dimen/card_item_normal_margin"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="#id/tv_skip"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:text="#string/dummy_btn_ok" />
<TextView
android:id="#+id/tv_skip"
style="#style/CardContent.White"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/card_normal_margin"
android:text="#string/skip"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The problem lies in here:
<androidx.cardview.widget.CardView
android:id="#+id/cv_splash_screen"
style="#style/CardTheme"
android:layout_width="match_parent"
<-- change layout:height from wrap_content to some specific height let it be 300-400dp -->
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/card_normal_outer_margin"
android:layout_marginTop="#dimen/card_normal_outer_margin"
android:layout_marginRight="#dimen/card_normal_outer_margin"
android:layout_marginBottom="#dimen/card_normal_outer_margin"
app:layout_constraintBottom_toTopOf="#id/btn_cta"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/iv_logo">
or the second option is you can use minHeight and maxHeight in your cardview or it's child layout which is Constraint layout to prevent it from expanding on full screen
and if you have long texts to read use ScrollView inside cardview.
As you have set the height of your CardView to wrapContent it will expand to the content that is put in it, what you can do is set app:layout_constrainedHeight="true" that will prevent it from expanding beyond its bounds.
Note that you do have to set up the view bound chaining properly for this to work, ie set app:layout_constraintTop_toX and app:layout_constraintBottom_toX on all the views in the 'chain' from the top of the view through to the bottom.
so in your code:
<androidx.cardview.widget.CardView
android:id="#+id/cv_splash_screen"
style="#style/CardTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/card_normal_outer_margin"
android:layout_marginTop="#dimen/card_normal_outer_margin"
android:layout_marginRight="#dimen/card_normal_outer_margin"
android:layout_marginBottom="#dimen/card_normal_outer_margin"
<!-- add this line --> app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#id/btn_cta"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/iv_logo">

ImageView below adview stop layout jump after ad loads

I have an imageview that I will place different images.
This images can have many sizes like 200x200 200x400 400x200...
Above imageview I have an adview and below this imageview I need 4 buttons.
The problem is, I'd like the image be below adview, but stop jumping position when ad loads. It goes down when an ad loads, I'd to stop this move, make the image fix, but above the adview.
My xml:
<?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:id="#+id/ad_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="49dp"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="#+id/imageView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ads:adSize="SMART_BANNER"
ads:adUnitId="ca-app-pub-xxx/xxx">
</com.google.android.gms.ads.AdView>
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:layout_marginTop="89dp"
android:contentDescription="img"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ad_view" />
<TextView
android:id="#+id/a1"
android:layout_width="127dp"
android:layout_height="50dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.207"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.447" />
<TextView
android:id="#+id/a2"
android:layout_width="127dp"
android:layout_height="50dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.806"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.447" />
<TextView
android:id="#+id/a3"
android:layout_width="127dp"
android:layout_height="50dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.207"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.582" />
<TextView
android:id="#+id/a4"
android:layout_width="127dp"
android:layout_height="50dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.806"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.582" />
</androidx.constraintlayout.widget.ConstraintLayout>
TL;DR
The fastest solution would be to change your ad view android:layout_height="wrap_content" into android:layout_height="fixed size" so your ad view will have a single height and won't change because of its wrap_content attribute (If your ad view is not loaded you can think of wrap_content as height of 0 and only after its loaded it will have height, thus the layout jump).
Why is it bad?
your layout won't be responsive.
How to fix?
Read the answer below.
Long but better answer:
You can use guidelines with app:layout_constraintGuide_percent=".2" to tell your guideline to be at the top of your screen (80%) and constraint your ad view to your guideline - this way your layout will won't jump (it will have its space to load into).
Another thing, different phones got different screen size, in your layout you are using fixed size on your view (fixed size is 50dp for example) and the result is that what may look good on one screen (your android studio preview screen) will not look good on another screen (your actual phone).
Here is an example to achieve your wanted look using ConstaintLayout:
<?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">
<Button
android:id="#+id/adView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintHeight_percent="0.08"
android:text="add view"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="#drawable/ic_launcher_background"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline"
app:layout_constraintWidth_percent="0.6" />
<TextView
android:id="#+id/a1"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="a1"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintWidth_percent="0.25"
app:layout_constraintBottom_toTopOf="#+id/a3"
app:layout_constraintEnd_toStartOf="#+id/a2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="#+id/imageView1"
app:layout_constraintTop_toBottomOf="#+id/imageView1" />
<TextView
android:id="#+id/a2"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="a2"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintWidth_percent="0.25"
app:layout_constraintBottom_toBottomOf="#+id/a1"
app:layout_constraintEnd_toEndOf="#+id/imageView1"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/a1"
app:layout_constraintTop_toTopOf="#+id/a1"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/a3"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="a3"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/a1"
app:layout_constraintStart_toStartOf="#+id/a1"
app:layout_constraintTop_toBottomOf="#+id/a1" />
<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=".2" />
<TextView
android:id="#+id/a4"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="a4"
app:layout_constraintBottom_toBottomOf="#+id/a3"
app:layout_constraintEnd_toEndOf="#+id/a2"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintStart_toStartOf="#+id/a2"
app:layout_constraintTop_toTopOf="#+id/a3" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is how it will look (I am adding a screenshot from the layout editor for better understanding ConstaintLayout)
Some extra information:
ConstraintLayout is not meant to have nested view groups (in your case you have LinearLayout inside constraintlayout).
ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.
You can Use ConstraintLayout with guidelines and Chains to support different screen sizes, you won't have to use fixed sizes on your views and you will be able to use a single layout to support different screen size.
Give the adview or it's surrounding layout a minimum height equal to the smart banner content in your case likely 90px.
It's jumping because with no content loaded your wrap_content height = 0, then it gets a new height of x, so your imageview shifts down x.

Categories

Resources