Android屏幕适配利器:Kotlin动态尺寸计算工具类完整封装
Kotlin 动态计算尺寸工具类封装
以下是使用 Kotlin 实现的动态计算尺寸工具类,包含基础版和增强版功能。
1. 基础工具类封装
import android.content.Context
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroupobject ViewSizeUtils {/*** 按屏幕宽度百分比设置View的宽度* @param view 需要设置的View* @param widthPercent 宽度百分比 (0.0 - 1.0)*/fun setWidthByScreenPercent(view: View, widthPercent: Float) {if (widthPercent <= 0 || widthPercent > 1) returnval displayMetrics = getDisplayMetrics(view.context)view.updateLayoutParams {width = (displayMetrics.widthPixels * widthPercent).toInt()}}/*** 按屏幕高度百分比设置View的高度* @param view 需要设置的View* @param heightPercent 高度百分比 (0.0 - 1.0)*/fun setHeightByScreenPercent(view: View, heightPercent: Float) {if (heightPercent <= 0 || heightPercent > 1) returnval displayMetrics = getDisplayMetrics(view.context)view.updateLayoutParams {height = (displayMetrics.heightPixels * heightPercent).toInt()}}/*** 按屏幕宽高百分比同时设置View的宽高* @param view 需要设置的View* @param widthPercent 宽度百分比 (0.0 - 1.0)* @param heightPercent 高度百分比 (0.0 - 1.0)*/fun setSizeByScreenPercent(view: View, widthPercent: Float, heightPercent: Float) {if (widthPercent <= 0 || widthPercent > 1 || heightPercent <= 0 || heightPercent > 1) returnval displayMetrics = getDisplayMetrics(view.context)view.updateLayoutParams {width = (displayMetrics.widthPixels * widthPercent).toInt()height = (displayMetrics.heightPixels * heightPercent).toInt()}}/*** 按父容器宽度百分比设置View的宽度* @param view 需要设置的View* @param widthPercent 宽度百分比 (0.0 - 1.0)*/fun setWidthByParentPercent(view: View, widthPercent: Float) {if (widthPercent <= 0 || widthPercent > 1 || view.parent !is View) returnval parent = view.parent as Viewval parentWidth = parent.widthif (parentWidth <= 0) {parent.post {setViewWidth(view, (parent.width * widthPercent).toInt())}} else {setViewWidth(view, (parentWidth * widthPercent).toInt())}}private fun setViewWidth(view: View, width: Int) {view.updateLayoutParams {this.width = width}}private fun getDisplayMetrics(context: Context): DisplayMetrics {return context.resources.displayMetrics}private inline fun View.updateLayoutParams(block: ViewGroup.LayoutParams.() -> Unit) {val params = layoutParams ?: ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT).also { layoutParams = it }params.block()layoutParams = params}
}
2. 增强版工具类(支持更多功能)
import android.content.Context
import android.view.View
import android.view.ViewGroup
import kotlin.math.roundToIntobject ViewSizeHelper {/*** 设置View的宽高比(基于宽度计算高度)* @param view 目标View* @param aspectRatio 宽高比(宽度/高度)*/fun setAspectRatio(view: View, aspectRatio: Float) {if (aspectRatio <= 0) returnview.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {override fun onLayoutChange(v: View,left: Int, top: Int, right: Int, bottom: Int,oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {val width = right - leftif (width > 0) {v.updateLayoutParams {height = (width / aspectRatio).roundToInt()}v.removeOnLayoutChangeListener(this)}}})}/*** 设置View的最小高度(单位:dp)*/fun setMinHeightDp(view: View, minHeightDp: Int) {view.minimumHeight = dpToPx(view.context, minHeightDp)}/*** 设置View的最小宽度(单位:dp)*/fun setMinWidthDp(view: View, minWidthDp: Int) {view.minimumWidth = dpToPx(view.context, minWidthDp)}/*** 设置View的固定尺寸(单位:dp)*/fun setFixedSizeDp(view: View, widthDp: Int, heightDp: Int) {view.updateLayoutParams {width = dpToPx(view.context, widthDp)height = dpToPx(view.context, heightDp)}}/*** 设置View的宽度(单位:dp)*/fun setWidthDp(view: View, widthDp: Int) {view.updateLayoutParams {width = dpToPx(view.context, widthDp)}}/*** 设置View的高度(单位:dp)*/fun setHeightDp(view: View, heightDp: Int) {view.updateLayoutParams {height = dpToPx(view.context, heightDp)}}/*** 设置View的margin(单位:dp)*/fun setMarginsDp(view: View,leftDp: Int = Int.MIN_VALUE,topDp: Int = Int.MIN_VALUE,rightDp: Int = Int.MIN_VALUE,bottomDp: Int = Int.MIN_VALUE) {val params = view.layoutParams as? ViewGroup.MarginLayoutParams ?: returnif (leftDp != Int.MIN_VALUE) params.leftMargin = dpToPx(view.context, leftDp)if (topDp != Int.MIN_VALUE) params.topMargin = dpToPx(view.context, topDp)if (rightDp != Int.MIN_VALUE) params.rightMargin = dpToPx(view.context, rightDp)if (bottomDp != Int.MIN_VALUE) params.bottomMargin = dpToPx(view.context, bottomDp)view.layoutParams = params}private fun dpToPx(context: Context, dp: Int): Int {return (dp * context.resources.displayMetrics.density).roundToInt()}private inline fun View.updateLayoutParams(block: ViewGroup.LayoutParams.() -> Unit) {val params = layoutParams ?: ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT).also { layoutParams = it }params.block()layoutParams = params}
}
3. 扩展函数版本(更 Kotlin 化的实现)
import android.content.Context
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup
import kotlin.math.roundToInt// 扩展属性:获取屏幕宽度
val Context.screenWidth: Intget() = resources.displayMetrics.widthPixels// 扩展属性:获取屏幕高度
val Context.screenHeight: Intget() = resources.displayMetrics.heightPixels// 扩展函数:dp转px
fun Context.dpToPx(dp: Int): Int = (dp * resources.displayMetrics.density).roundToInt()// 扩展函数:更新LayoutParams
inline fun View.updateLayoutParams(block: ViewGroup.LayoutParams.() -> Unit) {val params = layoutParams ?: ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT).also { layoutParams = it }params.block()layoutParams = params
}// 基础功能扩展函数
fun View.setWidthByScreenPercent(widthPercent: Float) {if (widthPercent <= 0 || widthPercent > 1) returnupdateLayoutParams {width = (context.screenWidth * widthPercent).toInt()}
}fun View.setHeightByScreenPercent(heightPercent: Float) {if (heightPercent <= 0 || heightPercent > 1) returnupdateLayoutParams {height = (context.screenHeight * heightPercent).toInt()}
}fun View.setSizeByScreenPercent(widthPercent: Float, heightPercent: Float) {if (widthPercent <= 0 || widthPercent > 1 || heightPercent <= 0 || heightPercent > 1) returnupdateLayoutParams {width = (context.screenWidth * widthPercent).toInt()height = (context.screenHeight * heightPercent).toInt()}
}// 增强功能扩展函数
fun View.setAspectRatio(aspectRatio: Float) {if (aspectRatio <= 0) returnaddOnLayoutChangeListener(object : View.OnLayoutChangeListener {override fun onLayoutChange(v: View,left: Int, top: Int, right: Int, bottom: Int,oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {val width = right - leftif (width > 0) {v.updateLayoutParams {height = (width / aspectRatio).roundToInt()}v.removeOnLayoutChangeListener(this)}}})
}fun View.setMinHeightDp(minHeightDp: Int) {minimumHeight = context.dpToPx(minHeightDp)
}fun View.setMinWidthDp(minWidthDp: Int) {minimumWidth = context.dpToPx(minWidthDp)
}fun View.setFixedSizeDp(widthDp: Int, heightDp: Int) {updateLayoutParams {width = context.dpToPx(widthDp)height = context.dpToPx(heightDp)}
}
4. 使用示例
基础工具类使用
// 设置按钮宽度为屏幕的50%
ViewSizeUtils.setWidthByScreenPercent(myButton, 0.5f)// 设置图片高度为屏幕的30%
ViewSizeUtils.setHeightByScreenPercent(myImageView, 0.3f)// 设置TextView宽高分别为屏幕的80%和20%
ViewSizeUtils.setSizeByScreenPercent(myTextView, 0.8f, 0.2f)// 设置RecyclerView宽度为父容器的70%
ViewSizeUtils.setWidthByParentPercent(recyclerView, 0.7f)
增强工具类使用
// 设置图片16:9的宽高比
ViewSizeHelper.setAspectRatio(myImageView, 16f/9f)// 设置按钮最小高度为48dp
ViewSizeHelper.setMinHeightDp(myButton, 48)// 设置固定尺寸为100dp×50dp
ViewSizeHelper.setFixedSizeDp(iconView, 100, 50)// 设置margin
ViewSizeHelper.setMarginsDp(view = myView,leftDp = 16,topDp = 8,rightDp = 16,bottomDp = 8
)
扩展函数版本使用
// 使用扩展函数更简洁
myButton.setWidthByScreenPercent(0.5f)
myImageView.setHeightByScreenPercent(0.3f)
myTextView.setSizeByScreenPercent(0.8f, 0.2f)// 设置宽高比
myVideoView.setAspectRatio(16f/9f)// 设置最小尺寸
floatingButton.setMinWidthDp(48)
floatingButton.setMinHeightDp(48)// 设置固定尺寸
iconView.setFixedSizeDp(100, 50)
这些 Kotlin 实现充分利用了语言特性,如扩展函数、属性、lambda 表达式等,使代码更加简洁易用。根据项目需求,可以选择工具类形式或扩展函数形式来实现动态尺寸计算。