背景
開發中偶爾遇到控件寬度或者高度在自適應的情況下,有個邊界值,也就是最大值。
比如高度自適應的情況下最大高度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