Search code examples
javaandroidkotlinandroid-linearlayoutandroid-scrollview

Android: center LinearLayout inside ScrollView in Java / Kotlin


I have this code in XML and it works as I require (LinearLayout is centered inside the 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:background="@android:color/holo_red_dark"
        android:layout_gravity="center">

       <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="some text" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="some text" />
    </LinearLayout>
</ScrollView>

But I need this code in Java/Kotlin, however, I fail in correctly setting android:layout_gravity, because LinearLayout is still on top, and not centered. Here is my Kotlin code:

ScrollView(context).also { scrollView ->
    scrollView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)

    LinearLayout(context).also { linearLayout ->
        linearLayout.orientation = LinearLayout.VERTICAL
        linearLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply {
            gravity = Gravity.CENTER // have tried this
            weight = 1f // and have tried this
        }
        linearLayout.gravity = Gravity.CENTER // have tried this
        linearLayout.setBackgroundColor(0xff_00_ff_00.toInt())

        IntRange(0, 2).forEach {
            linearLayout.addView(TextView(context!!).apply {
                text = "some text"
                textSize = 50f
            })
        }

        scrollView.addView(linearLayout)
    }
}

The only way how I managed to get it work is by setting isFillViewport to true for the ScrollView, but in this case the LinearLayout takes the full height and it's not exactly what I want. Will appreciate any help, pieces of advice


Solution

  • The solution was simple, however, not obvious. I needed to change LinearLayout.LayoutParams to FrameLayout.LayoutParams. So the final code in Kotlin looks like this:

    ScrollView(context).also { scrollView ->
        scrollView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
    
        LinearLayout(context).also { linearLayout ->
            // I changed this line of code
            linearLayout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply {
                gravity = Gravity.CENTER
            }
    
            linearLayout.orientation = LinearLayout.VERTICAL
            linearLayout.setBackgroundColor(0xff_00_ff_00.toInt())
    
            IntRange(0, 1).forEach {
                linearLayout.addView(TextView(context!!).apply {
                    text = "some text"
                    textSize = 50f
                })
            }
    
            scrollView.addView(linearLayout)
        }
    }