Android中如何用Kotlin获取布局/View运行时的wrap_content/match_parent宽高?
Android运行时获取View宽高并转换为Dip单位
直接在onCreate/onStart中调用getMeasuredWidth()或getWidth()通常会返回0——因为此时View还未完成测量布局。必须等View完成测量流程后再获取宽高,以下是几种可行方案:
方法一:利用ViewTreeObserver.OnGlobalLayoutListener
通过监听View树的全局布局完成事件,在回调中获取宽高并转换为Dip:
LinearLayout leftLayout = findViewById(R.id.layout_scrol_left); ViewTreeObserver observer = leftLayout.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听,避免重复触发回调 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { leftLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { leftLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // 获取View实际宽高(单位:px) int widthPx = leftLayout.getMeasuredWidth(); int heightPx = leftLayout.getMeasuredHeight(); // 转换为Dip单位 float widthDip = pxToDip(widthPx, leftLayout.getContext()); float heightDip = pxToDip(heightPx, leftLayout.getContext()); // 此处可使用转换后的宽高值 } });
方法二:使用OnLayoutChangeListener(API 11+)
给目标View设置布局变化监听,在布局完成后获取宽高:
LinearLayout leftLayout = findViewById(R.id.layout_scrol_left); leftLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { // 移除监听 v.removeOnLayoutChangeListener(this); int widthPx = v.getMeasuredWidth(); int heightPx = v.getMeasuredHeight(); float widthDip = pxToDip(widthPx, v.getContext()); float heightDip = pxToDip(heightPx, v.getContext()); } });
核心工具方法:Px转Dip
将像素值转换为Dip(设备独立像素)的工具方法:
private float pxToDip(int px, Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); return px / (displayMetrics.densityDpi / 160f); }
补充说明
getMeasuredWidth()与getWidth():前者是View测量阶段得到的宽度,后者是View最终显示在屏幕上的宽度,多数场景下两者数值一致;若View存在滚动、布局动态调整等情况,可能出现差异。- 自定义View场景:可直接重写
onMeasure()或onLayout()方法,在方法内部直接获取宽高并转换单位。
内容的提问来源于stack exchange,提问作者Peter Luo
相关产品推荐
相关产品推荐

