Android:获取组件的宽和高,我们都知道在 onCreate() 里面获取控件的高度是 0, 这是为什么呢? 我们来看一下示例:
首先我们自己写一个控件, 这个控件非常简单:
- public class MyImageView extends ImageView {
- public MyImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MyImageView(Context context) {
- super(context);
- }@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- System.out.println("onMeasure 我被调用了" + System.currentTimeMillis());
- }@Override protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- System.out.println("onDraw 我被调用了" + System.currentTimeMillis());
- }
- }
布局文件:
测试的 Activity 的 onCreate():
- @Override public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("执行完毕.." + System.currentTimeMillis());
- }
现在我们现在来看一下结果:
vcHLyOfPwrDst6g6PC9wPg0KPHByZSBjbGFzcz0="brush:java;"> //------------------------------------------------ 方法一 int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); imageView.measure(w, h); int height =imageView.getMeasuredHeight(); int width =imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); //----------------------------------------------- 方法二 ViewTreeObserver vto = imageView.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {public boolean onPreDraw() {int height = imageView.getMeasuredHeight(); int width = imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); return true; } }); //----------------------------------------------- 方法三 ViewTreeObserver vto2 = imageView.getViewTreeObserver(); vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Override public void onGlobalLayout() {imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth()); } });
这三个方法是哪里找到现在已经忘了.
现在要讨论的是当我们需要时候使用哪个方法呢
现在把测试的 Activity 改成如下:
- @Override public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview); //------------------------------------------------方法一 int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); imageView.measure(w, h); int height =imageView.getMeasuredHeight(); int width =imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); System.out.println("执行完毕.."+System.currentTimeMillis()); }
接着来看下面几种方式输出结果:
把测试 Activity 改成如下:
- @Override public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview); -----------------------------------------------方法二ViewTreeObserver vto = imageView.getViewTreeObserver();
- vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- int height = imageView.getMeasuredHeight();
- int width = imageView.getMeasuredWidth();
- textView.append("\n" + height + "," + width);
- return true;
- }
- });
- }
结果如下:
方法三就不再测试了同方法二!!!
那么方法而和方法三在执行上有什么区别呢
我们在布局文件中加入一个 TextView 来记录这个控件的宽高.
先来测试方法而:
- @Override public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview); -----------------------------------------------方法二ViewTreeObserver vto = imageView.getViewTreeObserver();
- vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- int height = imageView.getMeasuredHeight();
- int width = imageView.getMeasuredWidth();
- textView.append("\n" + height + "," + width);
- return true;
- }
- });
- }
结果如下:
我们再来测试方法三
- @Override public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview); //-----------------------------------------------方法三 ViewTreeObserver vto2 = imageView.getViewTreeObserver(); vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth()); } }); }
输出结果如下:
我想这方法二和方法三之间的区别就不用说了吧.
总结: 那么需要获取控件的宽高该用那个方法呢
方法一: 比其他的两个方法多了一次计算, 也就是多调用了一次 onMeasure() 方法, 该方法虽然看上去简单, 但是如果要目标控件计算耗时比较大的话 (如 listView 等), 不建议使用.
方法二, 它的回调方法会调用很多次, 并且滑动 TextView 的时候任然会调用, 所以不建议使用.
方法三, 比较合适.
当然, 实际应用的时候需要根据实际情况而定.
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-12/18562182.html