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:
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:
- position the 2 status bars (green/blue ones) on top/bottom edges as shown.
- 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" ).
- 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)
- the status bar widths should match the FrameLayout width, once done. They have been constrained to the end of the FrameLayout.
- 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:
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:
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
and likewise, if I just add a 5th col of buttons, and change ratio to 5:3 ..
this is good for me .. as I indicated, my board is static size, so just after the auto resizing to the different screen sizes.