日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

HenCoder Android 开发进阶:自定义 View 1-3 drawText() 文字的绘制

發布時間:2023/12/10 Android 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HenCoder Android 开发进阶:自定义 View 1-3 drawText() 文字的绘制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這期是 HenCoder 自定義繪制的第三期:文字的繪制。

之前的內容在這里:?
HenCoder Android 開發進階 自定義 View 1-1 繪制基礎?
HenCoder Android 開發進階 自定義 View 1-2 Paint 詳解

如果你沒聽說過 HenCoder,可以先看看這個:?
HenCoder:給高級 Android 工程師的進階手冊

簡介

上期的 Paint 詳解里已經說過,文字的繪制所能控制的內容太多太細,必須拆成單獨的一期專門來講。今天這期,就是來把這些細節講清楚的。

需要說明的有兩點:

  • 和上期一樣,這期講的是細節,其中有一部分內容并不是很常用,所以這期你不必要求自己把內容全部背會,而只要做到全部理解,知道都有什么東西,大概怎么用就好,到你真正需要用的時候再拐回來看就是;
  • 除了常用和不常用的內容,本期還會講到一些比較偏門的細節。這些偏門幾乎永遠不會用到,我講這些偏門的目的也只是為了做到知識的全覆蓋,幫你破開迷霧解開謎團,把那些「始終沒有搞懂,也不知道有沒有用」的 API 解釋出來。有的時候,一樣東西你確定了它確實沒用,也就夠了。所以如果遇到這些偏門的內容,你感興趣,看看就好;不感興趣,不看也罷——總之,不要把太多精力放在它們身上。
  • 下面進入正題。

    1 Canvas 繪制文字的方式

    Canvas?的文字繪制方法有三個:drawText()?drawTextRun()?和?drawTextOnPath()。

    1.1 drawText(String text, float x, float y, Paint paint)

    drawText()?是?Canvas?最基本的繪制文字的方法:給出文字的內容和位置,?Canvas?按要求去繪制文字。

    String text = "Hello HenCoder";...canvas.drawText(text, 200, 100, paint);

    方法的參數很簡單:?text?是文字內容,x?和?y?是文字的坐標。但需要注意:這個坐標并不是文字的左上角,而是一個與左下角比較接近的位置。大概在這里:

    而如果你像繪制其他內容一樣,在繪制文字的時候把坐標填成 (0, 0),文字并不會顯示在 View 的左上角,而是會幾乎完全顯示在 View 的上方,到了 View 外部看不到的位置:

    canvas.drawText(text, 0, 0, paint);

    ↑ 這里沒有貼錯圖哦

    再附上一張圖,應該能更清楚地表達:

    這是為什么?為什么其它的?Canvas.drawXXX()?方法,都是以左上角作為基準點的,而?drawText()?卻是文字左下方?

    先別覺得日了狗,這種設計其實是有道理的。drawText()?參數中的?y?,指的是文字的基線( baseline )?的位置。也就是這條線:

    眾所周知,不同的語言和文字,每個字符的高度和上下位置都是不一樣的。要讓不同的文字并排顯示的時候整體看起來穩當,需要讓它們上下對齊。但這個對齊的方式,不能是簡單的「底部對齊」或「頂部對齊」或「中間對齊」,而應該是一種類似于「重心對齊」的方式。就像電線上的小鳥一樣:

    每只小鳥的最高點和最低點都不一樣,但畫面很平衡

    而這個用來讓所有文字互相對齊的基準線,就是基線( baseline )。?drawText()?方法參數中的?y?值,就是指定的基線的位置。

    說完?y?值,再說說?x?值。從前面圖中的標記可以看出來,「Hello HenCoder」繪制出來之后的?x?點并不是字母 "H" 左邊的位置,而是比它的左邊再往左一點點。那么這個「往左的一點點」是什么呢?

    它是字母 "H" 的左邊的空隙。絕大多數的字符,它們的寬度都是要略微大于實際顯示的寬度的。字符的左右兩邊會留出一部分空隙,用于文字之間的間隔,以及文字和邊框的間隔。就像這樣:

    用豎線標記出邊界后的文字。

    所以,明白為什么?x?坐標在 "H" 的左邊再往左一點點的位置,而不是緊貼著 "H" 的左邊線了嗎?就是因為 "H" 的這個留出的空隙。

    除了?drawText(text, x, y, paint)?之外,?drawText()?還有幾個重載方法,使用方式跟這個都差不多,我就不說了,你自己看吧。

    1.2 drawTextRun()

    聲明:這個方法對中國人沒用。所以如果你有興趣,可以繼續看;而如果你想省時間,直接跳過這個方法看后面的就好了,沒有任何毒副作用。

    drawTextRun()?是在 API 23 新加入的方法。它和?drawText()?一樣都是繪制文字,但加入了兩項額外的設置——上下文和文字方向——用于輔助一些文字結構比較特殊的語言的繪制。

    • 額外設置一:上下文。

      有些語言的文字,字符的形狀會互相之間影響:一個字你單獨寫是一個樣,和別的字放在一起寫又是另外一個樣。不過由于我們最熟悉的語言——漢語和英語——都沒有這種情況,所以只靠說可能不太好理解,我就用圖說明一下吧。

      以阿拉伯文為例。阿拉伯文里的「????(阿拉伯)」是一個四字詞,它的中間兩個字符「??」在這個詞里的樣子,和單獨寫的時候的樣子是不同的。也就是說,當這四個字寫在一起的時候,中間兩個字由于受到兩邊的字的影響,形狀被改變了。看圖吧:

      上面第二行和第三行的文字是完全一樣的倆字,你敢信?

      哇塞,是不是特別神奇?

      不過我們就不用管它為什么這么神奇了,也不用替阿拉伯人操心這么復雜的文字他們使用起來會不會很痛苦,人家都已經用了幾百上千年了。我還說回到?drawTextRun()。?drawTextRun()?除了文字的內容和位置之外,還可以設置文字的上下文(也就是要繪制的文字的左邊和右邊是什么文字,雖然這些文字并不會被繪制出來),從而讓同樣的文字可以按需表現出不同的顯示效果。

    • 額外設置二:文字方向。

      除了上下文,?drawTextRun()?還可以設置文字的方向,即文字是從左到右還是從右到左排列的。

    介紹完這兩類額外設置,來看一下具體的方法吧:

    drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint paint)

    參數:?
    text:要繪制的文字?
    start:從那個字開始繪制?
    end:繪制到哪個字結束?
    contextStart:上下文的起始位置。contextStart?需要小于等于?start?
    contextEnd:上下文的結束位置。contextEnd?需要大于等于?end?
    x:文字左邊的坐標?
    y:文字的基線坐標?
    isRtl:是否是 RTL(Right-To-Left,從右向左)

    要實現上面圖中的「同樣的字有不同的顯示」效果,調節?contextStart?和?contextEnd?就可以了,至于具體的實現,你有興趣的話就自己試試吧。

    這就是?drawTextRun()?,一個增加了「上下文」和「RTL」支持的增強版本的?drawText()?。不過就像剛才說過的,這個方法對中國人其實沒什么用……

    1.3 drawTextOnPath()

    沿著一條?Path?來繪制文字。這是一個耍雜技的方法。

    canvas.drawPath(path, paint); // 把 Path 也繪制出來,理解起來更方便 canvas.drawTextOnPath("Hello HeCoder", path, 0, 0, paint);

    吁,拐角處的文字怎么那么難看?

    所以記住一條原則:?drawTextOnPath()?使用的?Path?,拐彎處全用圓角,別用尖角。

    具體的方法很簡單:

    drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)

    參數里,需要解釋的只有兩個:?hOffset?和?vOffset。它們是文字相對于?Path?的水平偏移量和豎直偏移量,利用它們可以調整文字的位置。例如你設置?hOffset?為 5,?vOffset?為 10,文字就會右移 5 像素和下移 10 像素。

    1.4 StaticLayout

    額外講一個?StaticLayout。這個也是使用?Canvas?來進行文字的繪制,不過并不是使用?Canvas?的方法。

    Canvas.drawText()?只能繪制單行的文字,而不能換行。它:

    • 不能在 View 的邊緣自動折行
    String text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";...canvas.drawText(text, 50, 100, paint);

    到了 View 的邊緣處,文字繼續向后繪制到看不見的地方,而不是自動換行

    • 不能在換行符?\n?處換行
    String text = "a\nbc\ndefghi\njklm\nnopqrst\nuvwx\nyz";...canvas.drawText(text, 50, 100, paint);

    在換行符?\n?的位置并沒有換行,而只是加了個空格

    如果需要繪制多行的文字,你必須自行把文字切斷后分多次使用?drawText()?來繪制,或者——使用?StaticLayout?。

    StaticLayout?并不是一個?View?或者?ViewGroup?,而是?android.text.Layout?的子類,它是純粹用來繪制文字的。?StaticLayout?支持換行,它既可以為文字設置寬度上限來讓文字自動換行,也會在?\n處主動換行。

    String text1 = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; StaticLayout staticLayout1 = new StaticLayout(text1, paint, 600, Layout.Alignment.ALIGN_NORMAL, 1, 0, true); String text2 = "a\nbc\ndefghi\njklm\nnopqrst\nuvwx\nyz"; StaticLayout staticLayout2 = new StaticLayout(text2, paint, 600, Layout.Alignment.ALIGN_NORMAL, 1, 0, true);...canvas.save(); canvas.translate(50, 100); staticLayout1.draw(canvas); canvas.translate(0, 200); staticLayout2.draw(canvas); canvas.restore();

    上面代碼中出現的?Canvas.save()?Canvas.translate()?Canvas.restore()?配合起來可以對繪制的內容進行移動。它們的具體用法我會在下期講,這期你就先依葫蘆畫瓢照搬著用吧。

    StaticLayout?的構造方法是 StaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad),其中參數里:

    width?是文字區域的寬度,文字到達這個寬度后就會自動換行;?
    align?是文字的對齊方向;?
    spacingmult?是行間距的倍數,通常情況下填 1 就好;?
    spacingadd?是行間距的額外增加值,通常情況下填 0 就好;?
    includeadd?是指是否在文字上下添加額外的空間,來避免某些過高的字符的繪制出現越界。

    如果你需要進行多行文字的繪制,并且對文字的排列和樣式沒有太復雜的花式要求,那么使用?StaticLayout?就好。

    2 Paint 對文字繪制的輔助

    Paint?對文字繪制的輔助,有兩類方法:設置顯示效果的和測量文字尺寸的。

    2.1 設置顯示效果類

    2.1.1 setTextSize(float textSize)

    設置文字大小。

    paint.setTextSize(18); canvas.drawText(text, 100, 25, paint); paint.setTextSize(36); canvas.drawText(text, 100, 70, paint); paint.setTextSize(60); canvas.drawText(text, 100, 145, paint); paint.setTextSize(84); canvas.drawText(text, 100, 240, paint);

    很簡單,不再詳細解釋。

    2.1.2 setTypeface(Typeface typeface)

    設置字體。

    paint.setTypeface(Typeface.DEFAULT); canvas.drawText(text, 100, 150, paint); paint.setTypeface(Typeface.SERIF); canvas.drawText(text, 100, 300, paint); paint.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "Satisfy-Regular.ttf")); canvas.drawText(text, 100, 450, paint);

    設置不同的?Typeface?就可以顯示不同的字體。我們中國人談到「字體」,比較熟悉的詞是 font, typeface 和 font 是一個意思,都表示字體。?Typeface?這個類的具體用法,需要了解的話可以直接看文檔,很簡單。

    嚴格地說,其實 typeface 和 font 意思不完全一樣。typeface 指的是某套字體(即 font family ),而 font 指的是一個 typeface 具體的某個 weight 和 size 的分支。不過無所謂啦~做人最緊要系開心啦。

    2.1.3 setFakeBoldText(boolean fakeBoldText)

    是否使用偽粗體。

    paint.setFakeBoldText(false); canvas.drawText(text, 100, 150, paint); paint.setFakeBoldText(true); canvas.drawText(text, 100, 230, paint);

    之所以叫偽粗體( fake bold ),因為它并不是通過選用更高 weight 的字體讓文字變粗,而是通過程序在運行時把文字給「描粗」了。

    2.1.4 setStrikeThruText(boolean strikeThruText)

    是否加刪除線。

    paint.setStrikeThruText(true); canvas.drawText(text, 100, 150, paint);

    2.1.5 setUnderlineText(boolean underlineText)

    是否加下劃線。

    paint.setUnderlineText(true); canvas.drawText(text, 100, 150, paint);

    2.1.6 setTextSkewX(float skewX)

    設置文字橫向錯切角度。其實就是文字傾斜度的啦。

    paint.setTextSkewX(-0.5f); canvas.drawText(text, 100, 150, paint);

    2.1.7 setTextScaleX(float scaleX)

    設置文字橫向放縮。也就是文字變胖變瘦。

    paint.setTextScaleX(1); canvas.drawText(text, 100, 150, paint); paint.setTextScaleX(0.8f); canvas.drawText(text, 100, 230, paint); paint.setTextScaleX(1.2f); canvas.drawText(text, 100, 310, paint);

    2.1.8 setLetterSpacing(float letterSpacing)

    設置字符間距。默認值是 0。

    paint.setLetterSpacing(0.2f); canvas.drawText(text, 100, 150, paint);

    為什么在默認的字符間距為 0 的情況下,字符和字符之間也沒有緊緊貼著,這個我在前面講?Canvas.drawText()?的?x?參數的時候已經說過了,在這里應該沒有疑問吧?

    2.1.9 setFontFeatureSettings(String settings)

    用 CSS 的?font-feature-settings?的方式來設置文字。

    paint.setFontFeatureSettings("smcp"); // 設置 "small caps" canvas.drawText("Hello HenCoder", 100, 150, paint);

    CSS 全稱是 Cascading Style Sheets ,是網頁開發用來設置頁面各種元素的樣式的。咦,網頁開發的設置怎么會出現在 Android 的 API 里?

    大多數 Android 開發者都不了解這個 CSS 的?font-feature-settings?屬性,不過沒關系,這個屬性設置的都是文字的一些次要特性,所以不用著急了解這個方法。當然有興趣的話也可以看一看哈,文檔在這里。

    2.1.10 setTextAlign(Paint.Align align)

    設置文字的對齊方式。一共有三個值:LEFT?CETNER?和?RIGHT。默認值為?LEFT。

    paint.setTextAlign(Paint.Align.LEFT); canvas.drawText(text, 500, 150, paint); paint.setTextAlign(Paint.Align.CENTER); canvas.drawText(text, 500, 150 + textHeight, paint); paint.setTextAlign(Paint.Align.RIGHT); canvas.drawText(text, 500, 150 + textHeight * 2, paint);

    2.1.11 setTextLocale(Locale locale) / setTextLocales(LocaleList locales)

    設置繪制所使用的?Locale。

    Locale?直譯是「地域」,其實就是你在系統里設置的「語言」或「語言區域」(具體名稱取決于你用的是什么手機),比如「簡體中文(中國)」「English (US)」「English (UK)」。有些同源的語言,在文化發展過程中對一些相同的字衍生出了不同的寫法(比如中國大陸和日本對于某些漢字的寫法就有細微差別。注意,不是繁體和簡體這種同音同義不同字,而真的是同樣的一個字有兩種寫法)。系統語言不同,同樣的一個字的顯示就有可能不同。你可以試一下把自己手機的語言改成日文,然后打開微信看看聊天記錄,你會明顯發現文字的顯示發生了很多細微的變化,這就是由于系統的?Locale?改變所導致的。

    Canvas?繪制的時候,默認使用的是系統設置里的?Locale。而通過?Paint.setTextLocale(Locale locale)?就可以在不改變系統設置的情況下,直接修改繪制時的?Locale。

    paint.setTextLocale(Locale.CHINA); // 簡體中文 canvas.drawText(text, 150, 150, paint); paint.setTextLocale(Locale.TAIWAN); // 繁體中文 canvas.drawText(text, 150, 150 + textHeight, paint); paint.setTextLocale(Locale.JAPAN); // 日語 canvas.drawText(text, 150, 150 + textHeight * 2, paint);

    有意思吧?

    另外,由于 Android 7.0 ( API v24) 加入了多語言區域的支持,所以在 API v24 以及更高版本上,還可以使用?setTextLocales(LocaleList locales)?來為繪制設置多個語言區域。

    2.1.12 setHinting(int mode)

    設置是否啟用字體的 hinting (字體微調)。

    現在的 Android 設備大多數都是是用的矢量字體。矢量字體的原理是對每個字體給出一個字形的矢量描述,然后使用這一個矢量來對所有的尺寸的字體來生成對應的字形。由于不必為所有字號都設計它們的字體形狀,所以在字號較大的時候,矢量字體也能夠保持字體的圓潤,這是矢量字體的優勢。不過當文字的尺寸過小(比如高度小于 16 像素),有些文字會由于失去過多細節而變得不太好看。 hinting 技術就是為了解決這種問題的:通過向字體中加入 hinting 信息,讓矢量字體在尺寸過小的時候得到針對性的修正,從而提高顯示效果。效果圖盜一張維基百科的:

    功能很強,效果很贊。不過在現在( 2017 年),手機屏幕的像素密度已經非常高,幾乎不會再出現字體尺寸小到需要靠 hinting 來修正的情況,所以這個方法其實……沒啥用了。可以忽略。

    2.1.13 setElegantTextHeight(boolean elegant)

    聲明:這個方法對中國人沒用,不想看的話可以直接跳過,無毒副作用。

    設置是否開啟文字的 elegant height 。開啟之后,文字的高度就變優雅了(誤)。下面解釋一下所謂的 elegant height:

    在有些語言中,可能會出現一些非常高的字形:

    左邊那幾個泰文文字,挺高的吧?但其實它們已經是被壓縮過了的,它們本來比這還要高。

    這些比較高的文字,通常都有兩個版本的字體:一個原始版本,一個壓縮了高度的版本。壓縮版本可以保證讓這些「大高個」文字在和普通文字(例如拉丁文字)放在一起的時候看起來不會顯得太奇怪。事實上,Paint?繪制文字時是用的默認版本就是壓縮版本,就像上圖這樣。

    不過有的時候,開發者會需要使用它們的原始(優雅)版本。使用?setElegantTextHeight()?就可以切換到原始版本:

    paint.setElegantTextHeight(true);

    這字得有多高?2 米 26 ?

    那么,setElegantTextHeight()?的作用到這里就很清晰了:

  • 把「大高個」文字的高度恢復為原始高度;
  • 增大每行文字的上下邊界,來容納被加高了的文字。
  • 其實這個問題我已經在 stackoverflow 回答過一次,原回答在這里。

    不過就像前面說的,由于中國人常用的漢語和英語的文字并不會達到這種高度,所以這個方法對于中國人基本上是沒用的。

    2.1.14 setSubpixelText(boolean subpixelText)

    是否開啟次像素級的抗鋸齒( sub-pixel anti-aliasing )。

    次像素級抗鋸齒這個功能解釋起來很麻煩,簡單說就是根據程序所運行的設備的屏幕類型,來進行針對性的次像素級的抗鋸齒計算,從而達到更好的抗鋸齒效果。更詳細的解釋可以看這篇文章。

    不過,和前面講的字體 hinting 一樣,由于現在手機屏幕像素密度已經很高,所以默認抗鋸齒效果就已經足夠好了,一般沒必要開啟次像素級抗鋸齒,所以這個方法基本上沒有必要使用。

    2.1.15 setLinearText(boolean linearText)

    這個方法老實說我從沒用過,也始終沒有搞懂它是什么意思,就不強行裝逼了。把文檔中的解釋照搬過來,各位自己研究吧。

    Helper for setFlags(), setting or clearing the LINEARTEXTFLAG bit

    上面這句中提到的?LINEAR_TEXT_FLAG:

    Paint flag that enables smooth linear scaling of text.

    Enabling this flag does not actually scale text, but rather adjusts text draw operations to deal gracefully with smooth adjustment of scale. When this flag is enabled, font hinting is disabled to prevent shape deformation between scale factors, and glyph caching is disabled due to the large number of glyph images that will be generated.

    SUBPIXELTEXTFLAG should be used in conjunction with this flag to prevent glyph positions from snapping to whole pixel values as scale factor is adjusted.

    以上就是?Paint?的對文字的顯示效果設置類方法。下面介紹它的第二類方法:測量文字尺寸類。

    2.2 測量文字尺寸類

    不論是文字,還是圖形或?Bitmap,只有知道了尺寸,才能更好地確定應該擺放的位置。由于文字的繪制和圖形或?Bitmap?的繪制比起來,尺寸的計算復雜得多,所以它有一整套的方法來計算文字尺寸。

    2.2.1 float getFontSpacing()

    獲取推薦的行距。

    即推薦的兩行文字的 baseline 的距離。這個值是系統根據文字的字體和字號自動計算的。它的作用是當你要手動繪制多行文字(而不是使用 StaticLayout)的時候,可以在換行的時候給?y?坐標加上這個值來下移文字。

    paint.setTextAlign(Paint.Align.LEFT); canvas.drawText(text, 500, 150, paint); paint.setTextAlign(Paint.Align.CENTER); canvas.drawText(text, 500, 150 + textHeight, paint); paint.setTextAlign(Paint.Align.RIGHT); canvas.drawText(text, 500, 150 + textHeight * 2, paint);

    2.2.2 FontMetircs getFontMetrics()

    獲取?Paint?的?FontMetrics。

    FontMetrics?是個相對專業的工具類,它提供了幾個文字排印方面的數值:ascent,?descent,?top,?bottom,?leading。

    如圖,圖中有兩行文字,每一行都有 5 條線:top,?ascent,?baseline,?descent,?bottom。(leading并沒有畫出來,因為畫不出來,下面會給出解釋)

    • baseline: 上圖中黑色的線。前面已經講過了,它的作用是作為文字顯示的基準線。

    • ascent?/?descent: 上圖中綠色橙色的線,它們的作用是限制普通字符的頂部和底部范圍。?
      普通的字符,上不會高過?ascent?,下不會低過?descent?,例如上圖中大部分的字形都顯示在?ascent?和?descent?兩條線的范圍內。具體到 Android 的繪制中,?ascent?的值是圖中綠線和?baseline?的相對位移,它的值為負(因為它在?baseline?的上方);?descent?的值是圖中橙線和?baseline?相對位移,值為正(因為它在?baseline?的下方)。

    • top?/?bottom: 上圖中藍色紅色的線,它們的作用是限制所有字形( glyph )的頂部和底部范圍。?
      除了普通字符,有些字形的顯示范圍是會超過?ascent?和?descent?的,而?top?和?bottom?則限制的是所有字形的顯示范圍,包括這些特殊字形。例如上圖的第二行文字里,就有兩個泰文的字形分別超過了?ascent?和?descent?的限制,但它們都在?top?和?bottom?兩條線的范圍內。具體到 Android 的繪制中,?top?的值是圖中藍線和?baseline?的相對位移,它的值為負(因為它在?baseline?的上方);?bottom?的值是圖中紅線和?baseline?相對位移,值為正(因為它在?baseline?的下方)。

    • leading: 這個詞在上圖中沒有標記出來,因為它并不是指的某條線和?baseline?的相對位移。?leading?指的是行的額外間距,即對于上下相鄰的兩行,上行的?bottom?線和下行的?top?線的距離,也就是上圖中第一行的紅線第二行的藍線的距離(對,就是那個小細縫)。

    leading?這個詞的本意其實并不是行的額外間距,而是行距,即兩個相鄰行的?baseline?之間的距離。不過對于很多非專業領域,leading?的意思被改變了,被大家當做行的額外間距來用;而 Android 里的?leading?,同樣也是行的額外間距的意思。

    另外,leading?在這里應該讀作 "ledding" 而不是 "leeding" 哦。原因就不說了,我這越扯越遠沒邊了。

    FontMetrics?提供的就是?Paint?根據當前字體和字號,得出的這些值的推薦值。它把這些值以變量的形式存儲,供開發者需要時使用。

    • FontMetrics.ascent:float 類型。
    • FontMetrics.descent:float 類型。
    • FontMetrics.top:float 類型。
    • FontMetrics.bottom:float 類型。
    • FontMetrics.leading:float 類型。

    另外,ascent?和?descent?這兩個值還可以通過?Paint.ascent()?和?Paint.descent()?來快捷獲取。

    FontMetrics 和 getFontSpacing():

    從定義可以看出,上圖中兩行文字的 font spacing (即相鄰兩行的?baseline?的距離) 可以通過?bottom - top + leading?(top?的值為負,前面剛說過,記得吧?)來計算得出。

    但你真的運行一下會發現,?bottom - top + leading?的結果是要大于?getFontSpacing()?的返回值的。

    兩個方法計算得出的 font spacing 竟然不一樣?

    這并不是 bug,而是因為?getFontSpacing()?的結果并不是通過?FontMetrics?的標準值計算出來的,而是另外計算出來的一個值,它能夠做到在兩行文字不顯得擁擠的前提下縮短行距,以此來得到更好的顯示效果。所以如果你要對文字手動換行繪制,多數時候應該選取?getFontSpacing()?來得到行距,不但使用更簡單,顯示效果也會更好。

    getFontMetrics()?的返回值是?FontMetrics?類型。它還有一個重載方法?getFontMetrics(FontMetrics fontMetrics)?,計算結果會直接填進傳入的?FontMetrics?對象,而不是重新創建一個對象。這種用法在需要頻繁獲取?FontMetrics?的時候性能會好些。

    另外,這兩個方法還有一對同樣結構的對應的方法?getFontMetricsInt()?和?getFontMetricsInt(FontMetricsInt fontMetrics)?,用于獲取?FontMetricsInt?類型的結果。

    2.2.3 getTextBounds(String text, int start, int end, Rect bounds)

    獲取文字的顯示范圍。

    參數里,text?是要測量的文字,start?和?end?分別是文字的起始和結束位置,bounds?是存儲文字顯示范圍的對象,方法在測算完成之后會把結果寫進?bounds。

    paint.setElegantTextHeight(true);

    它有一個重載方法?getTextBounds(char[] text, int index, int count, Rect bounds),用法非常相似,不再介紹。

    2.2.4 float measureText(String text)

    測量文字的寬度并返回。

    canvas.drawText(text, offsetX, offsetY, paint); float textWidth = paint.measureText(text); canvas.drawLine(offsetX, offsetY, offsetX + textWidth, offsetY, paint);

    咦,前面有了?getTextBounds(),這里怎么又有一個?measureText()?

    如果你用代碼分別使用?getTextBounds()?和?measureText()?來測量文字的寬度,你會發現?measureText()?測出來的寬度總是比?getTextBounds()?大一點點。這是因為這兩個方法其實測量的是兩個不一樣的東西。

    • getTextBounds: 它測量的是文字的顯示范圍(關鍵詞:顯示)。形象點來說,你這段文字外放置一個可變的矩形,然后把矩形盡可能地縮小,一直小到這個矩形恰好緊緊包裹住文字,那么這個矩形的范圍,就是這段文字的 bounds。

    • measureText(): 它測量的是文字繪制時所占用的寬度(關鍵詞:占用)。前面已經講過,一個文字在界面中,往往需要占用比他的實際顯示寬度更多一點的寬度,以此來讓文字和文字之間保留一些間距,不會顯得過于擁擠。上面的這幅圖,我并沒有設置?setLetterSpacing()?,這里的 letter spacing 是默認值 0,但你可以看到,圖中每兩個字母之間都是有空隙的。另外,下方那條用于表示文字寬度的橫線,在左邊超出了第一個字母?H?一段距離的,在右邊也超出了最后一個字母?r(雖然右邊這里用肉眼不太容易分辨),而就是兩邊的這兩個「超出」,導致了?measureText()?比?getTextBounds()?測量出的寬度要大一些。

    在實際的開發中,測量寬度要用?measureText()?還是?getTextBounds()?,需要根據情況而定。不過你只要掌握了上面我所說的它們的本質,在選擇的時候就不會為難和疑惑了。

    measureText(String text)?也有幾個重載方法,用法和它大同小異,不再介紹。

    2.2.5 getTextWidths(String text, float[] widths)

    獲取字符串中每個字符的寬度,并把結果填入參數?widths。

    這相當于?measureText()?的一個快捷方法,它的計算等價于對字符串中的每個字符分別調用?measureText()?,并把它們的計算結果分別填入?widths?的不同元素。

    getTextWidths()?同樣也有好幾個變種,使用大同小異,不再介紹。

    2.2.6 int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)

    這個方法也是用來測量文字寬度的。但和?measureText()?的區別是,?breakText()?是在給出寬度上限的前提下測量文字的寬度。如果文字的寬度超出了上限,那么在臨近超限的位置截斷文字。

    int measuredCount; float[] measuredWidth = {0};// 寬度上限 300 (不夠用,截斷) measuredCount = paint.breakText(text, 0, text.length(), true, 300, measuredWidth); canvas.drawText(text, 0, measuredCount, 150, 150, paint);// 寬度上限 400 (不夠用,截斷) measuredCount = paint.breakText(text, 0, text.length(), true, 400, measuredWidth); canvas.drawText(text, 0, measuredCount, 150, 150 + fontSpacing, paint);// 寬度上限 500 (夠用) measuredCount = paint.breakText(text, 0, text.length(), true, 500, measuredWidth); canvas.drawText(text, 0, measuredCount, 150, 150 + fontSpacing * 2, paint);// 寬度上限 600 (夠用) measuredCount = paint.breakText(text, 0, text.length(), true, 600, measuredWidth); canvas.drawText(text, 0, measuredCount, 150, 150 + fontSpacing * 3, paint);

    breakText()?的返回值是截取的文字個數(如果寬度沒有超限,則是文字的總個數)。參數中,?text?是要測量的文字;measureForwards?表示文字的測量方向,true?表示由左往右測量;maxWidth?是給出的寬度上限;measuredWidth?是用于接受數據,而不是用于提供數據的:方法測量完成后會把截取的文字寬度(如果寬度沒有超限,則為文字總寬度)賦值給?measuredWidth[0]。

    這個方法可以用于多行文字的折行計算。

    breakText()?也有幾個重載方法,使用大同小異,不再介紹。

    2.2.7 光標相關

    對于?EditText?以及類似的場景,會需要繪制光標。光標的計算很麻煩,不過 API 23 引入了兩個新的方法,有了這兩個方法后,計算光標就方便了很多。

    2.2.7.1 getRunAdvance(CharSequence text, int start, int end, int contextStart, int contextEnd, boolean isRtl, int offset)

    對于一段文字,計算出某個字符處光標的?x?坐標。?start?end?是文字的起始和結束坐標;contextStart?contextEnd?是上下文的起始和結束坐標;isRtl?是文字的方向;offset?是字數的偏移,即計算第幾個字符處的光標。

    int length = text.length(); float advance = paint.getRunAdvance(text, 0, length, 0, length, false, length); canvas.drawText(text, offsetX, offsetY, paint); canvas.drawLine(offsetX + advance, offsetY - 50, offsetX + advance, offsetY + 10, paint);

    其實,說是測量光標位置的,本質上這也是一個測量文字寬度的方法。上面這個例子中,start?和?contextStart?都是 0,?end?contextEnd?和?offset?都等于?text.length()。在這種情況下,它是等價于?measureText(text)?的,即完整測量一段文字的寬度。而對于更復雜的需求,getRunAdvance()?能做的事就比?measureText()?多了。

    // 包含特殊符號的繪制(如 emoji 表情) String text = "Hello HenCoder \uD83C\uDDE8\uD83C\uDDF3" // "Hello HenCoder

    總結

    以上是生活随笔為你收集整理的HenCoder Android 开发进阶:自定义 View 1-3 drawText() 文字的绘制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    色欧美88888久久久久久影院 | 欧美日韩在线观看一区 | 国产成人一区二区三区电影 | 成人手机在线视频 | 欧美日韩不卡一区二区 | 国产成人精品一区二区在线 | 国产99久久久国产精品成人免费 | 国产99在线免费 | 日韩精品久久久久 | www免费视频com━ | 91av视频在线观看免费 | 国产破处在线视频 | 国产又粗又硬又长又爽的视频 | 日本资源中文字幕在线 | 人人澡人人干 | 日本中文一区二区 | 久久久高清一区二区三区 | 精品免费国产一区二区三区四区 | 久久国语 | 国产乱对白刺激视频不卡 | 日韩在线小视频 | 一级黄色a视频 | 亚洲成年片 | 五月婷婷六月丁香 | 国产69精品久久app免费版 | 男女激情免费网站 | 91久久奴性调教 | 欧美另类美少妇69xxxx | 中文字幕亚洲高清 | 丁香花在线观看免费完整版视频 | 久久久av免费 | 狠狠综合网 | 天天天天色综合 | 91视频91蝌蚪 | 人人干人人干人人干 | 久热香蕉视频 | 国产精品成人一区 | 在线免费观看黄色av | 黄色网www | 91成人区 | 欧美一区二区三区在线 | 天天操天天拍 | 精品a级片| 久久艹人人| 香蕉视频在线视频 | 久久久久综合精品福利啪啪 | 国产高清在线a视频大全 | 超碰97人人在线 | 亚洲jizzjizz日本少妇 | 99久久精品免费一区 | 国产精品一区二区在线观看 | 亚洲一级理论片 | 最近日韩中文字幕中文 | 亚洲aⅴ久久精品 | 五月婷婷久 | 久久久免费国产 | 久久久久久久电影 | 成人免费在线播放视频 | 欧美不卡视频在线 | 亚洲精品av中文字幕在线在线 | 欧美另类高潮 | 久久电影中文字幕视频 | 91视频在线自拍 | 亚洲成人家庭影院 | 国产玖玖精品视频 | www.色com| 国产高清亚洲 | 中文av资源站 | 久久永久免费视频 | 久久69精品久久久久久久电影好 | 亚洲精品午夜久久久 | www.狠狠色.com| 97视频在线看| 成人免费看视频 | 99视频黄| 黄色三几片 | 五月婷婷网站 | 亚洲黄色av网址 | 中文字幕人成乱码在线观看 | 91人网站 | 91手机视频 | 久色网 | 日韩视频在线播放 | 97免费公开视频 | 99精品欧美一区二区三区黑人哦 | 成人免费一级 | 婷婷精品国产一区二区三区日韩 | 又黄又刺激 | 亚洲一区二区三区精品在线观看 | 色吧av色av | 一级一级一片免费 | 国产视频综合在线 | 91色吧| 丁香九月激情综合 | 午夜在线免费视频 | 天天躁天天躁天天躁婷 | 91久久丝袜国产露脸动漫 | 伊人春色电影网 | 久久国产精彩视频 | 免费的成人av| 麻豆av一区二区三区在线观看 | 日日天天狠狠 | .国产精品成人自产拍在线观看6 | 四虎影视国产精品免费久久 | 麻豆国产精品永久免费视频 | zzijzzij亚洲日本少妇熟睡 | 国产成人精品一区二区三区免费 | 国产精品自产拍在线观看中文 | 在线黄色毛片 | 天堂av官网 | 欧美在线91 | 99久久er热在这里只有精品15 | 久久成人精品视频 | 国产精品久久久久久久久久免费 | 亚洲精品视频中文字幕 | 精品一区二区亚洲 | 在线视频99| 久久免费激情视频 | 久久国产系列 | 国内丰满少妇猛烈精品播 | 天天干夜夜夜操天 | 国产区免费| 国产xxxx| 一区二区三区在线播放 | 亚洲国产操 | 国产精品高潮呻吟久久久久 | 国产999免费视频 | 成年人免费在线观看网站 | 一区二区三区久久精品 | 免费a级毛片在线看 | 国产亚洲精品久 | 狠狠地日| a一片一级 | 国产精品国产三级国产专区53 | 欧美精品久久久久久久久免 | 久久看片网站 | 国产精品久久久久久久久久不蜜月 | 亚洲免费精品一区二区 | av解说在线观看 | 国内视频| 激情动态 | 丁香视频全集免费观看 | 毛片基地黄久久久久久天堂 | 超碰公开在线观看 | 91最新在线视频 | 亚洲一区视频免费观看 | 午夜av不卡 | 最近免费在线观看 | 久久久国产精品久久久 | 久久综合久久久 | 久久激五月天综合精品 | 91传媒视频在线观看 | 四虎国产 | 亚洲精品国产精品乱码在线观看 | 97超碰超碰 | 亚洲精区二区三区四区麻豆 | 91传媒免费观看 | 黄色小说18 | 一区二区三区日韩在线 | 久草免费在线视频 | 手机av在线免费观看 | www.av在线播放 | 五月婷婷中文网 | 黄色网中文字幕 | 日本韩国精品一区二区在线观看 | 久久精品国产一区二区三 | 蜜桃久久久 | 国产精品久久久久久久久软件 | 五月天高清欧美mv | 最新中文字幕在线观看视频 | 欧美污污网站 | 国产一区在线免费观看 | 天天综合久久 | 午夜骚影| 国产精品都在这里 | 久久综合给合久久狠狠色 | 91夫妻自拍| 国产精品网红直播 | 国产高清在线视频 | 免费看的黄色小视频 | 中文字幕免费高清 | 91日韩国产 | 久久久激情网 | 国产精品综合久久久 | 不卡的av电影 | 人人草网站 | 欧美一区二区三区激情视频 | 中文字幕免费国产精品 | 欧洲精品码一区二区三区免费看 | 免费一级片久久 | 欧美大片在线看免费观看 | 69国产盗摄一区二区三区五区 | 一性一交视频 | 日本久久免费电影 | 久草网站在线 | 久久综合久久综合这里只有精品 | 日韩免费网址 | 亚洲开心激情 | 国产群p | 综合婷婷久久 | 青春草免费视频 | 国产理论在线 | 婷婷5月激情5月 | 国产一区二区三区高清播放 | 麻豆 91 在线 | 久久精品视 | 色一级片 | 久久久久久网站 | 国产精品96久久久久久吹潮 | 99中文视频在线 | 91精品国产99久久久久久久 | 99视频这里有精品 | www日韩视频| 狠狠狠狠狠狠狠干 | 五月激情六月丁香 | 91高清不卡 | 日韩a在线 | 在线视频观看国产 | 麻豆成人精品视频 | 亚洲精品动漫久久久久 | 又色又爽的网站 | 亚洲精品国产精品久久99热 | 欧美精品做受xxx性少妇 | 欧美伦理一区二区三区 | 亚洲va欧美va人人爽 | 国产精品自产拍 | 少妇bbw撒尿 | 久久精品中文视频 | 久久久久免费精品视频 | 久久国产精品区 | 日韩中文字幕国产 | 国内精品久久久久影院男同志 | 国产精品精品久久久 | 亚洲综合成人专区片 | 免费黄在线看 | 午夜精品久久久99热福利 | 久久九九影视网 | 在线观看国产亚洲 | 国产精品高清在线观看 | 激情动态 | 99精品一区 | 97在线观看免费观看 | 18国产精品白浆在线观看免费 | 午夜神马福利 | 国产人成看黄久久久久久久久 | 成人黄色一级视频 | 天天天色综合a | 青青草国产在线 | 激情伊人五月天久久综合 | 天天操天天射天天爱 | 97超碰资源总站 | 日韩一区二区三区视频在线 | 香蕉影视| 日韩av高潮| 久久a久久| 国产又粗又猛又色又黄视频 | 五月天综合婷婷 | 日韩免费在线 | 精品无人国产偷自产在线 | 在线观看免费成人av | 久久精品国产免费看久久精品 | 国产精品mm | 亚洲高清视频一区二区三区 | 成人av影视| 久久精品五月 | 91精品国产91久久久久福利 | 日韩一级黄色大片 | 国产精品免费久久久 | 久久婷亚洲五月一区天天躁 | 日韩理论在线视频 | 国产精品久久久久av免费 | www.黄色 | 国语久久 | 欧美日韩在线免费视频 | 中文字幕有码在线播放 | 一级α片免费看 | 九九九九九九精品任你躁 | 亚洲国产中文字幕在线观看 | 久久久999| 黄网av在线| 国产精品99久久免费观看 | av资源免费在线观看 | 色综合天天| av激情五月| 亚洲成a人片在线www | 免费黄色特级片 | 96久久久 | 国产精品久久久久永久免费观看 | 91字幕 | 久久久久久久久黄色 | 97免费在线观看 | 精品久久影院 | 午夜精品久久久久久久久久久久久久 | 国产精品va视频 | 久久伊人五月天 | 日日夜夜天天久久 | 成年人国产精品 | 91视频在线免费下载 | 日韩中文字幕一区 | 成人va在线观看 | 国产在线欧美日韩 | 三级在线视频播放 | 美女视频黄色免费 | 免费黄色在线网址 | 久热超碰 | 国产精品综合久久久久 | 99视频在线免费播放 | 日韩一级精品 | 97色在线| 色婷av| 国产高清无线码2021 | 粉嫩高清一区二区三区 | 狠狠的操狠狠的干 | 亚州精品视频 | 久久人人爽人人 | 天天色天天爱天天射综合 | 玖玖在线播放 | 91看片在线播放 | 福利一区二区三区四区 | 国产精品观看视频 | 久久露脸国产精品 | 亚洲国产人午在线一二区 | 国产日韩中文在线 | 午夜 在线 | 日韩在线电影一区二区 | 伊人天天综合 | 婷婷综合亚洲 | 国产在线观看免费av | 国产精品久久久久av | 精品国产精品久久 | 91传媒视频在线观看 | 99视频国产精品 | 日韩午夜在线 | 欧美激情在线网站 | 高清在线一区二区 | 深爱激情综合网 | 手机av在线不卡 | 亚洲天堂激情 | 天天看天天操 | 婷婷综合久久 | 久久草网站 | 三级黄在线| 黄色一级大片在线免费看国产一 | 黄色在线观看免费网站 | www.888av| 江苏妇搡bbbb搡bbbb | 91欧美精品 | 狠狠躁18三区二区一区ai明星 | 麻豆免费在线播放 | 日韩网站在线免费观看 | 91精品国产99久久久久久久 | 黄色的视频 | 国产精品热视频 | 久久免费视频6 | 精品亚洲成人 | 久久麻豆精品 | 亚洲国产日韩一区 | 黄a在线观看| 日韩激情第一页 | 日韩精品播放 | 丁香电影小说免费视频观看 | 蜜臀91丨九色丨蝌蚪老版 | 欧美日韩在线观看视频 | 欧美a级免费视频 | 国产一区二区三区四区大秀 | 99热这里只有精品1 av中文字幕日韩 | 国产美女免费 | 欧美美女激情18p | 一级免费观看 | 亚洲专区在线视频 | 久草在线免费资源站 | 又色又爽又黄高潮的免费视频 | 国产精品一区二区电影 | 中文字幕国产精品 | 天天综合婷婷 | 国产精品美女视频网站 | 国产精品久久久久久久久蜜臀 | 中文字幕在线视频一区 | 成人免费亚洲 | 日批在线观看 | 丁香婷婷色 | 超碰免费观看 | 99久久久国产精品美女 | 999毛片| 精品99在线 | 精品久操 | 国产免费又粗又猛又爽 | 久久精品国产一区二区 | 天天天综合网 | 9在线观看免费高清完整版在线观看明 | 视频99爱 | 香蕉视频91| 操操操av | 久久久免费毛片 | 中文字幕亚洲在线观看 | 日躁夜躁狠狠躁2001 | 中文字幕婷婷 | 成人av影视观看 | 亚洲精品啊啊啊 | 欧美久久精品 | 韩国精品在线观看 | 午夜 免费| 国产二区免费视频 | 国产91精品久久久久 | 在线影院av | 黄色毛片在线看 | 免费观看十分钟 | 日韩欧美在线高清 | 黄色的视频网站 | 久久综合影音 | 欧美 日韩 成人 | 亚洲精品女 | 99久久影视| 亚洲免费小视频 | 亚洲九九九在线观看 | 日韩一区在线播放 | 中文视频一区二区 | 99久久99视频只有精品 | 99精品欧美一区二区 | 亚洲春色奇米影视 | 久久网页 | a视频免费看 | 久久久久久久久久久电影 | 久久9视频 | 人人爽人人爽人人爽 | av网站在线观看播放 | 国产精品久久久一区二区三区网站 | 精品国产乱码久久久久久1区2匹 | 欧美久久久影院 | 国产精品自在欧美一区 | 欧美 亚洲 另类 激情 另类 | 伊甸园av在线| 久久一区二区三区四区 | 99高清视频有精品视频 | 日韩精品高清视频 | av在线专区 | 九九视频这里只有精品 | 一本色道久久综合亚洲二区三区 | 久久久久亚洲天堂 | 狠狠狠综合 | 天天天天天天天天操 | 日韩,中文字幕 | 色a在线观看 | 日韩欧美aaa| 人人草人 | 久久综合婷婷 | av网站手机在线观看 | 美女视频久久 | 国产一级黄 | 欧美精品在线观看免费 | 日韩理论片中文字幕 | 在线看国产一区 | 激情久久久久久久久久久久久久久久 | 国产成人av免费在线观看 | 中文字幕在线观看免费高清完整版 | 美女露久久 | 亚洲精品视频免费在线观看 | 韩国精品福利一区二区三区 | 亚洲精品国产品国语在线 | 69国产盗摄一区二区三区五区 | 国产精品免费在线播放 | 国产中文字幕视频 | 久久久精品国产一区二区 | av电影亚洲 | 在线亚洲午夜片av大片 | 99在线精品免费视频九九视 | 免费中文字幕视频 | 婷婷伊人综合亚洲综合网 | 欧美va电影 | 操一草 | 国产精品99久久久久久宅男 | 欧美性色综合网 | 国产精品久久久久久久久久新婚 | 日韩综合视频在线观看 | 国产中文视 | 久久这里只精品 | 中文在线字幕免费观看 | 久久精品麻豆 | 最近日本mv字幕免费观看 | 国产精品美乳一区二区免费 | 福利视频一区二区 | jizzjizzjizz亚洲| 亚洲v欧美v国产v在线观看 | 日日夜夜天天久久 | 亚洲国产精品电影在线观看 | 久久视了 | 国产精品亚洲精品 | 日本黄区免费视频观看 | 韩国视频一区二区三区 | 免费进去里的视频 | 亚洲九九九在线观看 | 日韩艹| 伊人五月在线 | 日韩网站一区二区 | 欧美精品中文 | 五月亚洲综合 | 二区精品视频 | 美女黄视频免费看 | 成人av免费看 | 久久人人爽爽人人爽人人片av | 中文字幕视频观看 | 99一区二区三区 | 丁香视频免费观看 | 欧美久久久影院 | 久草在线观看资源 | 久久国产精品精品国产色婷婷 | 日韩一级黄色片 | 99精品视频免费看 | 亚洲成人av免费 | 久久婷婷久久 | 美女黄频免费 | 69国产成人综合久久精品欧美 | 日韩二区在线 | 麻豆精品国产传媒 | 精品国产免费一区二区三区五区 | 久久精品播放 | 国产女做a爱免费视频 | 久操伊人 | 国产91对白在线 | 一区二区三区免费看 | 国产午夜三级一区二区三 | 国产精品三级视频 | 亚洲国产伊人 | 99视频黄 | 国产精品久久久免费看 | 嫩草伊人久久精品少妇av | 成人国产精品入口 | 91热视频在线观看 | 欧美一区二区在线刺激视频 | 日韩性网站 | 亚洲午夜激情网 | 欧美巨大荫蒂茸毛毛人妖 | 日韩av免费观看网站 | 成人黄色小说视频 | 精品中文字幕视频 | 精品国产一区二区三区久久久蜜臀 | 在线观看免费版高清版 | 在线色亚洲 | 天天综合日 | 久久国产一二区 | 国产精品资源网 | 中文字幕一区二区三区四区在线视频 | 成人免费在线电影 | 亚洲人成综合 | 国产视频一区在线播放 | 在线中文视频 | 黄色aaa级片 | 亚洲一区精品二人人爽久久 | 日韩午夜网站 | 精品在线不卡 | 不卡的av中文字幕 | 337p欧美| 91九色在线播放 | 黄色av免费| 在线成人免费电影 | 日本黄色黄网站 | 日本一区二区三区视频在线播放 | 精品国产伦一区二区三区观看方式 | 麻豆久久一区 | 97成人精品视频在线播放 | 日韩特黄一级欧美毛片特黄 | 亚洲色图美腿丝袜 | 精品在线免费视频 | 国产视频 亚洲视频 | 999男人的天堂 | 激情五月播播久久久精品 | 久久天天拍 | 久精品在线 | 2022久久国产露脸精品国产 | 久久精品国产亚洲aⅴ | 麻豆视频免费 | 在线你懂的视频 | 99视频黄 | 色多多视频在线观看 | 亚洲第一中文字幕 | 99免费在线| 337p欧美 | 国产91精品一区二区麻豆网站 | 黄色的视频网站 | 日韩高清精品一区二区 | av免费看在线| 成人黄大片视频在线观看 | 毛片在线网 | 色综合咪咪久久网 | 精品国产一区二区三区在线观看 | 精品福利av| 9ⅰ精品久久久久久久久中文字幕 | 久草影视在线观看 | 91精品综合| 中文字幕在线一区二区三区 | 美女视频黄色免费 | 国产黄色电影 | 97国产情侣爱久久免费观看 | 日韩欧美一区二区三区免费观看 | 97av在线| 国产精品国产三级国产 | 久久国产精品影片 | 91精品成人久久 | 国产一区二区久久久久 | 国产免费激情久久 | 成人激情开心网 | 国产精品毛片一区二区 | 亚洲一区二区精品视频 | 婷婷激情五月综合 | 国产精品国产三级在线专区 | 精品亚洲二区 | 国产不卡视频在线播放 | 免费看黄网站在线 | 嫩嫩影院理论片 | 国产精品久久久久久久午夜片 | 免费福利片2019潦草影视午夜 | 91麻豆精品国产91久久久久久 | 四虎在线免费观看视频 | 日本一区二区三区免费观看 | 成人在线视频免费观看 | 色婷婷欧美 | 色网站国产精品 | 国产a级片免费观看 | 婷婷去俺也去六月色 | 伊人色综合久久天天 | 久草在线免费电影 | 伊人春色电影网 | 波多野结衣在线观看视频 | 亚洲丝袜中文 | 日韩色视频在线观看 | 婷婷色网 | 黄色三级av | 97超在线 | 久久久久久国产精品美女 | 久久久免费网站 | 亚洲粉嫩av | 99r国产精品 | 亚洲天天 | 韩国一区二区av | 在线观看一区 | 国产在线免费 | 欧美性视频网站 | 色婷婷精品大在线视频 | 最近日韩免费视频 | 色婷婷在线播放 | 999成人网 | 欧美在线视频日韩 | 9幺看片 | 亚州精品在线视频 | 国产精品女教师 | 探花视频网站 | 久久午夜羞羞影院 | 中文字幕在线观看91 | 三级黄色网址 | 在线成人欧美 | 波多野结衣一区二区 | 美女视频国产 | 九九九热精品 | 激情偷乱人伦小说视频在线观看 | 国产中文字幕在线观看 | 日韩精品免费专区 | 大胆欧美gogo免费视频一二区 | 精品美女国产在线 | 黄色大全在线观看 | 69av久久| 麻豆va一区二区三区久久浪 | 波多野结衣在线观看一区 | 日韩一二三区不卡 | 国产在线播放一区 | 中文欧美字幕免费 | 激情久久影院 | 久久久久久久精 | 在线观看中文字幕亚洲 | 521色香蕉网站在线观看 | 国产成人在线精品 | 成人黄色电影免费观看 | 911在线| 亚洲精品美女久久17c | 一区av在线播放 | 亚洲蜜桃在线 | 国产在线永久 | 国产一区在线观看视频 | 色综合在 | 日韩中文字幕在线不卡 | 黄色.com| 天天干天天射天天爽 | 亚洲一区视频免费观看 | 欧美激情精品久久久久 | 免费观看高清 | 99热99re6国产在线播放 | 在线视频在线观看 | 国产精品一区二区三区免费看 | 亚洲网站在线看 | 九九九热精品 | 欧美综合在线观看 | 免费黄色av电影 | 四虎在线免费观看视频 | 九九在线国产视频 | 精品电影一区二区 | 中文字幕在线观看免费观看 | 久久理论片 | 亚洲区另类春色综合小说 | 久久国产精品系列 | 欧美电影黄色 | 麻豆视频在线播放 | 亚洲一区二区三区精品在线观看 | 99热这里只有精品1 av中文字幕日韩 | 国产在线观看av | 特级西西444www高清大视频 | 96久久久 | 97超碰中文 | 美女视频久久黄 | 狠狠色噜噜狠狠狠狠2022 | 又黄又爽又色无遮挡免费 | 97在线看| 亚洲v欧美v国产v在线观看 | 日韩高清精品一区二区 | 久草电影在线观看 | 在线免费黄色av | 69国产盗摄一区二区三区五区 | 波多野结衣视频一区 | 欧洲高潮三级做爰 | 超碰97国产在线 | 久草久草在线 | 在线欧美日韩 | 97在线观看免费观看高清 | 久久 亚洲视频 | 亚洲国产精品免费 | 婷婷色视频 | 国产精品麻 | 国产精品一区电影 | 色多多污污在线观看 | 国产亚洲精品bv在线观看 | 欧美色综合天天久久综合精品 | 99久精品视频 | 日韩女同一区二区三区在线观看 | 91精品国自产在线观看 | 日韩欧在线 | 国产精品99精品 | 午夜黄色影院 | 亚洲一级黄色av | 久久一区91| av在线影视 | 在线观看免费视频 | 在线看一级片 | 日韩高清黄色 | 亚洲人视频在线 | 精品久久国产精品 | 成人免费观看网站 | 日本中文字幕在线观看 | 97日日碰人人模人人澡分享吧 | 久久精品99北条麻妃 | 亚洲最大成人免费网站 | 手机成人在线 | 人人看看人人 | 亚洲精品高清在线 | 激情视频免费观看 | av在线播放中文字幕 | 久久成人精品电影 | 久久精品成人欧美大片古装 | 亚洲免费资源 | 999久久国产 | 亚洲视屏在线播放 | 精品国内| 国产在线播放一区二区 | 久久视频精品在线观看 | 成人一区不卡 | 性色av免费观看 | 国产黄色大片免费看 | 最新国产中文字幕 | 人人干人人干人人干 | 精品久久久久久久久久岛国gif | www日韩欧美 | 日日精品 | 亚洲综合视频在线观看 | 久久国内精品99久久6app | 三级黄色在线观看 | 国产精品网在线观看 | 亚洲激情六月 | 国产五月婷婷 | 国产第一页在线播放 | 激情五月综合 | 狠狠狠狠狠狠操 | 91av在线免费视频 | av黄色影院 | 狠狠色噜噜狠狠狠合久 | 亚洲情婷婷 | 99精品视频在线播放观看 | 91女神的呻吟细腰翘臀美女 | 五月婷婷激情综合 | 成人中文字幕在线观看 | 欧美精品久久久久久久久久久 | 国产在线精品一区二区 | 麻豆传媒视频在线 | av千婊在线免费观看 | 8090yy亚洲精品久久 | 91av小视频 | 久久亚洲在线 | 香蕉在线观看视频 | 国产精品久久久久影视 | 免费在线观看亚洲视频 | 黄色电影在线免费观看 | 三级黄色网络 | 女人魂免费观看 | 在线观看视频色 | 天天操天天操天天操天天 | 日本最新中文字幕 | 丁香五婷 | 亚洲精品美女视频 | 日本特黄特色aaa大片免费 | 丁香婷婷激情网 | 一区在线电影 | 婷婷激情综合五月天 | 免费久草视频 | 免费av片在线 | 综合色伊人 | 欧美精品视| 免费av试看 | 99久久99视频 | 91精品视频播放 | 国产美女无遮挡永久免费 | 欧美激情视频在线观看免费 | 天天操天天玩 | 亚洲黄色av一区 | 久久97精品 | 看黄色.com | 日韩偷拍精品 | 蜜桃av人人夜夜澡人人爽 | 国产69精品久久久久久 | 99视频网站| 国产精品免费一区二区三区在线观看 | 国产精品99免费看 | 奇米影视8888| 青青射| 中文字幕色网站 | zzijzzij亚洲成熟少妇 | 成人免费看片98欧美 | 日韩免费高清在线观看 | 九九久久免费 | 我要看黄色一级片 | 天天插日日操 | 亚洲综合成人婷婷小说 | 国产伦精品一区二区三区照片91 | 欧美日本国产在线观看 | 亚洲精品乱码久久久久久蜜桃欧美 | 97在线播放| 96av在线视频 | 亚洲精品午夜视频 | 日本黄色免费网站 | 久久国产免费 | 亚洲激情综合 | 国产一级电影网 | 色综合天天综合在线视频 | 国产在线999 | 欧美在线观看视频 | 欧洲精品久久久久毛片完整版 | 五月激情片 | 欧美日韩三级在线观看 | 国产精品欧美久久久久天天影视 | 亚洲免费观看视频 | 国产精品亚洲精品 | 麻豆国产精品va在线观看不卡 | 日韩精品视频一二三 | av在线官网 | 天天天天射 | 欧美日韩精品网站 | 亚洲最新av在线 | 国产清纯在线 | 亚洲综合激情五月 | 国产香蕉视频在线观看 | 91精品国产91久久久久久三级 | 一本一道波多野毛片中文在线 | 久久亚洲人 | 国产精品18久久久久久久久 | 午夜精品福利在线 | 亚洲高清视频在线播放 | 亚洲成人av片在线观看 | 成 人 黄 色 视频 免费观看 | 久久婷婷国产色一区二区三区 | 国产字幕在线看 | 国产一级二级在线播放 | 久久久久免费视频 | 国产一区观看 | 国产一区欧美日韩 | 美女视频免费一区二区 | 丁香婷婷久久 | 午夜天使 | 国内精品久久久久影院日本资源 | 天天操天天摸天天爽 | 国产一二区免费视频 | 免费网站污 | 国产成免费视频 | 香蕉视频导航 | 91亚洲永久精品 | 18国产精品白浆在线观看免费 | 久免费 | 成人一级片免费看 | 久久99中文字幕 | 国产91精品看黄网站在线观看动漫 | 国产精品久久久久久久久久久久久久 | 久久综合色婷婷 | 亚州精品在线视频 | 国产精品久久久久影视 | www.香蕉视频| 欧美精品乱码久久久久 | 欧美韩国日本在线 | 久久成人国产 | 免费观看一级视频 | 不卡中文字幕av | 成年人在线视频观看 | 国产999免费视频 | 亚洲欧美日本一区二区三区 | 免费看污污视频的网站 | 欧美久草网| 一区二区三区在线观看 | 天天视频色 | 91综合视频在线观看 | www日韩| 婷婷国产v亚洲v欧美久久 | 国产小视频福利在线 | 日韩特黄av | av中文字幕在线观看网站 | 亚洲激情婷婷 | 国产成人一区三区 | 国产偷国产偷亚洲清高 | 日韩av午夜 | 色偷偷网站视频 | 午夜精品电影 | 国产精品美女久久久久久免费 | 色偷偷人人澡久久超碰69 | 黄色亚洲片 | 国产精品99爱 | 超碰公开97 | 一区二区不卡 | 久久精品国产亚洲精品2020 | 蜜臀av在线一区二区三区 | 天天天在线综合网 | 久草精品视频在线播放 | 天天综合视频在线观看 | 特级毛片在线免费观看 | 97在线影视| 久久99视频精品 | 中文字幕人成乱码在线观看 | 激情久久久 | 国产精品亚州 | 婷婷在线视频观看 | 亚洲天堂社区 | 日韩精品一区电影 | 午夜av影院 | 免费看麻豆| 久久九精品| 天堂av在线免费观看 | 99成人精品 | www178ccom视频在线 | 欧美日韩精品影院 | 国产精品麻豆一区二区三区 | 亚洲一级免费电影 | 天天操比 | 国产一卡二卡在线 | 久一在线 | 日韩色中色 | 欧美日一级片 | 久久精品综合网 | 伊人首页 | 久久婷婷五月综合色丁香 | 天天天干夜夜夜操 | 91九色国产蝌蚪 | 久热电影| 69国产盗摄一区二区三区五区 | 97在线看 | 久久免费视频在线观看6 | 超碰在线观看av.com | 国产精品美女久久久久久免费 | 久草91视频 | 91精品在线免费观看视频 | 久久精品xxx| 国产精品资源在线观看 | 精品视频 | 成人四虎| 精一区二区 | 日韩中文字幕免费视频 | 日韩三区在线 | 欧美日韩在线视频一区二区 | 国产精品麻豆果冻传媒在线播放 | 亚洲人xxx | 国产成人一区二区三区影院在线 | 丁香资源影视免费观看 | 色婷婷国产 | 亚洲精品乱码久久久一二三 | 日韩中文在线电影 | 国产高清免费在线观看 | 五月婷婷色丁香 | 91香蕉国产在线观看软件 | 香蕉视频国产在线 | 久久激情视频 久久 | 黄色aaaaa| 日韩免费观看一区二区 | 六月丁香综合 | 91成人网页版 | 国产精品精品国产 | 国产日韩中文字幕在线 | 最新国产福利 | 久久99国产一区二区三区 |