我正在动态地创建我的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);
}

任何帮助都是感激的。


当前回答

我们需要等待绘制视图。为此,请使用OnPreDrawListener。芬兰湾的科特林的例子:

val preDrawListener = object : ViewTreeObserver.OnPreDrawListener {

                override fun onPreDraw(): Boolean {
                    view.viewTreeObserver.removeOnPreDrawListener(this)

                    // code which requires view size parameters

                    return true
                }
            }

            view.viewTreeObserver.addOnPreDrawListener(preDrawListener)

其他回答

我们需要等待绘制视图。为此,请使用OnPreDrawListener。芬兰湾的科特林的例子:

val preDrawListener = object : ViewTreeObserver.OnPreDrawListener {

                override fun onPreDraw(): Boolean {
                    view.viewTreeObserver.removeOnPreDrawListener(this)

                    // code which requires view size parameters

                    return true
                }
            }

            view.viewTreeObserver.addOnPreDrawListener(preDrawListener)

带post的答案是不正确的,因为大小可能无法重新计算。 另一个重要的事情是视图和所有它的祖先必须是可见的。为此,我使用属性view . isshows。

下面是我的kotlin函数,它可以放在utils中的某个地方:

fun View.onInitialized(onInit: () -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            if (isShown) {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                onInit()
            }
        }
    })
}

用法是:

myView.onInitialized {
    Log.d(TAG, "width is: " + myView.width)
}

如果你担心过度工作的onDraw方法,你可以总是设置维度为空在构造过程中,然后只设置onDraw内部的维度,如果它是空的。

这样你就不会在onDraw内部做任何工作

class myView(context:Context,attr:AttributeSet?):View(context,attr){
var height:Float?=null


override fun onDraw(canvas:Canvas){
    if (height==null){height=this.height.toFloat()}
    }
}

如果您正在使用Kotlin

  customView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {

            override fun onGlobalLayout() {

                if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    customView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
                else {
                    customView.viewTreeObserver.removeGlobalOnLayoutListener(this)
                }

                // Here you can get the size :)
                viewWidth = customView.width
            }
        })

这是因为视图需要更多的时间来膨胀。所以不用调用view。宽度和视图。主线程上的高度,你应该使用视图。Post{…}以确保你的观点已经被夸大了。在芬兰湾的科特林:

view.post{width}
view.post{height}

在Java中,您还可以在Runnable中调用getWidth()和getHeight()方法,并将Runnable传递给view.post()方法。

view.post(new Runnable() {
        @Override
        public void run() {
            view.getWidth(); 
            view.getHeight();
        }
    });