Parent View height is ignored - android

I have custom LinearLayout, which is parent of my child views. I'm adding child views into this parent View using parent.addView() by inflating child layout. This LinearLayout is wrapped in ScrollView, so I can scroll child views if there is more there. Problem is that LinearLayout height is ignored if I add child views there (it stretched to full screen height for some reason). This behaviour is completely destroying need of ScrollView. Any reason why is it happening? I need some maxHeight parameter for this to work. It should stretch only to max of 200dp.
Layout:
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/resultList"
android:layout_width="match_parent"
android:layout_height="200dp"
android:paddingTop="#dimen/padding_medium"
android:paddingStart="#dimen/padding_medium"
android:paddingEnd="#dimen/padding_medium"
android:orientation="vertical">
</LinearLayout>
</ScrollView>

You can achieve this behaviour by using a root of a ConstraintLayout with a child of a ScrollView with height to wrap_content and a maximum height to 200dp using the property app:layout_constraintHeight_max="200dp" and the ScrollView child will be the LinearLayout with layout_height to wrap_content.
Below is the 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_dark"
app:layout_constraintHeight_max="200dp"
app:layout_constraintVertical_bias="0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:id="#+id/resultList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/padding_medium"
android:paddingStart="#dimen/padding_medium"
android:paddingEnd="#dimen/padding_medium"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
And the result after adding 3 child Views of 50dp height with different colours to LinearLayout with a total height smaller than 200dp will be like below (No Scroll required):
And the result after adding 9 child Views of 50dp height with different colours to LinearLayout with total height greater than 200dp will be like below (Scroll is required) (ScrollView has its max height to 200dp):

It is not clear from your question what the goal of your layout is. It seems to me that ScrollView is making some assumption about the height of its child being unbounded (and it can have only one child.) If you want the LinearLayout to have a specific height, set that height on the ScrollView itself.

Related

How to set height of one layout to the height of another layout in Android?

I have this code. So I want to set height in my relativeLayout by height in scrollView. Can I set height by id of scrollView? It's need, because I have many fragments, but one of them should take height of scrollView (when virtual keyboard is open).
...
<ScrollView
android:id="#+id/scrollViewer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<FrameLayout
android:id="#+id/frameViewer"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/layoutViewer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webViewer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</FrameLayout>
</ScrollView>
...
ScrollViews child (and its childrens also) should have set layout_height="wrap_content" for avoiding multiple re-measurements (way better performance)
if you want to fullfil whole ScrollView even when content have less height then use fillViewport xml attribute

Same size children in vertical LinearLayout

I have a LinearLayout with vertical orientation. All of the children's height is set to wrap_content. I would like to make all children have the same height, the height of the biggest child. Is this possible to do?
To distribute sub views evenly in LinearLayout, The official docs give a standard way:
To create a linear layout in which each child uses the same amount of space on the screen, set the android:layout_height of each view to "0dp" (for a vertical layout) or the android:layout_width of each view to "0dp" (for a horizontal layout). Then set the android:layout_weight of each view to "1".
If you want to do to make that item follows its spaces, you can use, layout:weight
For example here,
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"/>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical"
android:weight="1"/>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical"
android:weight="1"/>
</LinearLayout>

Android Constraint Layout height inside scrollview have no effect

In Android, I want to achieve a scroll view with fixed height on the screen, and the content inside also have a fixed height.
The scroll view height is 300dp, the direct child (relative layout) is 500dp, and the text view distance from top is 301dp. This means after I reached the text view, there is 200dp more bottom space for me to scroll from the relative layout height.
I manage to create the desired effect using the XML below.
<ScrollView
android:layout_width="match_parent"
android:layout_height="300dp" >
<RelativeLayout
android:layout_width="match_parent"
android:background="#FFC0CB"
android:layout_height="500dp" >
<TextView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/new_realm_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="301dp"
android:text="long text" />
</RelativeLayout>
</ScrollView>
But here is the problem, if I change the relative layout to constraint layout, now the scrolling will only scroll up to the text View at height 310dp, not of showing the 200dp empty space at the bottom.
Can someone explain why constraint layout is giving me this weird behavior?
According to Differences between ConstraintLayout and RelativeLayout, constraint layout "has dual power of both Relative Layout as well as Linear layout", it should be able to achieve what relative layout can achieve.
Try this:
<ScrollView android:layout_width="match_parent"
android:layout_height="300dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:background="#FFC0CB"
android:minHeight="500dp"
android:layout_height="500dp" >
<TextView
android:id="#+id/new_realm_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="301dp"
android:text="long text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
It seems like there is a bug in constraint layout or layout height cannot be applied to constraint layout in a scroll view but you can use minimum height attribute in constraint layout.
Adding android:fillViewport="true" to the ScrollView.

How can I ignore a child element's margins?

Background
I'm developing a custom notification layout by injecting an OS-generated notification view into my own layout. My layout must be as short as possible, which is 50dp in Android 10.
Problem
The view that I'm injecting into my view has margins that cause it to stretch my layout from 50dp to 66dp.
Code
The following layout is a simplification of what's going on to demonstrate the problem:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/activity_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:orientation="horizontal"
>
<TextView
android:id="#+id/full_height_view"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_bright"
/>
<TextView
android:id="#+id/bad_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="46dp"
android:layout_marginBottom="20dp"
android:background="#android:color/holo_red_light"
>
</TextView>
</LinearLayout>
</FrameLayout>
Note that container has minHeight of 50dp, which I don't want to be exceeded. The problem is the margins from bad_view sum up to 66dp and stretch the parent to 66dp.
Question
How can I prevent the margins on bad_view from stretching the parent beyond its minimum height? I cannot set a fixed height on the parent because the exact height is OS-dependent. And I cannot modify bad_view because it's generated by the OS.
I ended up solving this by setting the visibility of bad_view to gone.
I found another solution: use GridLayout vertical weights to override the problematic view's height. This gave me the flexibility of a weighted horizontal LinearLayout but with the addition of vertical weights.

Nested layout inside CardView overlaps parent end

I have no idea how this can happen, but I have a ConstraintLayout with a CardView inside. Inside said CardView is a LinearLayout. That LinearLayout overlaps the parent on the end. Check the screenshot for more info. If I remove the android:layout_margin from the cardView, the inner layout looks good again, but adding margin to start seems to just push the entire layout to and over the end of the parent. It doesnt matter what sort of layout is used inside the CardView. The issue affects them all.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="#color/colorWhite">
..
<androidx.cardview.widget.CardView
android:id="#+id/wakeuptimer_status_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/md_keylines"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
.....
You need to change the Linearlayout height to match-parent instead of wrap_content. With wrap_content you aren't restricting the size of the Linearlayout view to the size of the CardView.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

Categories

Resources