一、设置控件宽高

设置Layout_width/height引发的宽高思考

方式一:




结果不符合预期。

运行结果:



方式二:



结果符合预期。

如下图:



Android控件宽高的规则

Android下的控件默认没有宽高,是由父控件给其宽高的。

其中一般的view控件是由(ViewGroup控件:LinearLayout、RelativeLayout 、TableLayout、FrameLayout 、AbsoluteLayou )五大布局给其宽高的。

而像LinearLayout、RelativeLayout等这些最外层的布局控件的宽高是由Android系统的FrameLayout控件设定的。可用android-sdk/tools下的工具hierarchyviewer.bat查看,如下图:


针对方式一的修改方案,如下代码:



运行结果如下:



二、Activity中获取控件的宽高

程序启动时想要获取特定视图组件的尺寸大小,在onCreate中可能无法取到,因为窗口Window对象还没创建完成,还没有执行onMeasure 和 onLayout方法,所以,此时getWidth返回值是0。那么如何或者说何时才能获取控件的大小呢?


方案1:在oncreate方法中, 发一个延迟消息,在handleMesaage中获取控件宽高。原理就是延时一段时间,等待控件测量、布局完成后再获取。(虽然有用但不优雅)

   Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case GET_SIZE:                    int width = listView.getWidth();                    break;            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_conversation_ui);        handler.sendEmptyMessageDelayed(GET_SIZE, 500);    }

方案2:获得全局viewTree的观察者,并添加全局的layout监听。原理就是监听onlayout方法执行完成之后,就可以获取控件大小了。

// 获得全局viewTree的观察者,并添加 全局的layout监听imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.    OnGlobalLayoutListener() {    @Override    public void onGlobalLayout() {      //由于此方法会执行多次,而我们只需要执行一次就可以了,      //所以,在执行一次的时候,将全局的layout监听取消,此处this指的是,内部的匿名对象      imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);      int width = imageView.getWidth();    }});


方案3:主动通知系统去测量,调用measure(0,0)方法 。再用getMeasureWidth就可以得到测量的结果了。

imageView.measure(0, 0);// 主动通知系统去测量LogUtils.d("========== imageView getMeasuredWidth: "+imageView.getMeasuredWidth());


方案4:重写Activity的onWindowFocusChanged方法。

在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前Activity。以上几种情况都会调用onWindowFocusChanged。

@Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        LogUtils.d("========== imageView getWidth: " + imageView.getWidth());    }


三、getWidth()与getMeasuredWidth()的区别

从上面代码可以看到,获取控件的宽高有时用getWidth()方法,有时用getMeasuredWidth()方法,这两个方法有什么区别呢?

getWidth()方法源码:

    /**     * Return the width of the your view.     *     * @return The width of your view, in pixels.     */    @ViewDebug.ExportedProperty(category = "layout")    public final int getWidth() {        return mRight - mLeft;    }

从源码可以看出,getwidth返回的是右边坐标减去左边坐标(也就是控件右边距屏幕Y轴的距离减去控件左边距屏幕Y轴的距离),这要在布局之后(也就是onLayout()方法执行完之后)才能确定它们的坐标。在布局后(也就是onLayout()方法执行完之后)才能调用getwidth来获取。

总结:getWidth()获得的宽度是View在设定好布局后整个View的宽度。 这个宽度是指在容器ViewGroup中,该view的宽度,可称为:布局宽度。


getMeasuredWidth()方法源码:

    /**     * Like {@link #getMeasuredWidthAndState()}, but only returns the     * raw width component (that is the result is masked by     * {@link #MEASURED_SIZE_MASK}).     *     * @return The raw measured width of this view.     */    public final int getMeasuredWidth() {        return mMeasuredWidth & MEASURED_SIZE_MASK;    }

注释:return The raw measured width of this view 获得的是原始的测量宽度。onMeasure()方法执行完之后就可以调用该方法获取。

总结:getMeasuredWidth()是对View上的内容进行测量后得到的View内容占据的宽度。这个宽度是根据view中的内容决定。可称为:组件宽度

当然要得到View内容占据的宽度,前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);(measure中的参数的值你自己可以定义),否则你得到的结果和getWidth()得到的结果是一样的。

比如你定义一个组件的宽50、高50;但是你在布局文件中,硬是要把layout_width指定为match_parent(假设只有一个组件),那这个组件的宽度就被拉到全屏了。这时候getWidth()得到的就是布局宽度。如果要想得到原始宽度,必须调用该组件的measure(0,0)方法重新测量 。再用getMeasureWidth就可以得到了。


两者的使用场合:

getMeasuredWidth:在自定义view重写onLayout时、在我们用layoutinflater动态加载view后想获得view的原始宽度时。

getWidth:一般在view已经布局后呈现出来了,想获取宽度时


四、layout_grivaty与grivaty


layout_grivaty使用时的注意点:


结果如下图:




结果如下图:



区别:




更多相关文章

  1. Android(安卓)Handler 机制
  2. Flutter 与 Android(安卓)的交互
  3. Android(安卓)Studio—— 关于在Android(安卓)Studio中使用Asset
  4. [置顶] 【Android归纳决】Asynctask与Handler异步综述
  5. Android(安卓)网络处理
  6. Android(安卓)中 startService()启动service的过程分析
  7. 说说 Android(安卓)的内容提供器(ContentResolver )
  8. android LinearLayout等view如何获取button效果
  9. Android(安卓)Tab切换之Fragment方法

随机推荐

  1. android 自定义View 滚动选择器PickerVie
  2. android左右滑动翻页查看图片
  3. Android读写文件示例
  4. android custom viewgroups 性能分析
  5. Android(安卓)valueAnimator和ObjectAnim
  6. Android中Broadcast的Intent大全
  7. Android涂鸦
  8. Android创建文件夹及文件并写入数据
  9. Android(安卓)studio 点击跳转WedView
  10. android SQLite的CRUD