zoukankan      html  css  js  c++  java
  • 视图View,获取视图大小

    一、获得LayoutInflater实例:

    LayoutInflater layoutInflater=LayoutInflater.from(context);

    得到LayoutInflater实例之后,就可以调用他的inflate()方法来加载布局:

    layoutInflater.inflate(resourceId,root);

    inflate方法一边拿有两个参数,第一个参数就是要加载的布局id,第二个参数是指给该布局的外部再嵌套一层父布局,如果不需要就直接传null。这样就成功创建了一个布局的实例,之后将他添加到指定的位置就可以显示出来。

    Android中的任何一个布局、任一个控件都是直接或间接继承自View,如TextView、Button、ImageView、ListView等。

    每一个视图的绘制过程都必须经过三个最主要的阶段:onMeasure()、onLayout()和onDraw()

    一、onMeasure()

    View系统的绘制流程会从ViewRoot的performTraversals()方法中开始,在其内部调用View的measure()方法。measure方法接收两个参数,widthMeasureSpec和heightMeasureSpec,这两个值分别用于确定视图的宽度和高度的规格和大小。

    MeasureSpec的值由specMode和specSize共同组成,其中specSize记录的是大小,specMode记录的是规格。specMode一共有三种类型,如下:

    1.EXACTLY

    表示俯视图喜旺子视图的大小应该是有specSize的值来决定的,系统默认会按照这个规则来设置子视图的大小,开发人员当然可以按照自己的沂源设置成任意大小。

    2.AT_MOST

    表示姿势图最多只可能是specSize中指定的大小

    3.UNSPECIFIED

    表示开发人员可以将视图按照自己的意愿设置成任意大小,没有任何限制,这种情况不太会用到

    childWidthMeasureSpec=getRootMeasureSpec(desirWindowWidth,lp.width);

    childHeigthMeasureSpec=getRootMeasureSpec(desirWindowHeigth,lp.height);

    可以看到,这里调用了getRootMeasureSpec()方法去获取widthMeasureSpec和heightMeasureSpec的值,注意方法中传入的参数,其中lp.width和lp.height在创建ViewGroup实例时就被赋值了,他们都等于MATCH_PARENT,然后看下getRootMeasureSpec()方法中的代码:

    private int getRootMeasure(int windowSize,int rootDimension){

    int measureSpec;

    switch(rootDimension){

    case  ViewGroup.LayoutParams.MATCH_PARENT:

    measureSpec=MeasureSpec.makeMeasureSpec(WindowSize,MeasureSpec.EXACTLY);

    break;

    case  ViewGroup.LayoutParams.WRAP_CONTENT:

    measureSpec=Measure.makeMeasureSpec(windowSize,MeasureSpec.AT_MOST);

    break;

    default:

    measureSpec=MeasureSpec.makeMeasureSpec(rootDimension,MeasureSpec.EXACTLY);

    break;

    }

    return measureSpec;

    }

    可以看到,这里使用了MeasureSpec.makeMeasureSpec()方法来组装一个MeasureSpec,当rootDimension参数等于MATCH_PARENT的时候,MeasureSpec的specMode就等于EXACTLY,当rootDimension等于WRAP_CONTENT的时候,MeasureSpec的specMode就等于AT_MOST。并且MATCH_PARENT和WRAP_CONTENT时的specSize都是等于windowSize的,也就意味着根视图总是会充满全屏的。

    下面是View的measure()方法代码:

    public final void measure(int widthMeasureSpec, int heightMeasureSpec) {  

        if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT ||  

                widthMeasureSpec != mOldWidthMeasureSpec ||  

                heightMeasureSpec != mOldHeightMeasureSpec) {  

            mPrivateFlags &= ~MEASURED_DIMENSION_SET; 

       if (ViewDebug.TRACE_HIERARCHY) {  

                ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE);  

            }  

            onMeasure(widthMeasureSpec, heightMeasureSpec);  if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) {  

    throw new IllegalStateException("onMeasure() did not set the"  

                       + " measured dimension by calling"  

                        + " setMeasuredDimension()");  

            }  

            mPrivateFlags |= LAYOUT_REQUIRED;  

        }  

        mOldWidthMeasureSpec = widthMeasureSpec;  

        mOldHeightMeasureSpec = heightMeasureSpec;  

    }  

     未完待续

    二、获取视图大小

    获取视图大小应该在试图加载完成后在获取。

    用View的post方法来获取,该方法接受一个Runnable线性参数,并将其添加到消息队列中(Runnable线程会在UI线程中执行。)

    View view;

    view=findViewById(R.id.dtext);
    view.post(new Runnable(){

    @Override
    public void run() {
    System.out.println("view has "+view.getWidth()+"and height:"+view.getHeight());

    }

    });

  • 相关阅读:
    Android数据存储之Application
    contentOffset、contentSize和contentInset
    block
    IOS中的深拷贝和浅拷贝
    手势图的设计原理(2)拖拽、捏合、轻扫、旋转
    深浅拷贝的应用-copy、mutableCopy
    手势图的设计原理(1)建立、开始、移动、结束、点击、长按
    UIView
    MVC-Model
    UIPageControl页面控制的控件
  • 原文地址:https://www.cnblogs.com/chhom/p/5235690.html
Copyright © 2011-2022 走看看