当前位置:首页 > 芯闻号 > 充电吧
[导读]1、public class View extends Objectimplements Drawable.Callback KeyEvent.Callback AccessibilityEvent

1、public class View extends Object
implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource java.lang.Object    ↳ android.view.View   Class Overview

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class forwidgets, which are used to create interactive UI components (buttons, text fields, etc.).

public abstract class   View是Android中所有控件的基类,Button/TextView/RelativeLayout/ListView等,其共同基类都是View。View是界面层的控件的一种抽象,待变一个控件。 ViewGroup extends View
implements ViewManager ViewParent


java.lang.Object    ↳ android.view.View      ↳ android.view.ViewGroup   Class Overview

A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers.

ViewGroup内部包含一组View,ViewGroup也继承自View,这就说明View本身就可以使单个控件或多个控件组成的一组控件。

UI界面架构图:


每个Activity都包含一个Window对象,Window对象通常由PhoneWindow来实现。PhoneWindow将一个DecorWindow设置为整个窗口的根View。DecView里有所有View的监听事件,通过WindowManagerService进行接收,并通过Activity对象回调相应的onClickListener。显示界面上,将屏幕分为两部分,分别为TitleView和ContentView。ContentView是一个ID为content的FrameLayout,布局文件activity_main.xml就是设置在这样一个FrameLayout中。

2、View的位置参数:

View根据上图得到View的宽高和坐标(相对于ViewGroup,而不是原点)的关系:

width = right - left;

height = bottom - top;

获取这几个参数的方法如下:

mLeft = getLeft();
mRight = getRight();
mTop = getTop();
mBottom = getBottpm();

Android3.0开始View增加了几个参数:x,y,translationX,translationY,其中x,y是View左上角的坐标,translationX,translationY是View左上角相对于父容器的偏移量:

x = left + translationX;

y = top + translationY;

需要注意:View在平移过程中,top/left表示的是原始左上角的位置信息,其值在移动期间不会发生改变,变化的是x,y,translationX,translationY.


3、View的三大流程(measure,layout,draw)之View的测量

View的绘制流程从ViewRoot的performTraversals方法开始,ViewRoot对应于ViewRootImpl类,是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成。在ActivityThread中,当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象与DecorView相关联:

root = new ViewRootImpl(view.getContext(),display);
root.setView(view,wparams,panelParentView);

View的绘制流程从ViewRoot的performTraversals方法开始,经过measure,layout,draw三个过程将一个View绘制出来。

performTraversals会依次调用performMeasure,performLayout,performDraw三个方法,分别完成顶级View的measure,layout,draw三大流程,其中performMeasure中会调用measure方法,在measure方法中又调用onMeasure方法,在inMeasure方法中会对所有子元素进行measure过程,此时measure流程就从父元素传到子元素了,这样完成了一次measure过程。接着子元素会重复父容器的measure过程,如此反复完成整个View树的遍历。performLayout与performDraw与之类似,不同的是performDraw的传递过程是在draw方法中通过dispatchDraw来实现。

测量过程在onMeasure()方法中进行。

Android提供了一个功能强大的类--MeasureSpec类。

public static class View.MeasureSpec extends Object
java.lang.Object    ↳ android.view.View.MeasureSpec Summary: Constants |Ctors | Methods | Inherited Methods | [Expand All] Added in API level 1


public static class View.MeasureSpec extends Object
java.lang.Object    ↳ android.view.View.MeasureSpec Class Overview

A MeasureSpec encapsulates the layout requirements passed from parent to child. Each MeasureSpec represents a requirement for either the width or the height. A MeasureSpec is comprised of a size and a mode. There are three possible modes:

UNSPECIFIED The parent has not imposed any constraint on the child. It can be whatever size it wants.EXACTLY The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.AT_MOST The child can be as large as it wants up to the specified size.


MeasureSpec是一个32位的int值,高2位为测量模式(SpecMode),低30位是测量大小(SpecSize).

View默认的onMeasure()方法只支持EXACTLY模式,因此如果让自定义View支持wrap_content属性,就必须重写onMeasure()方法来指定wrap_content大小(进一步说明,由源码得出,wrap_content下的SpecMode是AT_MOST,此时的specSize是parentSize,即如果不指定wrap_content,在布局中使用wrap_content就相当于使用match_parent).

解决方法:

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
	super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
	int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
	int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
	int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
	
	if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
		setMeasureDimension(mWidth,mHeight);
	}else if(widthSpecMode == MeasureSpec.AT_MOST){
		setMeasureDimension(mWidth,heightSpecSize);
	}else if(heightSpecMode == MeasureSpec.AT_MOST){
		setMeasureDimension(widthSoecSize,mHeight)
	}
}

在上面代码中指定View的默认宽高(mWidth/mHeight),并在wrap_content时设置此宽高。
Demo:

MeasureView.java


 

package sunny.example.ahthreeviewmeasure;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MeasureView extends View{

	public MeasureView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		 
	}
	
	public MeasureView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}
	
	public MeasureView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
		
		if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
			setMeasuredDimension(400,400);//指定宽高
		}else if(widthSpecMode == MeasureSpec.AT_MOST){
			setMeasuredDimension(400,heightSpecSize);
		}else if(heightSpecMode == MeasureSpec.AT_MOST){
			setMeasuredDimension(widthSpecSize,400);
		}
	}

	

}

 

activity_main.xml



MainActivity.java

 

package sunny.example.ahthreeviewmeasure;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//MeasureView mView = (MeasureView)findViewById(R.id.measureView);
	}

	
}

 

 

 

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

涡轮流量计是一种广泛用于测量液体和气体流量的仪器,它基于涡轮叶片的旋转来测量流体的速度并计算出流量。这种类型的流量计在工业、化工、石油、天然气、水处理和许多其他领域都得到了广泛的应用。然而,要确保涡轮流量计的准确性和可靠...

关键字: 涡轮流量计 涡轮叶片 测量

液位变送器是一种常见的工业自动化装置,用于测量液体高度或容器中的液体体积。它广泛应用于石油化工、食品加工、水处理等领域,在生产过程中起到重要的监测和控制作用。本文将介绍液位变送器的基本原理、应用设计步骤以及注意事项,帮助...

关键字: 液位变送器 工业自动化 测量

虚拟仪器技术是一种基于计算机和软件的测量与控制技术,它利用计算机软硬件平台,替代传统仪器设备,实现了仪器的虚拟化和软件化。通过虚拟仪器技术,我们可以设计出高灵活性、可扩展性和集成性的测量系统。以下是一些采用虚拟仪器技术实...

关键字: 虚拟仪器 测量 计算机

光纤光栅传感器是利用光纤中的光敏性制成的。所谓光纤中的光敏性是指激光通过掺杂光纤时,光纤的折射率将随光强的空间分布发生相应变化的特性。而在纤芯内形成的空间相位光栅,其实质就是在纤芯内形成一个窄带的(透射或反射)滤波器或反...

关键字: 光栅 传感器 测量

压力传感器主要的作用就是用来检测和控制,这种设备可以进行直接的压力测量同时也可以通过传感器的使用来对其他数值进行间接的测量。像是液体和气体以及速度还有水位的高度都是可以通过压力传感器来得到准确的数值。所以说,压力传感器的...

关键字: 压力传感器 控制 测量

使用压力传感器,可以进行压力测量以确定一系列不同值和不同类型的压力,具体取决于压力测量是相对于大气、真空条件还是其他压力参考水平进行的。压力传感器是可以设计和配置为检测这些变量的压力的仪器。

关键字: 压力传感器 测量 传感技术

摘要:多参数监护仪主要用于监测危重患者的生命体征参数,其监护参数一般包括心电、无创血压、血氧饱和度三个部分,有些监护仪还包括对呼末二氧化碳等人体生理参数的监护功能。多参数监护仪由三部分构成,即信号采集、信号处理和信号显示...

关键字: 多参数监护仪 不确定度 测量

去年,全球温度传感器市场规模超过70亿美元。如今疫情的突发是否是温度传感器市场爆发的一个契机?据Global Market Insights近日数据显示,2019年全球温度传感器市场规模超过70亿美元,估计从2020年至...

关键字: 传感器 市场 测量

本文中,小编将对压力传感器予以介绍,如果你想对压力传感器的详细情况有所认识,或者想要增进对它的了解程度,不妨请看以下内容哦。

关键字: 传感器 压力传感器 测量

以直流电压1V为例,4位半的万用表Fluke 15B+/17B+/18B+的精度是一致的,都是0.5%+3,分辨率为0.001V,偏差△V=1V*0.5%+3*0.001V=8mV,因此万用表直流电压1V测量显示: 0....

关键字: 直流电压 万用表 测量
关闭
关闭