2

so I am trying to build a UI for my Android-App that should look similar to this picture. The problem is that the textSize of them is obviously different because the length of the strings is different, but I need them to be the same size. I found two solutions:

  1. Leave them like this, get the four sizes and choose the smallest for them (still using the a autoSizeTextType="uniform" provided by Android)

  2. Loop through the textsizes for all the buttons until the lineCount is greater than one and choose the smallest once again

The problem is that both need the Layout fully loaded. If it isn’t fully loaded all three autosized Buttons will return the same size or lineCount will return 0 (I am aware that there is a solution here on StackOverflow but it doesn't work for me).

I am aware that the lifecycle (https://developer.android.com/guide/components/activities/activity-lifecycle) specifies that the Activity should be fully loaded onReasume() but that isn’t true as well.

Do you guys know a better solution than the two of mine or how to get them to work?

Here is my XML-File:

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.5" />

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

<Button
    android:id="@+id/btn_1"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="#009688"
    android:autoSizeTextType="uniform"
    android:maxLines="1"
    android:text="12"
    app:layout_constraintBottom_toTopOf="@+id/guideline"
    app:layout_constraintEnd_toStartOf="@+id/guideline2"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btn_2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="#E91E63"
    android:autoSizeTextType="uniform"
    android:maxLines="1"
    android:text="Test12"
    app:layout_constraintBottom_toTopOf="@+id/guideline"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@+id/guideline2"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btn_3"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="#FF5722"
    android:autoSizeTextType="uniform"
    android:maxLines="1"
    android:text="Hi"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/guideline2"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline" />

<Button
    android:id="@+id/btn_4"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="#673AB7"
    android:autoSizeTextType="uniform"
    android:maxLines="1"
    android:text="Hello World"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@+id/guideline2"
    app:layout_constraintTop_toTopOf="@+id/guideline" />

MainActivity:

package com.example.testsizes

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*



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

Thanks in advance!

WorstCoder
  • 23
  • 4

1 Answers1

1

For getting your views params before the view is visible to the user you can use the OnPreDrawListener.

First, make your class implement ViewTreeObserver.OnPreDrawListener -

class MyClass : ViewTreeObserver. OnPreDrawListener

Register your listener in your onResume callback or onCreate just for now -

mYourView.viewTreeObserver.addOnPreDrawListener(this)

*Best practice is to register your listeners in the onResume Callback of your view and unregister them in your onPause callback.

Now enjoy the onPreDraw callback that you've been asked to initiate after implementing the listener on your class -

override fun onPreDraw(): Boolean {
    mYourView.viewTreeObserver.removeOnPreDrawListener(this)
   // Get the params you need from mYourView

    return false
}
Itay Feldman
  • 846
  • 10
  • 23
  • Could you elaborate on where to put everything because I can't get it to work properly. Thanks! – WorstCoder Nov 17 '19 at 11:21
  • @WorstCoder Tried simplifying it more. Let me know if you're still having troubles. – Itay Feldman Nov 17 '19 at 11:29
  • So my MainActivity needs to inherit "ViewTreeObserver.OnDrawListener"? – WorstCoder Nov 17 '19 at 12:08
  • @WorstCoder Its more of implementation than inheritance cause you don't extend the class just implement its methods, make sure you add the listener on your view - mYourView.viewTreeObserver.addOnPreDrawListener(this) – Itay Feldman Nov 17 '19 at 12:15
  • I tried that but whenever I try to inherit it, I get the Error: "Expecting a top level declaration". – WorstCoder Nov 17 '19 at 12:21
  • @WorstCoder Can you post your MainActivity? – Itay Feldman Nov 17 '19 at 12:26
  • I added the MainActivity, it is a regular empty Activity created by AndroidStudio. I haven't added the "ViewTreeObserver.OnDrawListener" but I can if you want me to. – WorstCoder Nov 17 '19 at 12:40
  • Since you really don't have anything special in your activity maybe try this answer a ridiculous bug but might just be it :) https://stackoverflow.com/questions/55017476/android-kotlin-error-expecting-a-top-level-declaration-task-appbuildinfog – Itay Feldman Nov 17 '19 at 12:46
  • Everything works now! Thanks a lot! The problem with the inhertiance was that I used ":" instead of ",", my mistake sorry. The only thing you need to change in your answer ist that you have "class MyClass : ViewTreeObserver.OnDrawListener" but it should be "class MyClass : ViewTreeObserver.OnPreDrawListener". – WorstCoder Nov 17 '19 at 12:57