两个滚动视图,一个在另一个下面,每个都应使用一半的空间,但如果它们没有完全填充,则缩小以支持另一个

问题描述 投票:0回答:1

我在垂直 LinearLayout 中有两个垂直 ScrollView。 如果我将两者的layout_weight设置为1,它们都使用全高度的一半。 然而,如果其中一个只需要例如,情况也是如此。由于其内容而高度的四分之一。 在这种情况下,我想缩小第一个 ScrollView 并为第二个 ScrollView 使用多余的空间(反之亦然)。

知道如何实现这一目标吗?周围布局不一定是 LinearLayout。 (我看过this,但它没有回答我的问题)

android android-layout scrollview android-linearlayout
1个回答
0
投票

好吧,由于似乎没有办法直接使用LinearLayout,所以我创建了一个自定义布局。 它必须有两个 ScrollView 作为子项,但如果内部需要其他视图,则可以轻松进行调整。

/**
 * A vertical LinearLayout containing 2 ScrollViews.
 * The height of each ScrollView is growing with its content, as long as both
 * ScrollViews fit into the parent.
 * If one ScrollView needs to scroll its content, and the other is still smaller than half
 * of the parent, the smaller one takes only as much space as needed.
 * Only if both views need more than half of the parent space,
 * each of them receives exactly half of it.
 */
class DoubleScrollView : LinearLayout {

    private lateinit var scrollView1: ScrollView
    private lateinit var scrollView2: ScrollView

    constructor(context: Context) : super(context)

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

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

    override fun onFinishInflate() {
        super.onFinishInflate()
        //In this simple example, we assume to have exactly 2 ScrollViews as children
        scrollView1 = getChildAt(0) as ScrollView
        scrollView2 = getChildAt(1) as ScrollView
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //Allow the scroll views to set the full content height at first
        scrollView1.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, 0f)
        scrollView2.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, 0f)
        val widthSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY)
        val heightSpec = MeasureSpec.makeMeasureSpec(height, AT_MOST)
        scrollView1.measure(widthSpec, heightSpec)
        scrollView2.measure(widthSpec, heightSpec)
        // Based on the height the full content would need, adapt the LayoutParams
        // of the ScrollViews.
        val height = View.MeasureSpec.getSize(heightMeasureSpec)
        val height1 = scrollView1.measuredHeight
        val height2 = scrollView2.measuredHeight
        if (height1 + height2 >= height) {
            if (height1 < height / 2) {
                //First wrap content, second fills the rest
                scrollView2.setLayout(0, 1f)
            } else if (height2 < height / 2) {
                //Second wrap content, first fills the rest
                scrollView1.setLayout(0, 1f)
            } else {
                //First and second both with same weight
                scrollView1.setLayout(0, 1f)
                scrollView2.setLayout(0, 1f)
            }
        } //else: both views can just wrap content
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    private fun View.setLayout(height: Int, weight: Float) {
        this.layoutParams.height = height
        (this.layoutParams as LinearLayout.LayoutParams).weight = weight
    }
}

为了测试和演示,我创建了以下最小应用程序。

活动:

class MainActivity : AppCompatActivity() {

    private val mainViewModel: MainViewModel by viewModels()
    private lateinit var vb: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        vb = ActivityMainBinding.inflate(layoutInflater)
        setContentView(vb.root)
        mainViewModel.text1.observe(this) { text -> updateText(vb.text1, text) }
        mainViewModel.text2.observe(this) { text -> updateText(vb.text2, text) }
        listOf(vb.plus1, vb.minus1, vb.plus2, vb.minus2).forEachIndexed() { i, button ->
            button.setOnClickListener { mainViewModel.changeText(i <= 1, i % 2 == 0) }
        }
    }

    private fun updateText(textView: TextView, text: String?) {
        textView.text = text
    }

}

视图模型:

class MainViewModel : ViewModel() {
    val text1: LiveData<String> = MutableLiveData("")
    val text2: LiveData<String> = MutableLiveData("")

    fun changeText(first: Boolean, plus: Boolean) {
        val liveData = if (first) text1 else text2
        val text = liveData.value!!
        val size = text.count { it == '#' } + if (plus) 1 else -1
        val lines = Array(size.coerceAtLeast(0)) { "This is line #$it" }
        (liveData as MutableLiveData).value = lines.joinToString("\n")
    }
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<yourPackage.DoubleScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

            <Button
                android:id="@+id/plus1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="+"></Button>

            <Button
                android:id="@+id/minus1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="-"></Button>

            <TextView
                android:id="@+id/text1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

    <ScrollView
        android:id="@+id/scrollView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

            <Button
                android:id="@+id/plus2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="+"></Button>

            <Button
                android:id="@+id/minus2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="-"></Button>

            <TextView
                android:id="@+id/text2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

</yourPackage.DoubleScrollView>

通过按 + 和 - 按钮,您可以填充滚动视图并查看布局如何反应。

© www.soinside.com 2019 - 2024. All rights reserved.