android ViewGroup child 在 onMeasure 之后没有调整大小
andorid ViewGroup childs isn't resized after onMeasure
我想用 ImageView
和其他一些视图创建自己的 ViewGroup。我这样做如下(我已经删除了添加其他视图以简化示例):
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
}
}
}
我把这个小部件放入xml如下:
<?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>
结果很完美(中间有文字的猫):
现在我想让我的 TestWidget 总是方形的。为此,我重写 onMeasure
如下(对于纵向布局):
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(measuredWidth, measuredWidth)
}
然后我的猫就坏了:
如您所见,我的小部件的高度等于它的宽度,但是 ImageView
没有重绘,而是被截断了。 TextView
也没有重新绘制并且不在我的小部件的中心。我想删除 ImageView
.
上方的空 space
我尝试用不同的方式修复此行为:将布局参数设置为带约束的 backgroundView,从 onSizeChanged()
回调中调用 invalidate()
和 requestLayout()
,但没有任何帮助。我做错了什么?
像这样重写 onMeasure
:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec)
}
我想用 ImageView
和其他一些视图创建自己的 ViewGroup。我这样做如下(我已经删除了添加其他视图以简化示例):
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
}
}
}
我把这个小部件放入xml如下:
<?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>
结果很完美(中间有文字的猫):
现在我想让我的 TestWidget 总是方形的。为此,我重写 onMeasure
如下(对于纵向布局):
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(measuredWidth, measuredWidth)
}
然后我的猫就坏了:
如您所见,我的小部件的高度等于它的宽度,但是 ImageView
没有重绘,而是被截断了。 TextView
也没有重新绘制并且不在我的小部件的中心。我想删除 ImageView
.
我尝试用不同的方式修复此行为:将布局参数设置为带约束的 backgroundView,从 onSizeChanged()
回调中调用 invalidate()
和 requestLayout()
,但没有任何帮助。我做错了什么?
像这样重写 onMeasure
:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec)
}