ca88编程Android控件布局与控件绘制

作者:ca88编程

剧情是博主照着书敲出来的,博主码字挺费力的,转发请表明出处,后序内容时断时续会码出。

上一篇自定义View(Android群英传卡塔尔中说的是创设复合控件,那篇介绍第三种自定义View方法,重写View来得以达成全新的控件

引用UI模板

最后一步,自然是在须求使用的地点援引UI模板,在援用前,供给钦定援引第三方控件的名字空间。在构造文件中,能够观察如下一行代码。

xmlns:android="http://schemas.android.com/apk/res/android"

那行代码正是在钦点引用的名字空间xmlns,即xml namespace。这里钦点了名字空间为“android”,因而在接下去使用系统质量时,才方可运用“android:”来援用Android的系统品质。同样,假若要运用自定义属性,那么就供给创立自个儿的名字空间,在Android Stuido中,第三方控件都使用如下代码来援用名字空间。

xmlns:app="http://schemas.android.com/apk/res/res-auto"

那边大家将引进的第三方控件的名字空间取名叫app,之后在XML文件中使用自定义的性能时,就足以经过那个名字空间来引用,代码如下所示。

<com.example.demo.TopBar
        android:id="@ id/tb"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        app:leftBackGround="#ff000000"
        app:leftText="Back"
        app:leftTextColor="#ffff6734"
        app:leftTextSize="25dp" 
        app:rightText="More"
        app:rightTextSize="25dp"
        app:rightTextColor="#ff123456"
        app:title="自定义标题"
        app:titleTextColor="#ff654321"/>

接受自定义的View与系统原生的View最大的区分就是在声明控件时,要求钦赐完整的包名,而在引用自定义的属性时,要求利用自定义的xmlns名字。

剧情是博主照着书敲出来的,博主码字挺勤奋的,转发请注脚出处,后序内容时有时无会码出。

Android给大家提供了丰盛的构件库来创立丰盛的UI效果,相同的时候也提供了老大方便的开展方法。通过世襲Android的系统组件,大家得以特别便于地扩充现存作用,在系统组件的底工上创立新的作用,以至足以平素自定义三个控件,达成Android系统控件所未曾的效率。自定义控件作为Android中叁个可怜主要的职能,长期以来都被初读书人以为是表示高手的象征。其实,自定义View并从未想像中的那么难,与其说是在自定义一个View,不及说是在设计一个图片,唯有站在一个设计者的角度上,才足以更加好地开创自定义View。我们无法机械地记得全体绘图的API,而是要让那些API为您所用,结合具体中绘制的不二秘技,以至是PhotoShop的手艺,能力设计出更加好的自定义View。

适度地行使自定义View,能够加上应用程序的经验效果,但滥用自定义View则会带来多此一举的效率。二个让客户以为纯熟得控件,才是四个好的控件。要是始终追求炫彩的效能而创制自定义View,则会让客户以为硕华而不实。何况,在系统原生控件能够兑现效果与利益的底工上,系统也提供了核心、图片能源、各个风格来创制丰裕的UI。那几个控件都以通过了Android一代代版本迭代后的成品。纵然如此,在几最近的版本中,如故存在比很多Bug,更不要提大家自定义的View了。特别是现行Android ROM的两种性,引致Android的适配变得进一层复杂,很难保证自定义View在别的手提式有线电话机上也能达到规定的标准你想要的效能。

当然,了解Android系统自定义View的经过,可以补助大家询问系统的绘图机智。同有的时候间,在适用的场地下也得以通过自定义View来救助大家成立更佳灵活的构造。

在自定义View时,大家常常会去重写onDraw(卡塔尔国方法来挥着View的彰显内容。要是该View还索要利用wrap_content属性,那么还非得写onMeasure(卡塔尔国方法。此外,通过自定义attrs属性,还足以设置新的性质配置值。

在View中不足为怪有以下一些拾分首要的回调方法。

  • onFinishInflate(卡塔尔国:从XML加载组件后回调。
  • onSizeChanged(卡塔尔:组件大小更动时回调。
  • onMeasure(卡塔尔国:回调该办法来举办度量。
  • onLayout(卡塔尔(قطر‎:回调该办法来分明突显之处。
  • onTouchEvent(State of Qatar:监听到触摸事件时回调。

当然,创设自定义View的时候,并无需重写全数的不二秘技,只须要重写特定条件的回调方法就能够。那也是Android控件结构灵活性的呈现。 平时意况下,有以下二种办法来实现自定义的控件。

  • 对现存控件举办进行
  • 通过结合来贯彻新的控件
  • 重写View来达成全新的控件

ViewGroup的测量

在日前的深入剖判中说了,ViewGroup会去管理其子View,在那之中一个管理项目正是背负子View的显得大小。当ViewGroup的深浅为wrap_content时,ViewGroup就须求对子View实行遍历,以便获得全部子View的分寸,从而来设定自身的尺寸。而在任何形式下则会透过具体的内定值来设置自己大小。
ViewGroup在衡量时经过遍历全体子View,进而调用子View的Measure方法来博取每二个子View的衡量结果。当子View衡量实现后,就要求将子View放到十分之处,这么些进度就是View的Layout进程。ViewGroup在推行Layout进程时,同样是利用遍历来调用子View的Layout方法,并点名其实际展现之处,进而来调控其构造地点。
在自定义ViewGroup时,常常会去重写onLayout(State of Qatar方法来调节其子View呈现地点的逻辑。一样,假诺急需协助wrap_content属性,那么它还非得重写onMeasure(卡塔尔方法,那点与View是平等的。

重写View来兑现全新的控件

当Android系统原生的控件不能满意大家的急需时,我们就足以完全创造三个新的自定义View来得以达成内需的意义。创立三个自定义View,难题在于绘制控件和促成相互作用,这也是评价叁个自定义View优劣的专门的工作之一。平日需求继续View类,一视同仁写它的onDraw(卡塔尔(قطر‎、onMeasure(卡塔尔国等艺术来贯彻绘制逻辑,同不日常间经过重写onTouchEvent(卡塔尔等触控事件来完毕相互作用逻辑。当然,我们还足以像完成组合控件格局那样,通过引进自定义属性,丰裕自定义View的可定制性。 上面就因此多少个实例,让大家探听怎么创设三个自定义View,不过为了让程序尽恐怕轻巧,大家就不去自定义属性值了。

在PPT的洋洋模板中,皆犹如下图所示的这么一张比例图。

ca88编程 1比例图 那几个比重图能够充裕领悟地出示三个品种所占的比重,简单介绍明了。由此,完结如此二个自定义View用在大家的程序中,可以让任何程序完毕比较清晰地数量展现效果。那么该怎么创设三个如此的自定义View呢?很明朗,这些自定义View其实分为三个部分,分别是个中的圆形、中间呈现的文字和外侧的弧线。既然有了那般的思路,只要在onDraw(卡塔尔国方法中二个个去绘制就可以了。这里为了轻松,大家把View的绘图长度直接设置为显示器的小幅度。首先,在初叶化的时候,设置好绘制三种图形的参数。圆的代码如下所示。

mCircleXY = length / 2;mRadius =  (length * 0.5 / 2);

制图弧线,供给钦点其椭圆的外接矩形,代码如下所示。

mArcRectF = new RectF (length * 0.1),  (length * 0.1),  (length * 0.9),  (length * 0.9));

绘图文字,只要求安装好文字的开首绘制地方即可。 接下来,大家就能够在onDraw(卡塔尔方法中开展绘图了,代码如下所示。

// 绘制圆canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);// 绘制弧线canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint);// 绘制文字canvas.drawText(mShowText, 0, mShowText.length(), mCircleXY, mCircleXY   mShowTextSize / 4, mTextPaint);

言听计从这一个图片就算单独让您去绘制,应该是特别轻易的事体,只是这里实行了须臾间重新整合,就创造了三个新的View。其实,无论是何其繁琐的图纸、控件,它都以由那么些最大旨的图形绘制出来的,关键就在于你怎么样去解释、设计这几个图片,当您脑海中有了一幅设计图之后,剩下的政工就只是对坐标的总计了。 当然,对于这几个简单的View,有点方法能够让调用者来设置不一样的动静值,代码如下所示。

public void setSweepValue(float sweepValue) { if (sweepValue != 0) { mSweepValue = sweepValue; } else { mSweepValue = 25; } this.invalidate();}

譬喻,当客户不点名具体的比例值时,能够默许设置为25,而调用者能够通过如下代码来安装相应的比例值。

CircleProgressView circle = (CircleProgressView) findViewById(R.id.circle);circle.setSweepValue;

以下那个标题来自群里一个人开采者的标题,他想实现相近在PC上好几音乐播放器上根据音频音量大小显示音频条形图,如下图所示。

ca88编程 2节奏条形图 要是要促成叁个之类图所示的静态音频条,相信大家能够急速找到思路,也便是绘制二个个矩形,每一种矩形之间稍微偏移一点离开就能够。ca88编程 3静态音频条形图 如下代码就显示了一种总计坐标的措施。

@Overrideprotected void onDraw(Canvas canvas) { super.onDraw; for (int i = 0; i < mRectCount;   i) { canvas.drawRect(mRectWidth * i   offset, currentHeight, mRectWidth * , mRectHeight, mPaint); }}

如上代码中,大家透过轮回创立那几个小的矩形,此中currnetHeight正是各样小矩形的高,通过横坐标的无休止偏移,就绘制出了那些静态的小矩形。上面大家再让这几个小矩形的可观实行任性生成,通过Math.random(卡塔尔国方法来随意改造那个高度值,并赋值给currentHeight,代码如下所示。

mRandom = Math.random();float currentHeight =  (mRectHeight * mRandom);

这么,咱们就到位了静态效果的绘图,那么哪些兑现动态效果呢?其实极度轻巧,只要在onDraw(卡塔尔(قطر‎方法中再去调用invalidete()方法公告View举办重绘就足以了。可是,在这处没有须要每一回一绘制完新的矩形就通报View举行重绘,那样会因为刷新速度太快反而影响效果。由此,我们得以动用如下代码实行View的延期重绘,代码如下所示。

postInvalidateDelayed;

那样每间隔300ms布告View实行重绘,就足以拿走一个比较好的视觉效果了。最终,为了让自定义View尤其逼真,能够在绘制小矩形的时候,给绘制的Paint对象扩充三个LinearGradient渐变效果,那样分裂中度的矩形就能够有差异颜色的渐变效果,特别能够模拟音频条形图的品格,代码如下所示。

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getWidth(); mRectHeight = getHeight(); mRectWidth = mWidth / mRectCount; mLinearGradient = new LinearGradient(0, 0, mRectWidth, mRectHeight, Color.YELLOW, Color.GREEN, Shader.TileMode.CLAMP); mPaint.setShader(mLinearGradient);}

从这一个例子中,大家得以知晓,在开立自定义View的时候,须要一步步来,从二个着力的效果伊始,稳步地充时效果,绘制更目迷五色的效应。无论是多么复杂的自定义View,它分明是稳步迭代起来的意义,所以不要以为自定义View有多难。千里之行始于足下,只要开首做,稳步地就能够更熟悉。项目地址→RewriteView

原稿地址自定义View(Android群英传卡塔尔(قطر‎我的自媒体博客blankj小站(OJ、LeetCode、Android开辟State of Qatar,接待来逛逛。

创设复合控件

开创复合控件能够很好地创建出具体重用功效的控件集合。这种方式通常须要三番三遍三个适度的ViewGroup,再给它丰裕钦定效用的控件,进而组合成新的复合控件。通过这种措施开创的控件,大家日常会给它钦赐一些可配置的品质,让它抱有越来越强的拓宽性。
下边就以叁个通用的TopBar为示范,实行解说怎样创立复合控件。效果如下所示。

ca88编程 4

复合控件TopBar

率先新建一个TopBar类世袭RelativeLayout。

public class TopBar extends RelativeLayout {

    public TopBar(Context context) {
        this.TopBar(context, null);
    }

    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 初始化的方法
        // 初始化属性
        initAttr(context, attrs)
        // 初始化布局
        initView(context);
        // 初如化事件
        initEvent();
    }

}

对现成控件进行举办

那是三个不行首要的自定义View方法,它能够在原生控件的功底上举行扩充,扩展新的效果与利益、改善呈现的UI等。日常的话,我们得以再原生控件的根基上海展览中心开进行,扩展新的机能、校订展现的UI等。日常的话,我们能够在onDraw(卡塔尔方法中对原生控件行为举办扩充。

上边以二个TextView为例,来寻访哪些选拔实行原生控件的艺术创设新的控件。譬喻想让多个TextView的背景更佳足够,给其多绘制几层背景,如下图所示。

ca88编程 5自定义改过TextView

大家先来解析一下如何兑现这么些成效,原生的TextView使用onDraw(卡塔尔方法绘制要展现的文字。当世襲了系统的TextView之后,要是不重写其onDraw(State of Qatar方法,则不会纠正TextView的别样效果。能够以为在自定义的TextView中调用TextView类的onDraw(卡塔尔(قطر‎方法来绘制显示的文字,代码如下所示。

@Overrideprotected void onDraw(Canvas canvas) { super.onDraw;}

前后相继调用super.onDraw方法来促成原生控件的效能,然则在采纳super.onDraw(卡塔尔(قطر‎方法从前和之后,大家都足以达成和谐的逻辑,分别在系统绘制文字前后,完成本人的操作,即如下所示。

@Overrideprotected void onDraw(Canvas canvas) { //在调父类方法前,实现自己的逻辑,对TextView来说即是在绘制文本内容前 super.onDraw; //在调父类方法后,实现自己的逻辑,对TextView来说即是在绘制文本内容后}

如上正是通过修正控件的绘图行为创设自定义View的思路。有了上边的深入分析,大家就足以很自在地促成上海教室所示的自定义TextView了。我们在构造方法中成就需要对象的初叶化工作,如开头化画笔等,代码如下所示。

mPaint1 = new Paint();mPaint1.setColor(Color.BLUE);mPaint1.setStyle(Paint.Style.FILL);mPaint2 = new Paint();mPaint2.setColor(Color.YELLOW);mPaint2.setStyle(Paint.Style.FILL);

而代码中最要紧的有些则是在onDraw(卡塔尔(قطر‎方法中,为了改换原生的绘图行为,在系统调用super.onDraw方法前,也正是在绘制文字早先,绘制多少个不相同大小的矩形,产生二个重合效果,再让系统调用super.onDraw方法,实施绘制文字的干活。那样,我们就通过改换控件绘制行为,创立了二个新的控件,代码如下所示。

//绘制外层矩形canvas.drawRect( 0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint1);//绘制内层矩形canvas.drawRect( 10, 10, getMeasuredWidth() - 10, getMeasuredHeight() - 10, mPaint2);canvas.save();//绘制文字前平移10像素canvas.translate;//父类完成的方法,即绘制文本super.onDraw;canvas.restore();

下边再来看一个有些复杂一点的TextView。在头里多个实例中,我们一向动用了Canvas对象来实行图像的绘图,然后使用Android的绘图机制,能够绘制出更头眼昏花丰富的图像。比方能够动用LinearGradient Shader 和Matrix来促成二个动态的文字闪动作效果果,程序运转作效果果如下图所示。

ca88编程 6眨眼的文字效果

要想达成那一个效应,能够足够利用Android中Paint对象的Shader渲染器。通过安装三个穿梭改动的LinearGradient,并接纳含有该属性的Paint对象来绘制要来得的文字。首先,在onSizeChanged(卡塔尔国方法中进行部分对象的起头化职业,并依附View的增长幅度设置一个LinearGradient渐变渲染器,代码如下所示。

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (mViewWidth == 0) { mViewWidth = getMeasuredWidth(); if (mViewWidth > 0) { mPaint = getPaint(); mLinearGradient = new LinearGradient( 0, 0, mViewWidth, 0, new int[]{ Color.BLUE, 0xffffff, Color.BLUE }, null, Shader.TileMode.CLAMP); mPaint.setShader(mLinearGradient); mGradientMatrix = new Matrix(); } }}

里面最关键的正是行使getPaint(State of Qatar方法赢妥善前绘制TextView的Paint对象,并给这么些Paint对象设置原生TextView未有的LinearGradient属性。最终,在onDraw(卡塔尔(قطر‎方法中,通过矩形的措施来持续运动渐变效果,进而在绘制文字时,发生动态的闪动作效果果,代码如下所示。

@Overrideprotected void onDraw(Canvas canvas) { super.onDraw; if (mGradientMatrix != null) { mTranslate  = mViewWidth / 5; if (mTranslate > 2 * mViewWidth) { mTranslate = -mViewWidth; } mGradientMatrix.setTranslate(mTranslate, 0); mLinearGradient.setLocalMatrix(mGradientMatrix); postInvalidateDelayed; }}

原稿地址自定义View(Android群英传State of Qatar作者的自媒体博客blankj小站,应接来逛逛。

View的测量

Android系统在绘制View前,也必须要对View实行度量,告诉系统该画三个多大的View。这几个历程在onMeasure(卡塔尔(قطر‎方法中实行。
Android系统提供了二个类——MeasureSpec类,通过它来赞助我们度量View。MeasureSpec是多少个三拾一个人的int值,个中高2位为度量方式,低三十二个人为度量的分寸。

衡量方式可认为以下二种:

  • EXACTLY

    即规范方式,将控件的layout_width属性或layout_height属性钦点为现实数值时,比方android:layout_width

    "100dp",也许钦赐为match_parent属性时(占领父View的大大小小),系统使用EXACTLY形式。
  • AT_MOST
    即最大值情势,当控件的layout_width属性或layout_height属性钦定为wrap_content时,控件大小相像随着控件的子控件或内容的转移而生成,那时候间调控件的尺寸只要不当先父控件同意的最大尺寸就可以。
  • UNSPECIFIED
    其一性格比较古怪——它不点名其尺寸度量格局,View想多大就多大,平日状态下在绘制自定义View时才会采用。

通过MeasureSpec那贰个类,我们就取得了View的度量形式和View想要绘制的深浅。有了那几个消息,大家就能够决定View最终展现的高低。

实例:重写onMeasure()方法

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

在IDE中按住Ctrl键查看super.onMeasure(卡塔尔方法,能够窥见,系统末段会调用setMeasuredDimension(int widthMeasureSpec, int widthMeasureSpecState of Qatar方法将度量后的宽高值设置进去,进而成就度量职业。所以重写onMeasure(卡塔尔国方法后,最后要做的就是把衡量后的宽高值作为参数设置给setMeasuredDimension(State of Qatar方法。
通过上边的剖析,重写的onMeasure(State of Qatar方法代码如下:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(
            measureWidth(widthMeasureSpec),
            measureHeight(heightMeasureSpec));
}

在onMeasure(卡塔尔方法中,大家调用自定义的measureWidth(卡塔尔(قطر‎方法和measureHeight(卡塔尔方法分别对宽高重新定义,参数则是宽和高的MeasureSpec对象,MeasureSpec对象中隐含了衡量方式和衡量值的朗朗上口。

  • 第一步,从MeasureSpec对象中领抽出切实可行的衡量方式和尺寸,代码如下:
int specMode = MeasureSpec.getMode(measureSpec);  // 取出测量模式
int specSize = MeasureSpec.getSize(measureSpec);  // 取出测量大小
  • 第二步通过判断衡量形式,给出差别的度量值。
    当specMode为EXACTLY时,直接运用内定的specSize就能够;当specMode为其余三种格局时,必要给叁个私下认可的大小。假设钦赐wrap_content属性,即AT_MOST方式,则必要用大家钦命大小与specSize相当小值做为最终的衡量值。
    measureWidth(卡塔尔(قطر‎方法如下所示,这段代码基本得以视作模板代码:
private int measureWidth(int measureSpec) {
    int result = size;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if(specMode == MeasureSpec.EXACTLY) {
        result = specSize;
    } else {
        result = 200;  // 不是精确值模式时默认值为200
        if(specMode == MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
    }
    return result;
}

measureHeight(卡塔尔方法与masureWidth(卡塔尔基本一致。程序效果如下图所示。

ca88编程 7

结构作用

旋律条形图

只演示自定义View的用法,一纸空文地监听音频输入,随机模拟一些数字就可以。先看一下终极落到实处的法力图,如下图所示。

ca88编程 8

音频图

一旦要达成如此的效率,也正是绘制三个个的矩形,各个矩形之间稍稍偏移一点离开就可以。为了得以落成动态效果,只要在onDraw(卡塔尔方法中再去调用invalidate(State of Qatar方法通告View举行重绘就能够了。假使直接重绘会刷新太快影响意义,由此,能够选拔postInvalidateDelayed(300卡塔尔来开展缓延长时重绘。代码如下所示。

this.invalidate();
this.postInvalidateDelayed(300);

而且给绘制的Paint对象能够扩张三个LinearGradient渐变效果。代码如下所示。

private int mWidth;//控件的宽度
private int mRectWidth;// 矩形的宽度
private int mRectHeight;// 矩形的高度
private Paint mPaint;
private int mRectCount;// 矩形的个数
private int offset = 5;// 偏移
private double mRandom;
private LinearGradient lg;// 渐变

public ScaleMap(Context context) {
    this(context, null);
}

public ScaleMap(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    initPaint();  // 这些要在这里设置,因为渐变效果
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // 设置宽高
    setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}

// 初始化画笔
private void initPaint() {
    mPaint = new Paint();
    mPaint.setColor(Color.GREEN);
    mPaint.setStyle(Paint.Style.FILL);
    mRectCount = 12;
}

//重写onDraw方法
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    for (int i = 0; i < mRectCount; i  ) {
        mRandom = Math.random();
        float currentHeight = (int) (mRectHeight * mRandom);
        canvas.drawRect((float) (mWidth * 0.4 / 2   mRectWidth * i   offset * i), currentHeight,
        (float) (mWidth * 0.4 / 2   mRectWidth * (i   1)   offset * i), mRectHeight, mPaint);
    }
    postInvalidateDelayed(300);
}

//重写onSizeChanged方法,给画笔加上渐变
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mWidth = getWidth();
    mRectHeight = getHeight();
    mRectWidth = (int) (mWidth * 0.6 / mRectCount);
    lg = new LinearGradient(0, 0, mRectWidth, mRectHeight, Color.GREEN, Color.BLUE, TileMode.CLAMP);
    mPaint.setShader(lg);
}

自定义View一步一步来,从最宗旨的坚守初始,慢慢扩充效果与利益,绘制更目眩神摇的功用。

ViewGroup的绘制

ViewGroup经常状态下没有供给绘制,因为它自己就一向不索要绘制的东西,如若不是点名了ViewGroup的背景颜色,那么ViewGruop的onDraw()方法都不会被调用。不过,ViewGroup会使用dispatchDraw(卡塔尔方法去绘制其子View,其经过一样是经过遍历全部子View,并调用子View的绘图方法来变成绘制专门的学业。

导语

当系统控件不能够知足大家的急需的时候,此时大家就要求自定义控件,依据大家的必要来定制叁个能知足大家要求的控件。叁个让顾客熟谙的控件才是四个好的控件,如果一直追求光彩夺目的职能,会让顾客感觉硕大而无当。

Android控件结构

Android中的每一种控件都会在分界面中占得一块矩形区域,而在Android中央控制件差不离被分为两类,即ViewGroup控件与View控件。ViewGroup控件作为父控件能够包罗八个View控件,并管理其含有的View控件。
透过ViewGroup,整个分界面上的控件产生了叁个树形构造,那也正是我们常说的控件树,上层控件负担下层子控件的度量与绘图,并传递人机联作事件。
常见在Activity中应用findViewById(卡塔尔方法在控件树中以树的深浅优先遍历来查找对应元素。在每棵控件树的最上部,都有一个ViewParent对象,那正是整棵树的控件核心,全体的相互处监护人件都由它来归拢调节和分红,进而能够对总体视图举办一体化调节。下图展现了二个View视图树。

ca88编程 9

View树结构

经常见到意况下,在Activity中动用setContentView(卡塔尔国方法来设置四个搭架子,在调用该方法后,构造内容才真的地展现出来。Android分界面包车型大巴结构图如下图所示。

ca88编程 10

UI分界面结构图

在各样Activity中,都带有一个Window对象,在Android中Window对象日常由PhoneWindow来兑现。PhoneWindow将贰个DecorView设置为整个应用的窗口的根View。
DecorView作为窗口分界面包车型大巴顶层视图,封装了打包了一些窗口操作的通用方法。这里面全部View的监听事件,都经过WindowManagerService来进展收纳,并经过Activity对象来回调相应的onClickListener。在展现上它将荧屏分为两局部,三个是TitleView,另一个是ContentView。如下图所示。

ca88编程 11

行业内部视图树

视图树的第二层装载了叁个LinearLayout,作为ViewGroup,这一层的布局布局会基于对应的参数设置差别的布局,如最常用的构造——上边突显TitleBar下边是Content那样的布局。
顾客能够因而设置requestWindowFeature(Window.FEATURE_NO_TITLE卡塔尔国来安装全屏展现,视图树中的构作育就只有Content了,那就表达了干吗调用requestWindowFeature(卡塔尔方法自然要在调用setContentView(State of Qatar方法在此以前才干奏效的由来了。
在代码中,当程序在onCreate(State of Qatar方法中调用setContentView(卡塔尔方法后,ActivityManager瑟维斯会回调onResume(卡塔尔国方法,那时候系统才会把全体DecorView增添到PhoneWindow中,并让其出示出来,进而最终大功告成分界面包车型客车绘图。

本文由ca88发布,转载请注明来源

关键词: ca88网址 自定义 群英传 View Android开发