-1
<Button
  android:id="@+id/button"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" << Should probably change
  android:text="Button" />

How can i create a square button, when the width is set to wrap_content?

I have tried following the answer in this question:
Set button height equal to the button width
But I can't seem to get the width to actually match content, it just fills up the entire screen (similarly to match_parent)

TheSiIence
  • 327
  • 2
  • 10
  • Does this answer your question? [Set button height equal to the button width](https://stackoverflow.com/questions/29701234/set-button-height-equal-to-the-button-width) – jeprubio Dec 13 '19 at 20:26
  • Almost, I just couldn't get the width to wrap content, it fills all available space – TheSiIence Dec 13 '19 at 21:25

1 Answers1

0

I eventually achieved this requirement after some more research.

As some here pointed out, the solution given in most places was this (Converted to kotlin):

class SquareButton(context: Context, attrs: AttributeSet) : Button(context, attrs) {
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val width: Int = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(width, width)
    }
}

The problem with MeasureSpec.getSize in the scenario is that (along with MeasureSpec.getMode) it contains the sizing "rule" for the width.
In this case: size:(Available size) + mode:(AT_MOST) = the maximum width allowed for the button

The other option is to get the minimum width, already computed by the Button class:

class SquareButton(context: Context, attrs: AttributeSet) : Button(context, attrs) {
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val width: Int = measuredWidth
        setMeasuredDimension(width, width)
    }
}

getMeasuredWidth() returns the width measurement set in onMeasure() via setMeasuredDimension().

What is the difference between MeasureSpec.getSize(widthMeasureSpec) and getWidth()?

The measuredWidth property is set to the wrap_content value when calling super.onMeasure. This is the wanted value for the width and height.

TheSiIence
  • 327
  • 2
  • 10