I am building a checkers game. The checkers board is defined as a GridView with 8 columns and 8 rows. Each red tile is an ImageButton, and each black tile is an ImageView (because red tiles are playable and black tiles are not). The ImageButtons and ImageViews each have a drawable in them that is either a red checker, a black checker, or no checker. Each drawable is 50dpx50dp.
I am trying to get the board to resize itself so that it always fills about 80% of the available screen. The first thing I tried is creating "small", "large", and "xlarge" variants of the drawables, and that gets me pretty close, but the difference between a "small" screen and a "large" screen is pretty substantial, and this results in a lot of wasted screen real estate on devices that fall somewhere in the middle between "small" and "large".
I'd like to programmatically resize the drawable based on a calculation involving the current screen resolution. I'm happy to implement a screen resolution listener, but I'm not sure how to connect the listener to the drawable images, or if there's a better way to do this.
I did some Googling to see what I can find, and most of the stuff I came across talked about using different pixel densities, but that's not really the problem I have. I also found a bunch of stuff about using relative layouts and so on, but that doesn't work for a checker board.
I'd greatly appreciate any suggestions at all as to how to accomplish this. Thanks!
EDITED TO ADD
Based on the comment from @ben-p I have modified my code, and I'm getting closer. In my layout file, I now have:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp">
<fragment
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And in the fragment layout file, I have:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="8"
android:rowCount="8">
<ImageButton
android:id="@ id/Tile00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#cc0000"
android:contentDescription="@string/game_checkers_red_tile"
android:padding="0dp"
android:src="@drawable/game_checkers_player_none" />
<ImageView
android:background="#000000"
android:contentDescription="@string/game_checkers_black_tile"
android:padding="0dp"
android:src="@drawable/game_checkers_player_none" />
<!-- repeated for a total of 64 tiles -->
</GridLayout>
This constrains the checkerboard to a square on the screen with a 1:1 aspect ratio, but it is not scaling the checkerboard to show all 8x8 tiles. In the example below, you can see that the board is cropped:
What's the magic incantation to get the ConstraintLayout to scale up/down the contents of the fragment so that it always fits exactly in the space provided?
CodePudding user response:
I had to change the main view code a bit:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And then I had to change the fragment layout code as follows:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="8"
android:rowCount="8">
<ImageButton
android:id="@ id/Tile00"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:background="#cc0000"
android:contentDescription="@string/game_checkers_red_tile"
android:padding="0dp"
android:src="@drawable/game_checkers_player_none" />
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:background="#000000"
android:contentDescription="@string/game_checkers_black_tile"
android:padding="0dp"
android:src="@drawable/game_checkers_player_none" />
<!-- repeated for a total of 64 tiles -->
</GridLayout>
Once I did that, the checkerboard now scales up to fill the available space.