Android 获取View的高度和宽度
来源:互联网 发布:磁力解析在线播放软件 编辑:程序博客网 时间:2024/05/17 04:48
View宽高值为什么是0
如果我们想获取View的高度和宽度,通过在onCreate()
或者onStart()
或者onResume()
等生命周期中直接获取,像下面这样处理会获取到View的高度吗?
package com.wjj.imagepull;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ScrollView;import android.widget.TextView;public class MainActivity extends Activity{ ScrollView scrollView; public static final String TAG = "VIEW_PARAM"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scrollView = (ScrollView) findViewById(R.id.scroll_view); getHeightAndWidth("onCreate()"); } private void getHeightAndWidth(String method) { int height = 0; int width = 0; if (scrollView != null) { height = scrollView.getHeight(); width = scrollView.getWidth(); } Log.i(MainActivity.TAG, method + " has been called: " + System.currentTimeMillis() + " height: " + height + " width: " + width); } @Override protected void onStart() { super.onStart(); getHeightAndWidth("onStart()"); } @Override protected void onResume() { super.onResume(); getHeightAndWidth("onResume()"); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}
接下来在自定义的组件PullScrollView
中适当的方法中加入一些测试log:
public class PullScrollView extends ScrollView{ View view; int sacTopMargin; float lastY; float offsetY; public PullScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i(MainActivity.TAG, "onMeasure() has been called: " + System.currentTimeMillis()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.i(MainActivity.TAG, "onDraw() has been called: " + System.currentTimeMillis()); } ...}
然后运行后看一下Log
通过上面的方法,显然不能获取到View的高度和宽度,关于为什么获取不到View的这些参数值,原因很简单,因为当前Activity中持有的WindowPhone实例还尚未将View添加到DecorView上来,所以无法获取View的高度和宽度,一般在onResume生命周期过后300ms左右时间才会将需要显示的View添加到DecorView上去,代码像下面这样处理:
如何获取View宽高值
@Overrideprotected void onResume(){ super.onResume(); getHeightAndWidth("onResume()"); scrollView.postDelayed(new Runnable() { @Override public void run() { getHeightAndWidth("onResume()_postDelayed()"); } }, 300);}
这样就获取了View的宽高值,当然这个方法不太保险,因为你不能确保在onResume之后300ms 就能将View添加到DecorView中去,那么保险的方式是什么呢?相信读过Android源代码的同学对ViewTreeObserver.OnGlobalLayoutListener
并不陌生,当一个view的布局加载完成或者布局发生改变时OnGlobalLayoutListener可以监听到,利用这点我们可以在布局加载完成的瞬间获得一个view的宽高。
public class PullScrollView extends ScrollView implements ViewTreeObserver.OnGlobalLayoutListener{ public PullScrollView(Context context, AttributeSet attrs) { super(context, attrs); ViewTreeObserver observer = getViewTreeObserver(); if (null != observer) observer.addOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); sacTopMargin = -params.topMargin; Log.d(MainActivity.TAG, "" + sacTopMargin); getViewTreeObserver() .removeGlobalOnLayoutListener(this); } ...}
OnGlobalLayoutListener的onGlobalLayout被回调之前是没有值的。由于布局状态可能会发生多次改变,因此OnGlobalLayoutListener的onGlobalLayout可能被回调多次,所以我们在 第一次获得值之后就将listener注销掉。
当然关于如何获取View的高度和宽度值,还有很多方法,这里仅仅测试了两种比较靠谱的方法,感兴趣的同学可以继续深究。
- Android 获取View的高度和宽度
- Android获取View的宽度和高度
- Android获取View的宽度和高度
- 如何获取view的宽度和高度
- 获取View的高度和宽度
- android 中 view 的宽度和高度
- android中获取view在布局中的高度和宽度
- android 获取字符串的高度和宽度
- Android 获取手机屏幕的宽度和高度
- Android 获取手机屏幕的宽度和高度
- android 获取字符串的高度和宽度
- android获取屏幕的高度和宽度
- Android 获取手机屏幕的宽度和高度
- Android 获取屏幕的宽度和高度
- android: 获取屏幕的宽度和高度
- Android获取屏幕的高度和宽度
- android获取屏幕的高度和宽度
- android获取屏幕的高度和宽度
- 电脑断网2个星期
- C++学习笔记一
- Android.mk的用法和基础学习-----阿冬专栏
- CSS多行文本固定高度的居中
- FaceBook/infer-不同构建系统的支持
- Android 获取View的高度和宽度
- [rqnoj145]打水漂
- Spring在web请求中定义编码(org.springframework.web.filter.CharacterEncodingFilter)
- 【iOS开发-网络】使用NSURLSessionDownloadTask断点下载
- Awesome配置
- 第一章policy(特征,模板中的模板类)
- pcl到vs2005移植
- OC—属性
- 对Guava Cache的封装和使用(包括一个管理页面实现了查看统计信息、情况、查看记录等)