Android扩展-怎么在Activity中拿到一个View的宽和高

今天来简单的介绍一下怎么在Activity中拿到View的width和height。有人可能会疑问,这个有什么难的,我们直接可以在Activity生命周期函数里面获取width和height。看似简单,实际上在onCreate、onStart、onResume中均无法获取正确的width和height,这是因为View的measure过程和Activity的生命周期方法不是同步的,因此无法保证Activity执行了onCreate、onStart、onResume时,某个View已经测量完毕,如果View还没有测量完毕的话,那么获得的宽和高就是0.那么有什么方法来正确的获取呢?

1.onWindowFoucusChanged

 1 public class MainActivity extends AppCompatActivity {
 2
 3     private Button mButton = null;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9
10         mButton = (Button) findViewById(R.id.id_button);
11
12     }
13
14     @Override
15     public void onWindowFocusChanged(boolean hasFocus) {
16         super.onWindowFocusChanged(hasFocus);
17         if (hasFocus) {
18             int width = mButton.getMeasuredWidth();
19             int height = mButton.getMeasuredHeight();
20             Log.i("main", "width = " + width + " height = " + height);
21         }
22     }
23 }

onWindowFocusChanged这个方法的定义是:View已经初始化完毕了,width和height已经准备好了,这个时候去获取width和height是没有问题的。需要注意的是:onWindowFocusChanged会调用多次,当Activity的窗口得到焦点和失去焦点时均会被调用一次。具体来说,当Activity继续执行和暂停执行时,onWindowFocusChanged均会被调用,如果频繁的进行onResume和onPause,那么onWindowFocusChanged也会被频繁的调用。

 2.view.post(Runnable)

 1 public class MainActivity extends AppCompatActivity {
 2
 3     private Button mButton = null;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9
10         mButton = (Button) findViewById(R.id.id_button);
11         mButton.post(new Runnable() {
12             @Override
13             public void run() {
14                 int width = mButton.getMeasuredWidth();
15                 int height = mButton.getMeasuredHeight();
16                 Log.i("main", "width = " + width + " height = " + height);
17             }
18         });
19     }
20
21 }

我们可以通过post方法将一个runnable对象投递到mButton的消息队列的尾部,然后等待Looper调用此runnable的时候,View已经初始化好了。

 3.ViewTreeObserver

 1 public class MainActivity extends AppCompatActivity {
 2
 3     private Button mButton = null;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9
10         mButton = (Button) findViewById(R.id.id_button);
11     }
12
13     @Override
14     protected void onStart() {
15         super.onStart();
16         ViewTreeObserver viewTreeObserver = mButton.getViewTreeObserver();
17         viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
18             @Override
19             public void onGlobalLayout() {
20                 mButton.getViewTreeObserver().removeOnGlobalLayoutListener(this);
21                 int width = mButton.getMeasuredWidth();
22                 int height = mButton.getMeasuredHeight();
23             }
24         });
25     }
26 }

使用ViewTreeObsrever的众多回调可以完成这个功能,比如使用OnGlobalLayoutListener这个接口,当View树的状态发生改变或者View内部的View的可见性发生改变时,onGlobalLayout方法将被回调,因此这是获取View的width和height一个很好的时机。需要注意的是,伴随着View树的状态改变等等,onGlobalLayout会被调用多次。

时间: 2024-10-20 17:27:35

Android扩展-怎么在Activity中拿到一个View的宽和高的相关文章

android开发之在activity中控制另一个activity的UI更新

转自:http://blog.csdn.net/jason0539/article/details/18075293 第一种方法: 遇到一个问题,需要在一个activity中控制另一个acitivity做一些更新,没想到传递handler的方法,通过以下方式解决. 1.在MyAPP中定义属性handler 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package jason.com;     import jas

【Android笔记】在一个Activity中结束另一个Activity

以在Activity_B中结束Activity_A为例: 1.在Activity_A中定义一个Acitivity的全局静态变量: 1 public static Activity actA; 2.在Activity_A的OnCreate()方法中给Activity_A赋值: 1 actA=this; 3.在Activity_B中,需要结束Activity_A时,调用以下: 1 ActivityA.actA.finish(); 另外也可用广播的方式实现(此处忽略了,需要的自己试下吧) 参考原文:h

【Android开发-8】生命周期,Activity中打开另外一个Activity

前言:生命中有许多人陪伴自己走过一生中的某段旅程,只是有些人只是某阶段出现,有些人却陪伴自己很久.就像小学.中学.高中.大学,那些曾经以为会长久拥有的,当经历过天涯各地地忙碌于生活,或如意,或失意:渐渐地那些画面只剩回忆.天涯各自安命,能在一起的就尽力珍惜吧,不在一起地就衷心地祝福,我们都需要一种姿态生活下去!Android中的Activity的生命中,我们经常需要打开另外一个Activity,即另外一个界面.这个可能出现的时间很短暂,然后又回到主界面.但是这两个Activity都在各自的生命周

Android开发常见的Activity中内存泄漏及解决办法

上一篇文章楼主提到由Context引发的内存泄漏,在这一篇文章里,我们来谈谈Android开发中常见的Activity内存泄漏及解决办法.本文将会以"为什么""怎么解决"的方式来介绍这几种内存泄漏. 在开篇之前,先来了解一下什么是内存泄漏. 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是值由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费. 怎

Android开发中在一个Activity中关闭另一个Activity

Android开发中在一个Activity中关闭另一个Activity 比如有ActivityA, ActivityB,在ActivityB中关闭ActivityA 解决方案: 1. 在 ActivityA 里面设置一个静态的变量instance,初始化为this在 ActivityB 里面, ActivityA.instance.finish(); 2. 也可以通过ActivityManager ActivityManager manager = (ActivityManager)getSys

Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?

在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ? @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); getViewSize("onCr

【转】Android 获得view的宽和高

转自:http://blog.csdn.net/yangdeli888/article/details/25405263 Android 获得view的宽和高 分类: android 技术点项目2014-05-09 16:15 6954人阅读 评论(3) 收藏 举报 在oncreate()中利用view.getWidth()或是view.getHeiht()来获取view的宽和高,看似没有问题,其实他们去得值是0,并不是你想要的结果? 这是为什么呢? 在调用oncreate()方法时,界面处于不

Android 获得view的宽和高

转自:http://blog.csdn.net/yangdeli888/article/details/25405263 在oncreate()中利用view.getWidth()或是view.getHeiht()来获取view的宽和高,看似没有问题,其实他们去得值是0,并不是你想要的结果? 这是为什么呢? 在调用oncreate()方法时,界面处于不可见状态,内存加载组件还没有绘制出来,你是无法获取他的尺寸. 那如何在绘制组件之前能获取到该组件的尺寸大小呢? 这里有三种方法,经过验证的: 方法

android小技巧:在activity中实现与绑定的fragment的回调

看到标题你可能会想是一个多么高大上的技巧呢?其实很一般就是自定义回调函数. 首先我们知道activity之间的数据传递有几种方式: 一是startActivityForResut()启动一个activity,当栈顶activity 调用onActivityResult()并且 finish 掉时将会传递消息给启动该activity的父activity. 二是在使用Fragment时,通过setTargetFragment()和onActivityResult()方法实现两个fragment之间的