Home > Back-end >  how to adjust width of FrameLayout during app startup in kotlin
how to adjust width of FrameLayout during app startup in kotlin

Time:04-08

So I am new to Kotlin, so I realize this may be a bit basic, however, I've done a lot of searching and tried a few different things and not yet having any luck.

So I've got a simple layout I'm aiming for, with the main area a "chess-like" board of cells. I've managed to get everything together and all runs fine, however, when I try to implement resizing things (to accomodate different sized devices/resolutions/etc), I can't seem to figure out exactly how to handle that.

This is a simplified version of what I'm trying to do:

Board sample

As seen in the image, I have some "items" on the right side of the screen that will take up some space, however, the primary driving item will be the main playing board (for now, that grid of 4x4 buttons).

Explaining it in plain English, I'd like it to:

  1. position the 2 status bars (green/blue ones) on top/bottom edges as shown.
  2. Grid (a FrameLayout holding a TableLayout), is constrained to the top/bottom of these status bars, so the Height should be "set" to that difference. I need to determine the size of each cell ( ie height used by the FrameLayout divided by # of "rows" ).
  3. To make/keep the grid cells "square", I need to resize the widths to match that of their height. I'm trying to set the Framelayout width to that. (in my final version the grid is not actually square, eg 4x6 - but keep in mind, the grid is a fixed size - it's not dynamic, it's just the size of the cells I need to adjust for changes in resolution)
  4. the status bar widths should match the FrameLayout width, once done. They have been constrained to the end of the FrameLayout.
  5. the big textView in Bottom right will use up whatever width is left. It has also been constrained to the end of the FrameLayout.

I've tried to constrain the right side of the FrameLayout (to parent/screen -200), I've also tried setting it to fix width (then adjust). I've tried some other things like Linear layouts, and had no success with any option.

Here's the activity_main.xml for this sample:

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#515151"
tools:context=".MainActivity">

<LinearLayout
    android:id="@ id/linearLayout2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="#4CAF50"
    android:orientation="horizontal"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="@ id/frLay01"
    app:layout_constraintStart_toStartOf="parent">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:layout_weight="1"
        app:cardCornerRadius="8dp">

        <TextView
            android:id="@ id/textView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text="TextView" />
    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:layout_weight="2"
        app:cardCornerRadius="8dp">

        <TextView
            android:id="@ id/textView3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text="TextView" />
    </androidx.cardview.widget.CardView>
</LinearLayout>

<LinearLayout
    android:id="@ id/linearLayout"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="#2196F3"
    android:orientation="horizontal"
    app:layout_constraintEnd_toEndOf="@ id/frLay01"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:layout_weight="1"
        app:cardCornerRadius="8dp">

        <TextView
            android:id="@ id/textView12"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text="TextView" />
    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:layout_weight="2"
        app:cardCornerRadius="8dp">

        <TextView
            android:id="@ id/textView13"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text="TextView" />
    </androidx.cardview.widget.CardView>
</LinearLayout>

<androidx.cardview.widget.CardView
    android:layout_width="0dp"
    android:layout_height="200dp"
    android:layout_margin="6dp"
    app:cardCornerRadius="8dp"
    app:cardElevation="8dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@ id/frLay01">

    <TextView
        android:id="@ id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="4dp"
        android:text="TextView" />
</androidx.cardview.widget.CardView>

<FrameLayout
    android:id="@ id/frLay01"
    android:layout_width="500dp"
    android:layout_height="0dp"
    android:layout_marginTop="6dp"
    android:layout_marginEnd="200dp"
    android:layout_marginBottom="6dp"
    app:layout_constraintBottom_toTopOf="@ id/linearLayout2"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@ id/linearLayout">

    <TableLayout
        android:id="@ id/tblLay01"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <ImageButton
                android:id="@ id/imageButton00"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton03"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

        </TableRow>

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

            <ImageButton
                android:id="@ id/imageButton10"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton12"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton13"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

        </TableRow>

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

            <ImageButton
                android:id="@ id/imageButton20"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton21"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton22"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton23"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

        </TableRow>

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

            <ImageButton
                android:id="@ id/imageButton30"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton31"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton32"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

            <ImageButton
                android:id="@ id/imageButton33"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@android:drawable/checkbox_off_background" />

        </TableRow>

    </TableLayout>
</FrameLayout>

<Button
    android:id="@ id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="40dp"
    android:layout_marginEnd="40dp"
    android:text="Button"
    android:textColor="#FFFFFF"
    app:backgroundTint="#0920A3"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

and the MainActivity.kt I'm trying is:

package com.example.test1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.ViewTreeObserver
import android.widget.FrameLayout

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    fun try1 () {
        var frLay = findViewById ( R.id.frLay01 ) as FrameLayout
        var cellSize = frLay.height / 8
      //  frLay.getLayoutParams().width = cellSize * 8

        Log.i("Test: try1", "cellSize = "   cellSize)
    }

    fun try2 () {
        var frLay = findViewById ( R.id.frLay01 ) as FrameLayout
        var cellSize = frLay.getLayoutParams().height / 8
      //  frLay.getLayoutParams().width = cellSize * 8

        Log.i("Test: try2", "cellSize = "   cellSize)
    }

    fun try3() {
        var frLay = findViewById ( R.id.frLay01 ) as FrameLayout
        var cellSize : Int = 0

        val viewTreeObserver: ViewTreeObserver = frLay.getViewTreeObserver()
        if (viewTreeObserver.isAlive) {
            viewTreeObserver.addOnGlobalLayoutListener(object :
                ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    frLay.getViewTreeObserver().removeOnGlobalLayoutListener(this)
                    cellSize = frLay.getHeight() / 8
                }
            })
        }
     //   frLay.getLayoutParams().width = cellSize * 8

        Log.i("Test: try3", "cellSize = "   cellSize)
    }

    try1()
    try2()
    try3()
}

}

Every time I run, I can't seem to get a Height for the FrameLayout .. it always comes back as 0. (which makes sense, since it's set to constrained) (I also tried measuredHeight .. also shows 0)

How should I be adjusting the size of this grid ? or is there some sneaky way to setup the constraints to do it properly with everything set to "match parent" ??

[edit] this is basically what I'm aiming for .. this is the closest I've gotten:

target board

Board flush with left side, squares of the board are "square", board flush with top/bottom status bars. width resizes to keep cells square, and status bars match. Textview on right uses up whatever area is left.

I managed the above using a Recylerview, setting app:layout_constraintDimensionRatio="W,3:4" unfortunately, I had to manually hardcode the cell size in Adaptor class (I was following this tutorial at the time and modifying to my ends: enter image description here

Main layout:

<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/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#707070">

    <androidx.constraintlayout.widget.Guideline
        android:id="@ id/statusBarsDivider"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".45" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@ id/statusBarsEnd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="20dp"
        app:layout_constraintGuide_percent=".67" />

    <View
        android:id="@ id/topStatusBarBackground"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="-8dp"
        android:background="#0080ff"
        app:layout_constraintBottom_toBottomOf="@ id/topTextViewLeft"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@ id/topTextViewLeft"
        style="@style/text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="TextView"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsDivider"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@ id/topTextViewRight"
        style="@style/text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="TextView"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintStart_toEndOf="@id/statusBarsDivider"
        app:layout_constraintTop_toTopOf="parent" />


    <View
        android:id="@ id/bottomStatusBarBackground"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="-8dp"
        android:background="#00C864"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@ id/bottomTextViewLeft" />

    <TextView
        android:id="@ id/bottomTextViewLeft"
        style="@style/text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsDivider"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@ id/bottomTextViewRight"
        style="@style/text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintStart_toEndOf="@id/statusBarsDivider" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@ id/horizontalCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="20dp"
        app:layout_constraintGuide_percent=".5" />

    <TextView
        android:id="@ id/textView3"
        style="@style/text_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintTop_toTopOf="@ id/horizontalCenter" />

    <Button
        android:id="@ id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="24dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <include
        layout="@layout/game_board"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        app:layout_constraintBottom_toTopOf="@ id/bottomStatusBarBackground"
        app:layout_constraintDimensionRatio="w,1:1"
        app:layout_constraintEnd_toStartOf="@ id/statusBarsEnd"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/topStatusBarBackground" />

</androidx.constraintlayout.widget.ConstraintLayout>

The game_board layout: (There's probably a much better way to do this. I created four horizontal and four vertical view chains and all of the views have 0dp height and width so the ConstraintLayout makes them all take up evenly divided space.)

<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:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@ id/cellA1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#3F51B5"
        app:layout_constraintBottom_toTopOf="@ id/cellB1"
        app:layout_constraintEnd_toStartOf="@ id/cellA2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/cellA2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#9C27B0"
        app:layout_constraintBottom_toTopOf="@ id/cellB2"
        app:layout_constraintEnd_toStartOf="@ id/cellA3"
        app:layout_constraintStart_toEndOf="@ id/cellA1"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/cellA3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#F44336"
        app:layout_constraintBottom_toTopOf="@ id/cellB3"
        app:layout_constraintEnd_toStartOf="@ id/cellA4"
        app:layout_constraintStart_toEndOf="@ id/cellA2"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/cellA4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#FFEB3B"
        app:layout_constraintBottom_toTopOf="@ id/cellB4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/cellA3"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/cellB1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#8BC34A"
        app:layout_constraintBottom_toTopOf="@ id/cellC1"
        app:layout_constraintEnd_toStartOf="@ id/cellB2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/cellA1" />

    <View
        android:id="@ id/cellB2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#2196F3"
        app:layout_constraintBottom_toTopOf="@ id/cellC2"
        app:layout_constraintEnd_toStartOf="@ id/cellB3"
        app:layout_constraintStart_toEndOf="@ id/cellB1"
        app:layout_constraintTop_toBottomOf="@ id/cellA2" />

    <View
        android:id="@ id/cellB3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#009688"
        app:layout_constraintBottom_toTopOf="@ id/cellC3"
        app:layout_constraintEnd_toStartOf="@ id/cellB4"
        app:layout_constraintStart_toEndOf="@ id/cellB2"
        app:layout_constraintTop_toBottomOf="@ id/cellA3" />

    <View
        android:id="@ id/cellB4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#CDDC39"
        app:layout_constraintBottom_toTopOf="@ id/cellC4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/cellB3"
        app:layout_constraintTop_toBottomOf="@ id/cellA4" />

    <View
        android:id="@ id/cellC1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#E91E63"
        app:layout_constraintBottom_toTopOf="@ id/cellD1"
        app:layout_constraintEnd_toStartOf="@ id/cellC2"
        app:layout_constraintTop_toBottomOf="@ id/cellB1"
        app:layout_constraintStart_toStartOf="parent" />

    <View
        android:id="@ id/cellC2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#3F51B5"
        app:layout_constraintBottom_toTopOf="@ id/cellD2"
        app:layout_constraintEnd_toStartOf="@ id/cellC3"
        app:layout_constraintTop_toBottomOf="@ id/cellB2"
        app:layout_constraintStart_toEndOf="@ id/cellC1" />

    <View
        android:id="@ id/cellC3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#CDDC39"
        app:layout_constraintBottom_toTopOf="@ id/cellD3"
        app:layout_constraintEnd_toStartOf="@ id/cellC4"
        app:layout_constraintStart_toEndOf="@ id/cellC2"
        app:layout_constraintTop_toBottomOf="@ id/cellB3" />

    <View
        android:id="@ id/cellC4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#2196F3"
        app:layout_constraintBottom_toTopOf="@ id/cellD4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/cellC3"
        app:layout_constraintTop_toBottomOf="@ id/cellB4" />

    <View
        android:id="@ id/cellD1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#00BCD4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/cellD2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/cellC1" />

    <View
        android:id="@ id/cellD2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#673AB7"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/cellD3"
        app:layout_constraintStart_toEndOf="@ id/cellD1"
        app:layout_constraintTop_toBottomOf="@ id/cellC2" />

    <View
        android:id="@ id/cellD3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#FF9800"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@ id/cellD4"
        app:layout_constraintStart_toEndOf="@ id/cellD2"
        app:layout_constraintTop_toBottomOf="@ id/cellC3" />

    <View
        android:id="@ id/cellD4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#E91E63"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/cellD3"
        app:layout_constraintTop_toBottomOf="@ id/cellC4" />
</androidx.constraintlayout.widget.ConstraintLayout>

CodePudding user response:

ah Ok .. I finally had a Eureka moment .. and thanks to this question

Working board

and likewise, if I just add a 5th col of buttons, and change ratio to 5:3 .. 5:3 board

this is good for me .. as I indicated, my board is static size, so just after the auto resizing to the different screen sizes.

  • Related