androidkotlincustom-view

andorid ViewGroup childs isn't resized after onMeasure


I want to create my own ViewGroup with ImageView and some other views. I do this as follows (i have removed adding of other views for simplyfing the example):

class TestWidget @JvmOverloads constructor(
  context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

  init {
    addViews()
  }      

  private fun addViews() {
    val backgroundView = ImageView(context)
    backgroundView.setImageDrawable(resources.getDrawable(R.drawable.kitten)) // image is 640x640 px
    addView(backgroundView)

    val text = TextView(context)
    text.text = "My awesome cat"
    text.textSize = 10.dp.toFloat()
    text.setTextColor(Color.WHITE)

    addView(text)

    text.layoutParams = LayoutParams(
      LayoutParams.WRAP_CONTENT,
      LayoutParams.WRAP_CONTENT
    ).apply {
      rightToRight = id
      leftToLeft = id
      topToTop = id
      bottomToBottom = id
    }
  }
}

I put this widget into xml as follows:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp">

    <com.test.TestWidget
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</FrameLayout>

The result is perfect (cat with text in the center):

enter image description here

Now i want to make my TestWidget always square. For that i am override onMeasure as follows (for portrait layout):

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  setMeasuredDimension(measuredWidth, measuredWidth)
}

And after that my cat becomes broken:

enter image description here

As you can see, my widget's height becomes equal to its width, but the ImageView is not redrawn, and is cut off. TextView is not redrawn too and is situated not in the center of my widget. I want to remove that empty space above the ImageView.

I tried to fix this behaviour with different ways: setting layout params to backgroundView with constraint, call invalidate() and requestLayout() from onSizeChanged() callback, but nothing helps. What i am doing wrong?


Solution

  • Override onMeasure like this way:

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec)
    }