c0dehunter
c0dehunter

Reputation: 6160

Force a View on the bottom of ScrollView if content height less than screen height

I have a ScrollView with some Views in it. I want to force the last view to be on bottom if ScrollView's content height is less than screen height. How do I do that?

<ScrollView 
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal">

            <View ... />

            <View ... />

            <View ... />

            <View ... /> // this one should be on bottom if LinearLayout's contents don't exceed screen height
        </LinearLayout>
</ScrollView>

Upvotes: 5

Views: 1754

Answers (4)

Salih
Salih

Reputation: 181

Use the class below instead of LinearLayout inside your ScrollView. It will align the object at the bottom of the LinearLayout to the bottom if content is less than ScrollView height. I wrote this with Kotlin, please improve my answer if you convert it to Java.

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout

class ResizingLinearLayout: LinearLayout {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context) : super(context)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        val targetChild = getChildAt(this.childCount - 1)
        val parentScrollViewHeight = (parent!! as View).height
        val childParams = targetChild.layoutParams as LinearLayout.LayoutParams
        val addHeight = kotlin.math.max(parentScrollViewHeight - kotlin.math.max(oldh, h - childParams.topMargin), 0)
        if(targetChild.height > 0) {
            childParams.topMargin = addHeight
            targetChild.layoutParams = childParams
            super.onSizeChanged(w, h + addHeight, oldw, oldh)
        } else {
            super.onSizeChanged(w, h, oldw, oldh)
        }
    }
}

Upvotes: 0

ND1010_
ND1010_

Reputation: 3841

Try this:

Screen shot

enter image description here

xml code

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:text="Some views" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:orientation="vertical">

                <Button
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Click" />

            </LinearLayout>

        </RelativeLayout>

    </ScrollView>

</LinearLayout>

Upvotes: 2

SpiritCrusher
SpiritCrusher

Reputation: 21053

You can use RelativeLayout as a Root child of ScrollView with android:fillViewport="true".below is an example.

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/txt1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

Upvotes: 1

Archit Sureja
Archit Sureja

Reputation: 416

add following code

       <Space
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

before button view that you want to bottom of linnerLayout

+

change layout_height of LinearLayout to match_parent

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"

+

add android:fillViewport="true" to scrollview

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

Upvotes: 7

Related Questions