如何获取设置wrap_content属性后的Button尺寸?解决取值为0问题
嘿,我明白你现在遇到的问题了——明明给Button设置了wrap_content,调用measure()后用getWidth()/getHeight()却拿到0,没法统一两个按钮的大小。别着急,我来一步步帮你理清原因和解决方案~
为什么会拿到0?
你踩了一个很常见的Android布局坑:getWidth()和getHeight()返回的是View完成布局(layout阶段)后的实际显示尺寸,而measure()只是完成了测量阶段。在你调用measure()之后,系统还没执行布局步骤,这时候这两个方法自然返回0。
正确的做法是,在测量完成后,用getMeasuredWidth()和getMeasuredHeight()来获取测量后的尺寸——这两个方法才对应measure()阶段的结果。
靠谱的解决方案
下面给你两种可行的方案,根据你的场景选就行:
方案一:手动测量+设置固定尺寸
这种方法适合你能确定父布局约束的情况,直接手动触发测量,拿到尺寸后统一设置:
// 创建第一个按钮 Button firstButton = new Button(activity); LinearLayout.LayoutParams firstParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f); footerLayout.addView(firstButton, firstParams); // 创建第二个按钮 Button secondaryButton = new Button(activity); LinearLayout.LayoutParams secondaryParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f); footerLayout.addView(secondaryButton, 0, secondaryParams); // 准备测量规格:用UNSPECIFIED让Button按自身内容测量 int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); // 执行测量 firstButton.measure(widthSpec, heightSpec); secondaryButton.measure(widthSpec, heightSpec); // 获取测量后的尺寸 int firstMeasuredWidth = firstButton.getMeasuredWidth(); int firstMeasuredHeight = firstButton.getMeasuredHeight(); int secondMeasuredWidth = secondaryButton.getMeasuredWidth(); int secondMeasuredHeight = secondaryButton.getMeasuredHeight(); // 计算最大宽高 int maxWidth = Math.max(firstMeasuredWidth, secondMeasuredWidth); int maxHeight = Math.max(firstMeasuredHeight, secondMeasuredHeight); // 给两个按钮设置统一尺寸 firstParams.width = maxWidth; firstParams.height = maxHeight; firstButton.setLayoutParams(firstParams); secondaryParams.width = maxWidth; secondaryParams.height = maxHeight; secondaryButton.setLayoutParams(secondaryParams);
方案二:监听布局完成(更可靠)
如果父布局的尺寸还没确定(比如依赖屏幕大小、其他View的尺寸),手动测量可能不够准确,这时候可以用ViewTreeObserver监听布局完成事件,等所有View都布局好再获取尺寸:
// 先创建并添加按钮(和你原来的代码一样) Button firstButton = new Button(activity); LinearLayout.LayoutParams firstParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f); footerLayout.addView(firstButton, firstParams); Button secondaryButton = new Button(activity); LinearLayout.LayoutParams secondaryParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f); footerLayout.addView(secondaryButton, 0, secondaryParams); // 监听布局完成 footerLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 记得移除监听,避免重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { footerLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { footerLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // 现在可以安全获取实际尺寸了 int firstWidth = firstButton.getWidth(); int firstHeight = firstButton.getHeight(); int secondWidth = secondaryButton.getWidth(); int secondHeight = secondaryButton.getHeight(); // 计算最大宽高并设置 int maxWidth = Math.max(firstWidth, secondWidth); int maxHeight = Math.max(firstHeight, secondHeight); firstParams.width = maxWidth; firstParams.height = maxHeight; firstButton.setLayoutParams(firstParams); secondaryParams.width = maxWidth; secondaryParams.height = maxHeight; secondaryButton.setLayoutParams(secondaryParams); } });
小提醒
你原来的代码里给按钮加了权重1f,设置固定宽高后权重就不会生效了哦。如果想要两个按钮既保持相同大小,又能平分父布局的剩余空间,可以考虑把宽高设为MATCH_PARENT,同时设置minWidth和minHeight为计算出的最大尺寸——不过这得看你的具体需求啦。
内容的提问来源于stack exchange,提问作者Liran Siman Tov
相关产品推荐
相关产品推荐

