Android获取控件宽高的几种方式

获取控件的宽高直接使用view的getWidth() 和 getHeight()方法获取。
但是直接在Activity的onCreate() 或 onResume()中获取的宽高为0。
原因是Activity的启动流程和布局文件的加载流程是2个异步的过程,在onCreate或onResume的时候控件还没有绘制完成,因此直接通过getWidth() 和 getHeight()获取的宽、高为0,下面给出几种方式来实现view宽高的获取。

定义获取宽高方法
/** * 以textView为例获取控件宽、高 */private void getTextWidthAndHeight() {int width = textView.getWidth();int height = textView.getHeight();Log.i(TAG,"width:" + width + ", height:" + height);}
第一种方式:在需要时获取,如控件点击时再获取
button.setOnClickListener(new View.OnClickListener() {     @Override     public void onClick(View v) {          getTextWidthAndHeight();          }});
第二种方式:重写onWindowFocusChanged()方法
@Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);if (hasFocus) {getTextWidthHeight();}}

需要注意的是,这个方法可能会执行多次,比如锁屏,切到后台等重新进入时都会执行该方法。

第三种方式:添加OnPreDrawListener事件监听
getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {    @Override    public boolean onPreDraw() {         getTextWidthHeight();         getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this);         return false;    }});
第四种方式:添加OnGlobalLayoutListener事件监听
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {      @Override      public void onGlobalLayout() {           getTextWidthHeight();           getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this);      }});
第五种方式:post Runnable方式
 textView.post(new Runnable() { @Overridepublic void run() { getTextWidthHeight(); } });

示例

public class GetViewHeightActivity extends AppCompatActivity {    private Button testView;    private TextView tvHeightWidthInfo;    private String info = "";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_get_view_height);        testView = findViewById(R.id.view_test);        tvHeightWidthInfo = findViewById(R.id.tv_height_width_info);        getHeightWidth("Default");        onPreView();        onGlobalLayout();        postRunnable();        //点击按钮的时候再获取        testView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                getHeightWidth("onClick");            }        });    }    /**     * 获取view宽高     */    private void getHeightWidth(String tag) {        int height = testView.getHeight();        int width = testView.getWidth();        info += tag + " width:" + width + ", height:" + height + "\n";        tvHeightWidthInfo.setText(info);    }    /**     *  重写onWindowFocusChanged()方法     * @param hasFocus 当前页面是否有焦点     */    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if (hasFocus) {            getHeightWidth("onWindowFocusChanged");        }    }    /**     * OnPreDrawListener事件监听     */    private void onPreView() {        getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {            @Override            public boolean onPreDraw() {                getHeightWidth("OnPreView");                getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this);                return false;            }        });    }    /**     * OnGlobalLayoutListener事件监听     * 最低支持Api 16     */    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)    private void onGlobalLayout() {        getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                getHeightWidth("OnGlobalLayout");                getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this);            }        });    }    /**     * post Runnable方式     */    private void postRunnable() {        tvHeightWidthInfo.post(new Runnable() {            @Override            public void run() {                getHeightWidth("PostRunnable");            }        });    }}
布局文件R.layout.activity_get_view_height
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="12dp"    tools:context=".GetViewHeightActivity">    <Button        android:id="@+id/view_test"        android:layout_width="match_parent"        android:layout_height="85dp"        android:text="test view"        app:layout_constraintTop_toTopOf="parent" />    <TextView        android:id="@+id/tv_height_width_info"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:textSize="16sp"        app:layout_constraintTop_toBottomOf="@+id/view_test" />androidx.constraintlayout.widget.ConstraintLayout>
结果截图

更多相关文章

  1. Activity的启动流程分析
  2. android内核编译方法[转贴]
  3. imageView中图片各种比例类型的显示方式的参数设置
  4. Android对话框Dialog,PopupWindow,Toast的实现机制
  5. Android的Touch事件处理和手势
  6. android发送模拟按键消息,出现死锁,timeout的解决方法
  7. android 的消息处理
  8. Android(安卓)SimpleAdapter源码详解
  9. Android(安卓)Gson

随机推荐

  1. SQL Server将一列的多行内容拼接成一行的
  2. sqlserver四舍五入使用round函数及cast和
  3. 数据库触发器DB2和SqlServer有哪些区别
  4. SQL获取第一条记录的方法(sqlserver、ora
  5. SqlServer异常处理常用步骤
  6. SQL语句执行顺序详解
  7. SQL SERVER 2014 安装图解教程(含SQL SERV
  8. SQLite之Autoincrement关键字(自动递增)
  9. master数据库损坏的解决办法有哪些
  10. 如何把sqlserver数据迁移到mysql数据库及