java - View 的 getWidth() 和 getHeight() 返回 0

标签 java android android-layout getter

我正在动态创建我的 android 项目中的所有元素。我正在尝试获取按钮的宽度和高度,以便可以旋转该按钮。我只是想学习如何使用 android 语言。但是,它返回 0。

我做了一些研究,发现它需要在 onCreate() 方法之外的其他地方完成。如果有人可以给我一个如何做的例子,那就太好了。

这是我当前的代码:

package com.animation;

import android.app.Activity;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;

public class AnimateScreen extends Activity {


//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LinearLayout ll = new LinearLayout(this);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    layoutParams.setMargins(30, 20, 30, 0);

    Button bt = new Button(this);
    bt.setText(String.valueOf(bt.getWidth()));

    RotateAnimation ra = new RotateAnimation(0,360,bt.getWidth() / 2,bt.getHeight() / 2);
    ra.setDuration(3000L);
    ra.setRepeatMode(Animation.RESTART);
    ra.setRepeatCount(Animation.INFINITE);
    ra.setInterpolator(new LinearInterpolator());

    bt.startAnimation(ra);

    ll.addView(bt,layoutParams);

    setContentView(ll);
}

感谢任何帮助。

最佳答案

基本问题是,您必须等待绘图阶段才能进行实际测量(尤其是使用 wrap_contentmatch_parent 等动态值),但通常是这个阶段直到 onResume() 还没有完成。所以你需要一个解决方法来等待这个阶段。对此有不同的可能解决方案:

1。监听绘图/布局事件:ViewTreeObserver

ViewTreeObserver 因不同的绘图事件而被触发。通常是 OnGlobalLayoutListener是您获取测量值所需的内容,因此监听器中的代码将在布局阶段之后被调用,因此测量值已准备就绪:

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                view.getHeight(); //height is ready
            }
        });

注意:监听器将被立即删除,否则它将在每个布局事件上触发。如果您必须支持应用程序SDK Lvl < 16,请使用此取消注册监听器:

public void removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener 受害者)


2。添加一个runnable到布局队列:View.post()

不是很出名,也是我最喜欢的解决方案。基本上只需将 View 的 post 方法与您自己的可运行文件一起使用。如Romain Guy 所述,这基本上将您的代码排在 View 的度量、布局等之后。 :

The UI event queue will process events in order. After setContentView() is invoked, the event queue will contain a message asking for a relayout, so anything you post to the queue will happen after the layout pass

例子:

final View view=//smth;
...
view.post(new Runnable() {
            @Override
            public void run() {
                view.getHeight(); //height is ready
            }
        });

优于ViewTreeObserver:

  • 您的代码只执行一次,您不必在执行后禁用 Observer,这可能很麻烦
  • 简洁的语法

引用资料:


3。覆盖 Views 的 onLayout 方法

这仅在逻辑可以封装在 View 本身中的某些情况下才实用,否则这是一种非常冗长和繁琐的语法。

view = new View(this) {
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        view.getHeight(); //height is ready
    }
};

还要注意,onLayout 会被多次调用,所以要考虑你在方法中做了什么,或者在第一次之后禁用你的代码


4。检查是否已经通过布局阶段

如果您在创建 ui 时有多次执行的代码,您可以使用以下支持 v4 lib 方法:

View viewYouNeedHeightFrom = ...
...
if(ViewCompat.isLaidOut(viewYouNeedHeightFrom)) {
   viewYouNeedHeightFrom.getHeight();
}

Returns true if view has been through at least one layout since it was last attached to or detached from a window.

附加:获取静态定义的测量值

如果只获得静态定义的高度/宽度就足够了,您可以这样做:

但请注意,这可能与绘制后的实际宽度/高度不同。 javadoc 更详细地描述了差异:

The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.

The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().

The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().

关于java - View 的 getWidth() 和 getHeight() 返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3591784/

相关文章:

java - 我应该绑定(bind)我的服务还是多次调用 startService ?

java - 数组越界异常? (正在制作康威的生命游戏)

android - 找不到 com.android.support :support-v4:21. 0.2

java - 如何简化 Android 小部件中 View 的设置值

android - 如何截取Activity的内容,包括PopupWindows和AlertDialogs?

java - 飞行路线设置问题

java - Android - 外部存储的可用空间无法正确显示

android - View 模型不断创建实时数据的实例

java - Google 端点 - Android GoogleAuthIOException Tic Tac Toe - 删除了 clientIds

Android:如何从传入的短信中获取电话号码?