Home > Mobile >  Android: Resizing Views Based On Screen Resolution
Android: Resizing Views Based On Screen Resolution

Time:04-01

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:

enter image description here

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.

  • Related