背景
开发中偶尔遇到控件宽度或者高度在自适应的情况下,有个边界值,也就是最大值。
比如高度自适应的情况下最大高度300dp这种场景。
实现
关键节点代码:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//获取测量规范的尺寸://heightSize 和 widthSize 分别从 heightMeasureSpec 和 widthMeasureSpec 中提取尺寸。int heightSize = MeasureSpec.getSize(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int maxHeightMeasureSpec = heightMeasureSpec;int maxWidthMeasureSpec = widthMeasureSpec;//如果 maxHeight 不为 0,则将 heightSize 限制在 maxHeight 和 heightSize 的较小值,并重新创建 maxHeightMeasureSpec。if (maxHeight != 0) {heightSize = Math.min(heightSize, maxHeight);maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);}//如果 maxWidth 不为 0,则将 widthSize 限制在 maxWidth 和 widthSize 的较小值,并重新创建 maxWidthMeasureSpec。if (maxWidth != 0) {widthSize = Math.min(widthSize, maxWidth);maxWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);}//使用调整后的测量规范 maxWidthMeasureSpec 和 maxHeightMeasureSpec 调用父类的 onMeasure 方法,以完成测量过程。super.onMeasure(maxWidthMeasureSpec, maxHeightMeasureSpec);}
代码是通过自定义视图的 onMeasure 方法实现。
主要功能是根据传入的测量规范(MeasureSpec)和自定义的最大宽度(maxWidth)和最大高度(maxHeight)来确定视图的最终尺寸。
调整尺寸以满足最大宽度和高度限制,这样可以确保视图的尺寸不会超过指定的最大值。
实现类
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayoutclass CustomizeRelativeLayout @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {private var maxHeight = 0private var maxWidth = 0fun setMaxHeight(maxHeight: Int) {this.maxHeight = maxHeight}fun setMaxWidth(maxWidth: Int) {this.maxWidth = maxWidth}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {var heightMode = MeasureSpec.getMode(heightMeasureSpec)var heightSize = MeasureSpec.getSize(heightMeasureSpec)var widthSize = MeasureSpec.getSize(widthMeasureSpec)var maxHeightMeasureSpec = heightMeasureSpecvar maxWidthMeasureSpec = widthMeasureSpecif (maxHeight != 0) {heightSize = heightSize.coerceAtMost(maxHeight)maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST)}if (maxWidth != 0) {widthSize = widthSize.coerceAtMost(maxWidth)maxWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST)}super.onMeasure(maxWidthMeasureSpec, maxHeightMeasureSpec)}}
总结
这下好了kotlin和java都有了。
缺陷
容器确实能做到不超出指定宽高,但是子控件超出的话会被裁剪掉,不会去自动适应容器的宽高。下期说下怎么去规避掉这个问题。
答案:ViewTreeObserver.OnPreDrawListener