Android 如果内容高度小于屏幕高度,则强制在ScrollView底部显示视图

Android 如果内容高度小于屏幕高度,则强制在ScrollView底部显示视图,android,scrollview,Android,Scrollview,我有一个滚动视图,其中包含一些视图。如果ScrollView的内容高度小于屏幕高度,我想强制最后一个视图位于底部。我该怎么做 <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent"

我有一个滚动视图,其中包含一些视图。如果ScrollView的内容高度小于屏幕高度,我想强制最后一个视图位于底部。我该怎么做

<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>

//如果LinearLayout的内容不超过屏幕高度,则此项应位于底部
添加以下代码

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

您可以使用
RelativeLayout
作为
ScrollView
android:fillViewport=“true”
的根子级。下面是一个示例

<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>


试试这个:

屏幕截图

xml代码

<?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>

使用下面的类,而不是滚动视图中的线性布局。如果内容小于ScrollView高度,则会将LinearLayout底部的对象与底部对齐。我是用Kotlin写的,如果你把它转换成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)
        }
    }
}

您是否尝试过使用相对布局并赋予属性“align\u parentBottom”=true?效果很好。此解决方案似乎运行良好,但当同时使用LinearLayout和RelativeLayout作为ScrollView的根子级时,我确实收到以下布局设计视图警告此LinearLayout应使用android:layout\u height=“wrap\u content”ScrollView子项必须将其布局宽度或布局高度属性设置为在滚动维度Issue id:ScrollViewSize中换行内容,而不是填充父项或匹配父项。警告所说的很有意义-为什么要创建包含与父项高度匹配的子项的滚动视图。这对其他人有什么影响?
<?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>
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)
        }
    }
}