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

任何帮助都是感激的。


当前回答

如果您正在使用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
            }
        })

其他回答

public final class ViewUtils {

    public interface ViewUtilsListener {
        void onDrawCompleted();
    }

    private ViewUtils() {
    }

    public static void onDraw(View view, ViewUtilsListener listener) {
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (view.getHeight() != 0 && view.getWidth() != 0) {
                    if (listener != null) {
                        listener.onDrawCompleted();
                    }
                    view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            }
        });
    }
}

你可以这样用;

ViewUtils.onDraw(view, new ViewUtils.ViewUtilsListener() {
                @Override
                public void onDrawCompleted() {
                    int width = view.getWidth();
                    int height = view.getHeight();
                }
            });

如果你使用RxJava & RxBindings,一行。类似的方法没有样板。这也解决了蒂姆·奥廷(Tim Autin)的回答中隐藏警告的问题。

RxView.layoutChanges(yourView).take(1)
      .subscribe(aVoid -> {
           // width and height have been calculated here
      });

就是它了。不需要取消订阅,即使从未调用。

我们需要等待绘制视图。为此,请使用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)

如果您正在使用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
            }
        })

这是一个有点旧,但我自己有麻烦(需要在一个片段中创建动画对象)。这个解决方案对我来说很有效,我相信这是不言自明的。

class YourFragment: Fragment() {
    var width = 0
    var height = 0


override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val root = inflater.inflate(R.layout.fragment_winner_splash, container, false)
    container?.width.let {
        if (it != null) {
            width = it
        }
    }
    container?.height.let {
        if (it != null) {
            height = it
        }
    }
    
    return root
}