欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

揭秘Android視圖繪制的流程步驟

 更新時(shí)間:2023年06月02日 08:37:02   作者:午后一小憩  
在Android的UI中,View是至關(guān)重要的一個(gè)組件,它是用戶(hù)界面的基本構(gòu)建塊,在View的繪制過(guò)程中,涉及到很多重要的概念和技術(shù),本文將詳細(xì)介紹Android?View的繪制過(guò)程,讓你能夠更好地理解和掌握Android的UI開(kāi)發(fā),需要的朋友可以參考下

什么是View?

View是Android系統(tǒng)中的一個(gè)基本組件,它是用戶(hù)界面上的一個(gè)矩形區(qū)域,可以用來(lái)展示文本、圖片、按鈕等等。View可以響應(yīng)用戶(hù)的交互事件,比如點(diǎn)擊、滑動(dòng)等等。在Android中,所有的UI組件都是繼承自View類(lèi)。

View的繪制過(guò)程

View的繪制過(guò)程可以分為三個(gè)階段:測(cè)量、布局和繪制。下面我們將逐一介紹這三個(gè)階段。

測(cè)量階段(Measure)

測(cè)量階段是View繪制過(guò)程的第一個(gè)重要階段。在測(cè)量階段,系統(tǒng)會(huì)調(diào)用View的onMeasure方法,測(cè)量View的寬度和高度。在這個(gè)過(guò)程中,系統(tǒng)會(huì)根據(jù)View的LayoutParams和父容器的大小來(lái)計(jì)算出View的大小。

例:下面代碼是一個(gè)自定義View的onMeasure方法例程。在測(cè)量過(guò)程中,我們?cè)O(shè)定了View的大小。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // 獲取寬度的Size和Mode
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    // 如果Mode是精確的,直接返回
    if (widthMode == MeasureSpec.EXACTLY) {
        setMeasuredDimension(widthSize, heightMeasureSpec);
        return;
    }
    // 計(jì)算View的寬度
    int desiredWidth = getPaddingLeft() + getPaddingRight() + defaultWidth;
    int measuredWidth;
    if (desiredWidth < widthSize) {
        measuredWidth = desiredWidth;
    } else {
        measuredWidth = widthSize;
    }
    // 設(shè)置寬度和高度的Size和Mode
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int measuredHeight = defaultHeight;
    if (heightMode == MeasureSpec.EXACTLY) {
        measuredHeight = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        measuredHeight = Math.min(defaultHeight, heightSize);
    }
    setMeasuredDimension(measuredWidth, measuredHeight);
}

在測(cè)量階段結(jié)束后,系統(tǒng)會(huì)將計(jì)算好的寬度和高度傳遞給布局階段。

布局階段(Layout)

布局階段是View繪制過(guò)程的第二個(gè)重要階段。在布局階段,系統(tǒng)會(huì)調(diào)用View的onLayout方法,將View放置在父容器中的正確位置。在這個(gè)過(guò)程中,系統(tǒng)會(huì)根據(jù)View的LayoutParams和父容器的位置來(lái)確定View的位置。

例:下面代碼是一個(gè)自定義ViewGroup的onLayout方法例程。在布局過(guò)程中,我們遍歷子View,并根據(jù)LayoutParams確定子View的位置和大小。

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int count = getChildCount();
    int left = getPaddingLeft();
    int top = getPaddingTop();
    int right = getMeasuredWidth() - getPaddingRight();
    int bottom = getMeasuredHeight() - getPaddingBottom();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() == GONE) {
            continue;
        }
        LayoutParams lp = (LayoutParams) child.getLayoutParams();
        int childLeft = left + lp.leftMargin;
        int childTop = top + lp.topMargin;
        int childRight = right - lp.rightMargin;
        int childBottom = bottom - lp.bottomMargin;
        child.layout(childLeft, childTop, childRight, childBottom);
    }
}

繪制階段(Draw)

繪制階段是View繪制過(guò)程的最后一個(gè)重要階段。在繪制階段,系統(tǒng)會(huì)調(diào)用View的onDraw方法,繪制View的內(nèi)容。在這個(gè)過(guò)程中,我們可以使用Canvas對(duì)象來(lái)繪制各種形狀、文本和圖片等等。

例:下面代碼是一個(gè)自定義View的onDraw方法例程。在繪制過(guò)程中,我們使用Paint對(duì)象繪制了一段文本。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //繪制文本
    String text = "Hello World";
    Paint paint = new Paint();
    paint.setTextSize(50);
    paint.setColor(Color.RED);
    paint.setAntiAlias(true);
    canvas.drawText(text, 0, getHeight() / 2, paint);
}

除了繪制內(nèi)容,我們還可以在繪制階段繪制View的背景和前景。系統(tǒng)會(huì)調(diào)用drawBackgrounddrawForeground方法來(lái)繪制背景和前景。值得注意的是,View的繪制順序是:先繪制背景,再繪制內(nèi)容,最后繪制前景。

View的繪制流程

View的繪制流程可以看作是一個(gè)遞歸調(diào)用的過(guò)程,下面我們將具體介紹這個(gè)過(guò)程。

Step 1:創(chuàng)建View

在View繪制過(guò)程的開(kāi)始階段,我們需要?jiǎng)?chuàng)建一個(gè)View對(duì)象,并將它添加到父容器中。在這個(gè)過(guò)程中,系統(tǒng)會(huì)調(diào)用View的構(gòu)造函數(shù),并將View的LayoutParams傳遞給它。

Step 2:測(cè)量View

接下來(lái),系統(tǒng)會(huì)調(diào)用View的measure方法,測(cè)量View的寬度和高度。在這個(gè)過(guò)程中,View會(huì)根據(jù)自身的LayoutParams和父容器的大小來(lái)計(jì)算出自己的寬度和高度。

Step 3:布局View

在測(cè)量完成后,系統(tǒng)會(huì)調(diào)用View的layout方法,將View放置在父容器中的正確位置。在這個(gè)過(guò)程中,View會(huì)根據(jù)自身的LayoutParams和父容器的位置來(lái)確定自己的位置。

Step 4:繪制背景

在布局完成后,系統(tǒng)會(huì)調(diào)用View的drawBackground方法,繪制View的背景。在這個(gè)過(guò)程中,我們可以使用Canvas對(duì)象來(lái)繪制各種形狀、文本和圖片等等。

Step 5:繪制內(nèi)容

接下來(lái),系統(tǒng)會(huì)調(diào)用View的onDraw方法,繪制View的內(nèi)容。在這個(gè)過(guò)程中,我們可以使用Canvas對(duì)象來(lái)繪制各種形狀、文本和圖片等等。

Step 6:繪制前景

在繪制內(nèi)容完成后,系統(tǒng)會(huì)調(diào)用View的drawForeground方法,繪制View的前景。在這個(gè)過(guò)程中,我們同樣可以使用Canvas對(duì)象來(lái)繪制各種形狀、文本和圖片等等。

Step 7:繪制子View

接著,系統(tǒng)會(huì)遞歸調(diào)用ViewGroup的dispatchDraw方法,繪制所有子View的內(nèi)容。在這個(gè)過(guò)程中,我們可以使用Canvas對(duì)象來(lái)繪制各種形狀、文本和圖片等等。

Step 8:完成繪制

最后,所有的View繪制完成,整個(gè)View樹(shù)也就繪制完成。

例:下面代碼是一個(gè)自定義ViewGroup的繪制流程例程。在繪制過(guò)程中,我們先畫(huà)背景,再繪制每個(gè)子View的內(nèi)容。

public class MyViewGroup extends ViewGroup {
    public MyViewGroup(Context context) {
        super(context);
    }
    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 測(cè)量子View的寬高
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        // 獲取ViewGroup的寬高大小
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        // 設(shè)置ViewGroup的寬高
        setMeasuredDimension(widthSize, heightSize);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // 遍歷所有子View,設(shè)置它們的位置和大小
        int childCount = getChildCount();
        int left, top, right, bottom;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            left = childView.getLeft();
            top = childView.getTop();
            right = childView.getRight();
            bottom = childView.getBottom();
            childView.layout(left, top, right, bottom);
        }
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 畫(huà)背景
        canvas.drawColor(Color.WHITE);
    }
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        // 繪制每個(gè)子View的內(nèi)容
        for (int i = 0; i < getChildCount(); i++) {
            View childView = getChildAt(i);
            childView.draw(canvas);
        }
    }
}

在ViewGroup的繪制流程中,系統(tǒng)會(huì)先調(diào)用ViewGroup的draw方法,然后依次調(diào)用dispatchDraw方法和繪制每個(gè)子View的draw方法。ViewGroup的繪制順序是先繪制自己的背景,再繪制每個(gè)子View的內(nèi)容和背景,最后繪制自己的前景。

總結(jié)

本文詳細(xì)介紹了Android View的繪制過(guò)程,包括測(cè)量階段、布局階段和繪制階段。同時(shí),我們還在代碼實(shí)現(xiàn)的角度,詳細(xì)說(shuō)明了Android ViewGroup的繪制流程,幫助你更好地理解和掌握Android的UI開(kāi)發(fā)。

以上就是揭秘Android視圖繪制的流程步驟的詳細(xì)內(nèi)容,更多關(guān)于Android 視圖繪制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • android RecyclerView的一些優(yōu)化點(diǎn)介紹

    android RecyclerView的一些優(yōu)化點(diǎn)介紹

    大家好,本篇文章主要講的是android RecyclerView的一些優(yōu)化點(diǎn)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽
    2021-12-12
  • Android編程實(shí)現(xiàn)震動(dòng)與振鈴的方法詳解

    Android編程實(shí)現(xiàn)震動(dòng)與振鈴的方法詳解

    這篇文章主要介紹了Android編程實(shí)現(xiàn)震動(dòng)與振鈴的方法,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)震動(dòng)與振鈴的Vibrator類(lèi)及MediaPlayer類(lèi)相關(guān)使用技巧,需要的朋友可以參考下
    2018-03-03
  • 總結(jié)Android App內(nèi)存優(yōu)化之圖片優(yōu)化

    總結(jié)Android App內(nèi)存優(yōu)化之圖片優(yōu)化

    網(wǎng)上有很多大拿分享的關(guān)于Android性能優(yōu)化的文章,主要是通過(guò)各種工具分析,使用合理的技巧優(yōu)化APP的體驗(yàn),提升APP的流暢度,但關(guān)于內(nèi)存優(yōu)化的文章很少有看到。下面是我在實(shí)踐過(guò)程中使用的一些方法,很多都是不太成熟的項(xiàng)目,只是將其作為一種處理方式分享給大家。
    2016-08-08
  • Android自定義TabLayout效果

    Android自定義TabLayout效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義TabLayout效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android studio 2020中的Android SDK 下載教程

    Android studio 2020中的Android SDK 下載教程

    這篇文章主要介紹了Android studio 2020中的Android SDK 下載教程,本文圖文并茂給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Android Rxjava3 使用場(chǎng)景詳解

    Android Rxjava3 使用場(chǎng)景詳解

    本文主要介紹了Android Rxjava3 使用場(chǎng)景詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • android實(shí)現(xiàn)背景平鋪的三種方法

    android實(shí)現(xiàn)背景平鋪的三種方法

    這篇文章主要介紹了Android的圖片平鋪效果的實(shí)現(xiàn)方法,主要有使用系統(tǒng)API、使用XML配置、自定義繪制三種方法,需要的朋友可以參考下
    2014-02-02
  • Android的Activity跳轉(zhuǎn)動(dòng)畫(huà)各種效果整理

    Android的Activity跳轉(zhuǎn)動(dòng)畫(huà)各種效果整理

    Android的Activity跳轉(zhuǎn)就是很生硬的切換界面。其實(shí)Android的Activity跳轉(zhuǎn)可以設(shè)置各種動(dòng)畫(huà),本文整理了一些,還有很多動(dòng)畫(huà)效果,就要靠我們發(fā)揮自己的想象力
    2013-06-06
  • Android GPS室內(nèi)定位問(wèn)題的解決方法(location為null)

    Android GPS室內(nèi)定位問(wèn)題的解決方法(location為null)

    這篇文章主要為大家詳細(xì)介紹了Android GPS室內(nèi)定位問(wèn)題的解決方法,location為null,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android實(shí)現(xiàn)拖動(dòng)效果的兩種方法

    Android實(shí)現(xiàn)拖動(dòng)效果的兩種方法

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)拖動(dòng)效果的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04

最新評(píng)論