国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android視圖控件架構(gòu)分析之View、ViewGroup

2019-12-12 06:25:34
字體:
供稿:網(wǎng)友

在Android中,視圖控件大致被分為兩類,即ViewGroup和View,ViewGroup控件作為父控件,包含并管理著子View,通過ViewGroup和View便形成了控件樹,各個(gè)ViewGoup對(duì)象和View對(duì)象就是控件樹中的節(jié)點(diǎn)。在控件樹中,以樹的深度來遍歷查找對(duì)應(yīng)的控件元素,同時(shí),上層控件負(fù)責(zé)子控件的測(cè)量與繪制,并傳遞交互事件。

Android控件樹:

  

AndroidUI界面架構(gòu)圖:

  

一.測(cè)量View的工具類:MeasureSpec

1.MeasureSpec包含了測(cè)量的模式和測(cè)量的大小,通過MeasureSpec.getMode()獲取測(cè)量模式,通過MeasureSpec.getSize()獲取測(cè)量大小;

2.MeasureSpec是一個(gè)32位的int值,高2位為測(cè)量的模式,低30位為測(cè)量的大小,使用位運(yùn)算的目的在于提高優(yōu)化效率。

二.測(cè)量的模式

1.EXACTLY,精確值模式:將layout_width或layout_height屬性指定為具體數(shù)值或者match_parent。

2.AT_MOST,最大值模式:將layout_width或layout_height指定為wrap_content。

3.UNSPECIFIED: View想多大就多大

三.View類默認(rèn)的onMeasure()方法只支持EXACTLY模式,如果要支持其它模式,就必須重寫onMeasure(),重寫onMeasure()的模板代碼:

package com.example.demoapp.views;import android.content.Context;import android.view.View;public class MeasuredView extends View {  public MeasuredView(Context context) {    super(context);  }    @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    // 調(diào)用父類的onMeasure()    super.onMeasure(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    // 或者直接調(diào)用父類的setMeasuredDimension(),因?yàn)楦割惖膐nMeasure()最終調(diào)用了setMeasuredDimension()    // setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));  }    /**   * 測(cè)量View的width   * @param measureSpec MeasureSpec對(duì)象   * @return View的width   */  private int measureWidth(int measureSpec) {    int result = 0;    int specMode = MeasureSpec.getMode(measureSpec);    int specSize = MeasureSpec.getSize(measureSpec);        if (specMode == MeasureSpec.EXACTLY) {      result = specSize;    } else {      result = 200;      if (specMode == MeasureSpec.AT_MOST) {        result = Math.min(result, specSize);      }    }    return result;  }    /**   * 測(cè)量View的height   * @param measureSpec MeasureSpec對(duì)象   * @return View的height   */  private int measureHeight(int measureSpec) {    int result = 0;    int specMode = MeasureSpec.getMode(measureSpec);    int specSize = MeasureSpec.getSize(measureSpec);        if (specMode == MeasureSpec.EXACTLY) {      result = specSize;    } else {      result = 200;      if (specMode == MeasureSpec.AT_MOST) {        result = Math.min(result, specSize);      }    }    return result;  }}

四.View的繪制

1.2D繪圖必備利器――Canvas

  1)獲取Canvas對(duì)象的方式:

    a.由方法中的參數(shù)傳入,例如,View的onDraw()中有一個(gè)參數(shù)就是Canvas對(duì)象

    b.通過構(gòu)造方法構(gòu)造,即:Canvas canvas = new Canvas(bitmap),在Canvas的構(gòu)造方法傳入一個(gè)Bitmap對(duì)象,即可獲取一個(gè)Canvas對(duì)象。通過傳入Bitmap對(duì)象構(gòu)造Canvas對(duì)象的過程稱為“畫布的裝載”,傳入的Bitmap對(duì)象承載了多有繪制在Canvas上的像素信息,調(diào)用Canvas.drawXXX方法(如:Canvas.drawBitmap(bitmap, 0, 0, null))都將發(fā)生在該Bitmap對(duì)象上。

  2)利用Canvas繪圖

    a.通過Canvas.drwaXXX進(jìn)行繪制操作將直接作用于Bitmap對(duì)象,當(dāng)再次刷新View的時(shí)候,我們將會(huì)被繪制的Bitmap對(duì)象發(fā)生了改變;

    b.利用Canvas和Paint進(jìn)行繪圖;

    c.不管多么復(fù)雜、精美的空間,都可以被拆分為一個(gè)個(gè)小的圖形單元,我們只要找到這些圖形單元,就可以將控件繪制出來。

五.ViewGroup的測(cè)量

  1.ViewGroup的作用:管理子View,如子View的大小、位置;

  2.ViewGroup通過遍歷子View,調(diào)用子View的Measure()來獲得每一個(gè)子View的測(cè)量結(jié)果;

  3.ViewGroup測(cè)量完子View,調(diào)用子View的Layout()將子View放到合適的位置;

  4.在自定義ViewGroup的時(shí)候,通常會(huì)重寫onLayout()控制子View的顯示;

  5.如果需要支持wrap_content屬性,必須重寫onMeasure()。

六、ViewGroup的繪制

  通常情況下,ViewGoup不需要繪制,但是ViewGroup會(huì)使用dispatchDraw()來繪制其子View。

七.自定義View

1.自定義View的時(shí)候,通常需要重寫onDraw()來繪制View要顯示的內(nèi)容,如果還需要支持wrap_content屬性,必須重寫onMeasure();

2.通過自定義attrs屬性,可以設(shè)置新的View屬性;

3.View中一些重要的回調(diào)方法:

    1)onFinishInflate():從XML中加載組建后回調(diào);

    2)onSizeChanged():組件大小改變時(shí)回調(diào);

    3)onMeasure():進(jìn)行測(cè)量;

    4)onLayout():設(shè)置顯示的位置;

    5)onTouchEvent():觸摸事件。

4.實(shí)現(xiàn)自定義View的三種常用方法:

    1)通過重寫onDraw()對(duì)原生控件進(jìn)行擴(kuò)展;

    2)通過組合實(shí)現(xiàn)新的控件,通常集成一個(gè)合適的額ViewGoup,再通過addView()給它添加指定功能的控件,從而組合成新的復(fù)合控件。

    3)重寫View實(shí)現(xiàn)全新的控件,通過重寫onDraw(),onMeasure()實(shí)現(xiàn)繪制邏輯,重寫onTouchEvent()實(shí)現(xiàn)交互邏輯。

5.自定義屬性

    1)自定義屬性的方法:在res資源目錄的values目錄下創(chuàng)建一個(gè)attrs.xml的屬性定義文件,文件模板:

<?xml version="1.0" encoding="utf-8"?><resources>  <declare-styleable name="customAttr">    <attr name="title" format="string" />    <attr name="fontSize" format="dimension" />    <attr name="fontColor" format="color" />    <attr name="background" format="reference|color" />    <attr name="fontStyle" format="enum" />    <attr name="shadeSupport" format="boolean" />  </declare-styleable></resources>

    2)通過TypedArray獲取自定義屬性集,通過TypedArray.getString()、TypedArray.getColor()等方法獲取屬性值,模板代碼:

package com.jy.myrecyclerview.test;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import com.jy.myrecyclerview.R;/** * Created by 123 on 2016/5/6. */public class TestCustomAttrs extends View {  private Context mContext;  private AttributeSet mAttrs;  private String mTitle;  private float mFontSize;  private int mFontColor;  private int mBackground;  private int mFontStyle;  private boolean mShadeSupport;  public TestCustomAttrs(Context context) {    super(context);    this.mContext = context;  }  public TestCustomAttrs(Context context, AttributeSet attrs) {    super(context, attrs);    this.mContext = context;    this.mAttrs = attrs;  }  public TestCustomAttrs(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    this.mContext = context;    this.mAttrs = attrs;  }  private void getCustomAttrs() {    TypedArray ta = mContext.obtainStyledAttributes(mAttrs, R.styleable.customAttr);    mTitle = ta.getString(R.styleable.customAttr_title);    mFontSize = ta.getDimension(R.styleable.customAttr_fontSize, 10);    mFontColor = ta.getColor(R.styleable.customAttr_fontColor, 0);    mBackground = ta.getColor(R.styleable.customAttr_background, 0);    mFontStyle = ta.getInt(R.styleable.customAttr_fontStyle, 0);    mShadeSupport = ta.getBoolean(R.styleable.customAttr_shadeSupport, false);    ta.recycle();  }}  

6.定義回調(diào)接口,實(shí)現(xiàn)自定義控件的靈活控制;

7.引用UI模板

    1)自定義控件需要使用命名空間進(jìn)行引入:xmlns:custom="http://schemas.android.com/apk/res-auto",即將自定義控件的命名空間取名為custom

    2)在XML文件中使用自定義屬性的時(shí)候,就可以通過這個(gè)命名空間來引用,代碼模板如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:custom="http://schemas.android.com/apk/res-auto"  android:layout_width="match_parent"  android:layout_height="match_parent" >  <com.jy.myrecyclerview.test.TestCustomAttrs    android:id="@+id/id_recyclerview"    android:divider="#ffff0000"    android:dividerHeight="10dp"    android:layout_width="match_parent"    android:layout_height="match_parent"    custom:title="title"    custom:fontSize="12sp"    custom:fontColor="@color/colorPrimary"    custom:background="@color/colorPrimary"    custom:shadeSupport="false" /></RelativeLayout>

九.自定義ViewGroup

  1.需要重寫的方法:

    1)onMeasure():對(duì)子View進(jìn)行測(cè)量;

    2)onLayout():設(shè)置子View的位置;

    3)onTouchEvent():設(shè)置觸摸交互事件。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 佛冈县| 策勒县| 丹江口市| 永宁县| 繁峙县| 冷水江市| 许昌市| 阿克陶县| 绵阳市| 砚山县| 西乌珠穆沁旗| 汉沽区| 沁源县| 寿阳县| 吴桥县| 云林县| 来凤县| 嘉定区| 洛扎县| 石狮市| 白银市| 孝昌县| 鄯善县| 太谷县| 涿州市| 三明市| 荔浦县| 兴仁县| 仁布县| 玉树县| 红安县| 客服| 房产| 淮滨县| 东光县| 巫山县| 泽州县| 尼勒克县| 西青区| 大庆市| 玛曲县|