日韩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() 文字的绘制的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    国产999精品久久久 免费a网站 | 欧美色精品天天在线观看视频 | 日韩视频中文 | 中文超碰字幕 | 在线观看黄色小视频 | 国产精品美女久久久久久久久久久 | 777奇米四色 | 2020天天干夜夜爽 | 激情av综合| 日韩高清www| 天天干天天操天天干 | 青青河边草免费视频 | 国产h片在线观看 | 午夜精品一区二区三区免费视频 | 国产精品永久免费观看 | 亚洲精品videossex少妇 | 亚洲成人av电影在线 | 精品视频不卡 | 精品视频资源站 | 毛片基地黄久久久久久天堂 | av大片免费在线观看 | 天天亚洲 | 911国产| av在线永久免费观看 | 99色网站| 亚洲精品播放 | 伊人久久在线观看 | 亚洲一区二区天堂 | 久草在线看片 | 黄色亚洲在线 | 色综合婷婷久久 | www.av免费观看 | 欧美色黄 | 免费看污在线观看 | 中文字幕精品三区 | 超级碰碰视频 | 成人aaa毛片 | 国际精品久久 | 亚洲色图美腿丝袜 | 久久久91精品国产一区二区三区 | 2020天天干天天操 | 99热这里只有精品在线观看 | 婷婷六月天丁香 | 在线成人免费电影 | 欧美成人精品欧美一级乱 | 毛片a级片| 去看片| 2023av| 福利电影久久 | 夜色在线资源 | 久草在线电影网 | 国产剧情久久 | av成人免费观看 | 亚洲精品国精品久久99热 | 欧美最猛性xxxxx(亚洲精品) | 精品一区二区在线免费观看 | 国产精品不卡av | 青青河边草观看完整版高清 | 免费中文字幕在线观看 | 玖玖视频网 | 久久人人爽人人爽人人片av软件 | 国产精品18久久久久久久网站 | 免费日p视频| 成片免费 | 麻豆传媒视频在线播放 | 日日日操 | 日本69hd| 日韩高清片 | 日日日操操 | 欧美日韩精品在线观看 | 亚洲精品国偷拍自产在线观看 | 在线观看av中文字幕 | 日韩精品免费一区 | 欧美日韩在线观看一区二区三区 | 色天天久久 | 91视频网址入口 | wwxxx日本| 日韩av五月天 | 手机在线看片日韩 | 国产小视频在线观看 | 久久精品视频在线观看 | avav99| 亚洲国产中文字幕 | 在线 你懂| 深夜激情影院 | 青青五月天| 国产麻豆视频 | 日本在线观看黄色 | 国产麻豆视频网站 | 久久精品久久精品久久精品 | 久久经典国产 | 国产1区2 | 亚洲国产精品人久久电影 | 激情欧美xxxx | 九九亚洲精品 | 欧美日韩高清在线观看 | 国产精品一区二区在线观看 | 五月综合激情 | 日韩av网页 | 毛片网站在线 | 91爱看片 | 黄色aaa级片| 91九色成人蝌蚪首页 | 中文字幕一区av | 久久九九精品 | 亚洲国产精品va在线看黑人动漫 | 国产精品 日韩精品 | 99久久婷婷国产综合精品 | 国产又粗又猛又黄视频 | 在线成人免费 | 日韩av看片 | 国产精品视频免费在线观看 | 超碰最新网址 | 亚洲成人av电影在线 | www.夜夜干.com | 国产一区免费在线观看 | 久久视频国产精品免费视频在线 | 操处女逼 | 国产视频 亚洲视频 | 99久久日韩精品视频免费在线观看 | 亚洲精品福利在线观看 | 欧美狠狠操 | 国内精品久久影院 | 亚洲一区二区麻豆 | 丁香花在线观看免费完整版视频 | 久久色在线观看 | 日韩激情小视频 | 91在线精品一区二区 | 欧美日韩不卡在线视频 | 国产精品免费大片视频 | 成人av资源在线 | 91av手机在线 | 亚洲日韩欧美视频 | 在线 日韩 av | 九九激情视频 | 在线观看av麻豆 | 日韩免费视频在线观看 | 国产尤物视频在线 | 天天射天天色天天干 | 日韩中午字幕 | 久久婷婷一区 | 在线日韩精品视频 | 精品日韩在线一区 | 精品国产黄色片 | 韩国av电影在线观看 | 欧日韩在线 | 夜夜嗨av色一区二区不卡 | 三级视频日韩 | 在线观看国产中文字幕 | 国产丝袜 | 亚洲一区欧美精品 | 国产精品久久久777 成人手机在线视频 | 国产精品大片免费观看 | 久久久私人影院 | 成人午夜精品久久久久久久3d | 97精品国产97久久久久久粉红 | 久久一视频 | 超碰成人网| 欧美小视频在线观看 | 婷婷色站 | 国产精品美女www爽爽爽视频 | 91精品在线观看入口 | 精品超碰| 一区二区三区四区五区在线 | av大片网址| 成人欧美一区二区三区在线观看 | 国产精品久久99精品毛片三a | 91av电影网| 欧美日韩高清一区二区 国产亚洲免费看 | 午夜私人影院 | 欧美日韩91 | 久久久久久美女 | 五月婷婷一区二区三区 | 日韩精品 在线视频 | 成人一级影视 | 91丨九色丨丝袜 | va视频在线观看 | 欧美一级片 | 久久成人国产精品 | 黄色大片中国 | 日韩精品一区二区在线 | 久久久精品小视频 | 99在线热播精品免费99热 | 婷婷丁香六月天 | 久久久受www免费人成 | japanesexxxhd奶水| 国产精品完整版 | 精品在线一区二区 | 91精品亚洲影视在线观看 | 日本久久成人 | 精品1区2区3区 | 国产免费影院 | 五月婷久久 | 五月宗合网 | 91资源在线免费观看 | 男女拍拍免费视频 | 成人观看视频 | 中文字幕一区二区在线播放 | 国产亚洲免费观看 | 日韩久久精品一区 | 精品视频一区在线 | 日韩精品一区二区三区丰满 | 色欧美视频 | 国产精品黄色av | 高清在线观看av | 9999精品 | www.久久99 | 日韩视频中文字幕在线观看 | 九九热在线精品 | 欧美日韩一区三区 | 日日夜夜人人精品 | 国产在线色视频 | 中文字幕日韩在线播放 | 国产中文视 | 日韩在线视频免费播放 | 蜜臀av性久久久久av蜜臀三区 | 911国产在线观看 | 色婷婷av一区 | av免费线看 | 青青草华人在线视频 | 91精品91 | 91网址在线看 | 在线观看免费观看在线91 | 超碰人人干人人 | 久久综合色8888 | 成人一区不卡 | 国产资源网 | 久久99九九99精品 | 五月婷婷色 | 国产激情小视频在线观看 | 91香蕉视频污在线 | 国产黄色免费电影 | 国产亚洲免费观看 | 久久免费激情视频 | 日韩天堂在线观看 | 在线国产日韩 | 91麻豆免费版 | 91亚洲精品久久久蜜桃 | 亚洲精品动漫久久久久 | 天天干人人干 | 五月婷网| caobi视频 | 最近高清中文在线字幕在线观看 | 亚洲黄色网络 | 韩日在线一区 | 日日夜av| 91精品毛片 | 日日草av| 久久免费99精品久久久久久 | 欧美日韩亚洲一 | 精品国产一区二区三区四区在线观看 | 日韩精品一区二区三区电影 | 9797在线看片亚洲精品 | 国产一区视频导航 | 国产一级免费电影 | www.日本色 | 日韩av播放在线 | 久久精品综合一区 | 欧美亚洲成人xxx | 91精品对白一区国产伦 | 国产福利免费在线观看 | 91天堂素人约啪 | 日韩影视精品 | 国产午夜在线 | 国产精品丝袜久久久久久久不卡 | av一级片| 人人爽人人爱 | 97国产在线观看 | 综合在线色 | 久久久免费高清视频 | 国产96视频| 一级免费观看 | 久久免费精品视频 | 精品国产免费人成在线观看 | 色伊人网| 色综合天天综合网国产成人网 | 国产精品一码二码三码在线 | 在线视频日韩一区 | 日本最新高清不卡中文字幕 | 亚洲成人动漫在线观看 | 久久午夜免费视频 | 欧美精品乱码久久久久久 | 91欧美精品 | 中文在线免费观看 | 91久久一区二区 | 在线观看的a站 | 国产午夜精品一区二区三区嫩草 | 美女视频久久黄 | 欧美在线1区 | 中文久久精品 | 国产精品麻豆视频 | 精品亚洲一区二区 | 久久精品久久久久久久 | 亚洲成av人影院 | av网站在线免费观看 | 久久精品96 | 国产不卡精品视频 | 成人手机在线视频 | 九九九电影免费看 | 色综合网在线 | 深爱激情五月婷婷 | 99久久99热这里只有精品 | 91精选在线 | 久久精品一区二区三区视频 | 中文乱码视频在线观看 | 国产成视频在线观看 | 人人精品 | 亚洲国产精彩中文乱码av | 激情久久综合 | 亚洲精品美女久久久久网站 | 99一区二区三区 | 国产录像在线观看 | 国产视频欧美视频 | 久操伊人| 欧美一级片在线免费观看 | 亚洲精品国产精品乱码不99热 | 免费看片网页 | 亚洲黄色免费网站 | 黄网在线免费观看 | 国产日产精品一区二区三区四区的观看方式 | 国产在线色站 | 国产午夜精品福利视频 | 天天综合网~永久入口 | 99热国产在线 | 在线播放国产一区二区三区 | 在线视频 成人 | 又色又爽又激情的59视频 | 久草在线免费在线观看 | 97在线公开视频 | 精品一区av| 亚洲综合成人在线 | 国产一区二区三区高清播放 | 91精品国自产拍天天拍 | 国产一区二区视频在线播放 | 欧美日韩久久 | 国产91精品高清一区二区三区 | 黄色一级大片在线免费看国产一 | 91亚洲视频在线观看 | 久久久福利影院 | 亚洲欧美一区二区三区孕妇写真 | 国产在线观看免费 | 福利视频第一页 | a极黄色片 | 国产一区免费看 | 丁香花在线视频观看免费 | 五月婷婷综合在线观看 | 免费av网站在线看 | 欧美激情第八页 | 国产成人一区三区 | 免费看成年人 | 婷婷色在线视频 | a天堂一码二码专区 | 久章草在线 | 五月婷婷丁香激情 | 狠狠撸电影 | 久久伊人精品天天 | 日日摸日日添夜夜爽97 | www.xxxx变态.com | 91麻豆视频 | 欧美成人亚洲 | 成人精品久久 | 五月婷婷综合激情网 | 国产一卡久久电影永久 | 国产精品久久久久9999 | 亚洲综合在线五月 | 国产精品破处视频 | 精品黄色视 | 国产又粗又猛又爽 | 激情五月在线视频 | 亚洲另类xxxx | 精品影院一区二区久久久 | 91黄色免费网站 | 亚洲91网站 | 999成人| 久久怡红院 | 蜜臀精品久久久久久蜜臀 | av电影在线免费 | 国产福利电影网址 | 91精品国产电影 | 欧美性做爰猛烈叫床潮 | 欧美精品一级视频 | 久久久性 | 在线观看网站你懂的 | 日本在线中文在线 | 麻豆国产露脸在线观看 | www.xxxx欧美 | 在线免费91| 在线观看亚洲精品视频 | 国产精品白丝jk白祙 | free. 性欧美.com | 国产亚洲精品久久久久久久久久久久 | 欧美日韩精品区 | 五月婷香蕉久色在线看 | 亚洲午夜久久久久久久久 | 国产69精品久久99的直播节目 | 91传媒激情理伦片 | 日韩在线免费高清视频 | 深爱五月激情五月 | 免费看一级黄色大全 | 成人丝袜 | av资源免费观看 | 久久久免费看视频 | 亚洲视频大全 | 三级动图| 欧美日韩aaaa | 五月天,com | www欧美色 | 免费久久99精品国产婷婷六月 | 日日干日日色 | 国产精品ssss在线亚洲 | 综合久久影院 | 亚洲综合在线播放 | 综合网天天射 | 久久综合影院 | 欧美另类高潮 | 免费国产在线视频 | 国产精品日韩高清 | 国产999精品久久久久久 | 久久久久在线视频 | 日韩av伦理片 | 国产 日韩 欧美 中文 在线播放 | 亚洲第一中文网 | 国产色在线 | 国产黑丝袜在线 | av在线a| 五月婷婷视频在线观看 | 激情丁香5月| 国产男男gay做爰 | 色激情五月 | 久久96国产精品久久99漫画 | 国产小视频免费在线观看 | 一区二区三区电影大全 | 久久www免费人成看片高清 | 亚洲aⅴ乱码精品成人区 | 国产一区二区在线播放视频 | 玖玖玖影院 | 热久久99这里有精品 | 成人网在线免费视频 | 亚洲一区美女视频在线观看免费 | 国产精品人成电影在线观看 | 成年人在线免费看视频 | 国产小视频精品 | 日本深夜福利视频 | 国产伦理久久精品久久久久_ | 色在线亚洲 | 久久久久国产一区二区三区 | 亚洲精品视频在线观看免费视频 | 亚洲 中文 在线 精品 | 91麻豆精品国产91久久久无限制版 | 国产黄色成人av | 国产你懂的在线 | 中文字幕影片免费在线观看 | 久久久久久国产精品免费 | 免费在线播放av电影 | 最新超碰 | 日韩理论在线视频 | 日韩精品久久久久久久电影竹菊 | 四虎亚洲精品 | 91精品国产综合久久婷婷香蕉 | 九九热免费在线观看 | 97色涩| 91国内在线 | 91九色蝌蚪视频网站 | 97视频亚洲 | 久草网在线视频 | 久久99精品国产99久久 | 337p日本大胆噜噜噜噜 | 日韩欧美一区二区三区视频 | 国产精品毛片久久久久久久久久99999999 | 亚洲精品国产综合久久 | 精品电影一区 | 日韩另类在线 | 亚洲国产精品久久久久婷婷884 | 6080yy午夜一二三区久久 | 免费黄色av片 | 在线观看日韩专区 | 中文字幕欧美日韩va免费视频 | 色婷婷丁香 | 91精品国产自产91精品 | 国产v在线 | 亚洲精品国产精品国自产观看 | 在线观看亚洲 | 91丨九色丨高潮丰满 | 国产精品久久久久影视 | 免费视频91蜜桃 | 人人爽人人爽人人爽学生一级 | 亚洲精品国产精品国自产在线 | se婷婷| 黄a在线 | 国产又黄又爽又猛视频日本 | 日韩免费不卡av | 91视频91色| 国产在线播放一区二区三区 | 成人国产精品一区二区 | 91精品推荐 | 特黄色大片 | 99精品免费在线观看 | 日本少妇视频 | 九九免费观看全部免费视频 | 91精品国产91 | 91在线网址 | 九九免费视频 | 免费网站在线观看成人 | 色婷婷狠狠18 | www欧美xxxx | 激情综合啪 | 日韩欧美一区二区三区在线观看 | 五月激情六月丁香 | 成人中文字幕在线 | 日本在线观看中文字幕 | av中文字幕日韩 | 国产成人a v电影 | 日本久久免费视频 | 在线免费观看亚洲视频 | 91丨porny丨九色 | 日韩中文字幕亚洲一区二区va在线 | 视频成人永久免费视频 | 91探花在线视频 | 国内精品视频一区二区三区八戒 | 亚洲精品乱码久久久久久 | 色偷偷97 | 人人澡人人添人人爽一区二区 | 中文字幕免费 | 97成人精品视频在线播放 | 综合久久精品 | 四虎影视成人永久免费观看亚洲欧美 | 国内99视频 | 丁香六月网 | 午夜精品视频免费在线观看 | 丁香导航| 婷婷日| 97国产精品一区二区 | 亚洲精品一区二区在线观看 | 国产精品久久久久久久久久妇女 | 99精品国产aⅴ | 日韩四虎 | 深夜免费福利网站 | 中文字幕视频三区 | 97国产大学生情侣白嫩酒店 | 免费观看全黄做爰大片国产 | 亚洲黄色片在线 | 探花视频网站 | 色夜影院 | 成人午夜电影在线播放 | 久久久久一区 | 欧美日韩高清不卡 | 日韩xxx视频| 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 色99导航| 亚州av免费 | 久久综合欧美 | 久久黄色网页 | 国产高清日韩欧美 | 欧美日韩aaaa | 国产精品高潮久久av | 伊人影院99 | 天天色综合久久 | 亚洲春色成人 | 亚洲第一香蕉视频 | 超碰在线免费福利 | 成人理论电影 | 成人免费av电影 | 久久电影色| 国内精品亚洲 | av大全在线 | 天天操综 | 免费 在线 中文 日本 | a视频免费看 | 精品综合久久久 | 欧美淫aaa免费观看 日韩激情免费视频 | 男女激情片在线观看 | 国产午夜视频在线观看 | 91看片在线播放 | 国产一区在线播放 | 亚洲一区二区三区四区在线视频 | 黄色日视频 | 久久免费看毛片 | 在线欧美中文字幕 | 亚洲欧洲精品一区二区 | 国产视频在线观看一区 | 日本黄色大片免费看 | 久草在线最新 | 国产第一福利 | 亚州性色| 九九在线国产视频 | 欧美激情精品久久久 | 探花视频网站 | 久久免费精品一区二区三区 | 亚洲日日日 | 国产精品永久免费视频 | 国产在线国产 | 欧美日韩国产亚洲乱码字幕 | 色综合网 | 成人国产电影在线观看 | 久久国产视频网站 | 人人爱爱 | 成年人看片 | 在线观看黄网站 | 久久欧美视频 | 九九在线免费视频 | 在线 精品 国产 | 日本黄色免费电影网站 | 欧美极品xxx | 国色天香av| 97超在线 | 久久成人视屏 | 99亚洲精品在线 | 日本成人中文字幕在线观看 | 99在线精品免费视频九九视 | 精品一区二区在线免费观看 | 午夜电影 电影 | 91中文在线| 国产一区二区网址 | 亚洲午夜久久久久久久久电影网 | 97激情影院 | 五月综合婷 | 天堂av在线网址 | 成人三级网站在线观看 | 亚洲精品在线视频播放 | 日韩精品一区二区三区在线播放 | 四虎天堂| 久草在线中文视频 | 日批视频 | 久操操| 亚洲国产高清视频 | 五月天亚洲精品 | 久久视频免费 | 久久精品爱爱视频 | 亚洲综合色丁香婷婷六月图片 | 久爱综合 | 99精品国产一区二区三区麻豆 | 片网站 | 国产精品视频永久免费播放 | 开心激情婷婷 | 国产精品原创 | 一区二区三区中文字幕在线 | 欧美性久久久久久 | 亚洲 成人 一区 | 香蕉视频导航 | 亚洲日本va在线观看 | 久久精品久久久精品美女 | 午夜精品视频免费在线观看 | 91福利社在线观看 | 国产麻豆精品久久一二三 | 欧美日韩国产精品一区二区 | 久久精品中文字幕少妇 | 国产精品99久久久久久大便 | 91视频麻豆 | 天天操天天干天天爽 | www.com黄 | 久草在| av一区二区在线观看中文字幕 | 视频成人永久免费视频 | 97精品在线| 精品亚洲二区 | 97超碰人人模人人人爽人人爱 | 成人一级免费电影 | 久久夜色精品国产欧美乱极品 | 色诱亚洲精品久久久久久 | 欧美怡红院视频 | 国产福利一区二区三区视频 | 亚洲欧洲久久久 | 一区在线播放 | 日日干综合| 国产精品久久久久久久久免费 | 九九热av| 色欧美视频 | 开心激情综合网 | 国产私拍在线 | 国产麻豆精品一区 | 欧美精品在线观看免费 | 91久久黄色 | 91天堂在线观看 | 成人国产电影在线观看 | 色婷婷综合久色 | 91麻豆精品国产91久久久久久久久 | 成人影视免费看 | www.神马久久 | 99热在线观看 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 91视频午夜 | av高清网站在线观看 | 日韩在线欧美在线 | 黄色av三级在线 | 国产精品久久久久永久免费 | 国产一级免费观看视频 | 亚洲九九影院 | 一区二区三区精品在线 | 天天爽天天爽 | 久久精品久久综合 | 久久成人高清 | 久久综合九色综合网站 | 国产精品12345| 四虎影视成人永久免费观看亚洲欧美 | 一区二区三区在线免费播放 | zzijzzij亚洲日本少妇熟睡 | 欧美日韩国产亚洲乱码字幕 | 国产综合精品一区二区三区 | av一本久道久久波多野结衣 | 伊人狠狠干 | 精品视频久久 | 久久久久久国产一区二区三区 | 亚洲aⅴ久久精品 | 日韩中文幕 | 成人黄色毛片视频 | 在线亚洲人成电影网站色www | 高清日韩一区二区 | 久久久在线视频 | 草在线 | 国产网站色 | 午夜影院先 | 中文字幕日韩免费视频 | 五月天六月婷婷 | 在线视频手机国产 | 亚洲人人av | 亚洲欧美日韩国产 | 国产手机视频 | 国产亚洲婷婷免费 | 精品欧美一区二区三区久久久 | 91九色蝌蚪国产 | 天天av资源 | 国产片免费在线观看视频 | 午夜精品一区二区三区可下载 | www.av免费观看 | 日韩三级视频在线看 | 一区二区精品在线视频 | 91网站在线视频 | 国模一二三区 | 久久精品中文视频 | av三级av| 色欧美综合 | 91porny九色在线播放 | 98涩涩国产露脸精品国产网 | 久久久精品小视频 | 国产不卡一区二区视频 | 国产成人一二片 | 国产超碰在线 | a久久久久久 | 久久精品免费看 | 欧美在线观看视频一区二区三区 | 91少妇精拍在线播放 | 91视频在线网址 | 亚洲三级国产 | 蜜臀久久99静品久久久久久 | 欧美日韩视频观看 | 成人aⅴ视频 | 日韩电影在线观看一区 | 国产精品一区二区你懂的 | 国产亚洲精品xxoo | 亚洲精品高清在线观看 | 久久成人高清视频 | 麻豆91小视频 | 亚洲国产理论片 | 欧美性一级观看 | 精品国偷自产在线 | 不卡av在线播放 | 成年人在线免费看片 | 日韩毛片久久久 | 综合久久久久久久 | 亚洲精品视频在线观看免费视频 | 99人成在线观看视频 | 视频在线观看99 | 免费视频成人 | 国产免费xvideos视频入口 | 2021国产视频 | 日本三级不卡视频 | 国产精品视频你懂的 | 久久久久免费精品 | 久久久久北条麻妃免费看 | 精品久久久久久久久久久久久久久久久久 | 看黄色.com| 国产精品99免视看9 国产精品毛片一区视频 | 97碰在线 | 97网在线观看 | 免费视频久久久久久久 | 97超碰免费 | 欧美一区视频 | 久久精品免费播放 | 亚洲国产成人在线观看 | 成人影片在线播放 | 又污又黄的网站 | 久久天天躁夜夜躁狠狠躁2022 | 91av网址| 日韩伦理片一区二区三区 | 国产糖心vlog在线观看 | 久草视频网 | 欧美日韩高清一区二区 国产亚洲免费看 | 国产精品 久久 | 五月综合网站 | 国产成人精品aaa | 国产一区二区午夜 | 毛片网在线 | 国产成人免费在线观看 | 久久精品一区二区三区国产主播 | 视频在线一区 | 成人影视片| 91麻豆传媒 | 2019中文字幕第一页 | 99这里只有精品99 | 一区二区三区国产欧美 | 99久久久成人国产精品 | 久草电影免费在线观看 | 国产成人精品免费在线观看 | 日韩h在线观看 | 久久综合色天天久久综合图片 | 婷婷亚洲五月色综合 | 日韩精品字幕 | 天天综合网国产 | 日韩亚洲在线 | 五月天中文字幕 | 久久新视频 | 69av在线播放 | 国产特级毛片aaaaaaa高清 | 日产乱码一二三区别在线 | 天天色婷婷 | 亚洲午夜精品久久久久久久久 | 91精品在线播放 | 丰满少妇在线观看资源站 | 97超碰人人澡人人 | 欧美精品久久久久久久免费 | 成人午夜毛片 | 91福利视频久久久久 | 99在线热播精品免费 | 免费成人黄色片 | 韩日精品视频 | 国产中文字幕在线看 | 久草在线视频国产 | 人人爽人人澡 | 国产视频999 | 丁香激情网 | 国产精品久久久久av福利动漫 | 四虎在线视频 | 欧美日韩国产精品一区二区亚洲 | 99操视频 | 欧美日韩性视频 | 日韩欧美视频在线观看免费 | bayu135国产精品视频 | av官网在线 | 毛片在线网 | 中文字幕在线观看第一区 | 欧美黑人性爽 | 正在播放国产精品 | 天天搞天天干天天色 | 日韩中文在线视频 | 色网站免费在线观看 | 激情欧美丁香 | 日韩欧美一区二区三区在线 | 国产久草在线观看 | 国产精品在线看 | 亚洲最大色 | 亚洲国产最新 | 成年人免费在线播放 | 日韩特黄一级欧美毛片特黄 | 久久在线免费观看视频 | 国产成人精品av | 99久久精品费精品 | 国产亚洲成人网 | 国产精品18久久久久久首页狼 | 午夜 在线 | 91免费版在线观看 | 91在线精品秘密一区二区 | 伊甸园av在线 | 久久久鲁 | 日韩午夜在线观看 | 亚洲天堂自拍视频 | 国产91成人在在线播放 | 麻豆国产在线播放 | 欧美日韩中文另类 | 久久这里有 | 成人精品一区二区三区中文字幕 | 国产精品成久久久久三级 | 99精品电影 | 亚洲国产精品传媒在线观看 | 国产精品免费一区二区三区在线观看 | 天天射综合 | 中文字幕之中文字幕 | 天天操天天舔天天干 | 在线观看一区视频 | 日韩免费看 | 成人国产精品免费观看 | 在线免费视频a | 天天操网 | 天天碰天天操 | 777奇米四色 | 久草视频在 | 欧美一区二区三区在线视频观看 | 久久综合影视 | 国产美女在线精品免费观看 | 六月丁香激情综合 | 欧美极品少妇xxxx | 玖玖色在线观看 | 国产啊v在线观看 | 成人久久18免费网站麻豆 | 日韩欧美在线免费 | 91 在线视频播放 | 国产美女视频一区 | 国内精品久久久久影院日本资源 | 一级免费黄色 | 九月婷婷色 | 色视频网站在线观看一=区 a视频免费在线观看 | 狠狠狠色丁香综合久久天下网 | 九九爱免费视频 | 亚洲精品99久久久久久 | 美女国内精品自产拍在线播放 | 波多野结衣在线中文字幕 | 日韩精品一区二区在线观看视频 | 国产特黄色片 | 日韩三区在线 | 久草网视频| 日韩高清一区在线 | 亚洲国产精品免费 | 伊人狠狠干 | 国产精品久久一卡二卡 | 超碰97国产精品人人cao | 国内精品久久久久影院日本资源 | 久久精品人 | 久久黄色小说 | 在线亚洲人成电影网站色www | 国产美女永久免费 | 91污污视频在线观看 | 国产在线高清视频 | 久久久毛片| 天堂va欧美va亚洲va老司机 | 二区精品视频 | 激情文学综合丁香 | 亚洲五月婷| 中文字幕在线播放视频 | 亚洲国产网站 | 九九免费在线看完整版 | 免费观看一区二区三区视频 | 亚洲va欧美 | 五月天久久婷 | 成人一级| 亚洲国产中文在线观看 | 中文字幕在线视频免费播放 | 日韩在线观看一区二区三区 | 97精品国自产拍在线观看 | 91免费在线看片 | 成人a v视频 | 97免费 | 色插综合| 国产精品国产精品 | 99热在线国产 | 国产欧美最新羞羞视频在线观看 | 日韩高清三区 | 精品国产精品久久一区免费式 | 在线免费观看欧美日韩 | 黄色av在 | 欧美精品一二 | 国产免费午夜 | 黄色三级免费网址 | 亚洲精品456在线播放乱码 | 97超碰在线久草超碰在线观看 | 日韩在线免费高清视频 | 视频一区在线播放 | 91在线91拍拍在线91 | 欧美在线观看视频一区二区 | 免费成人黄色av | 国产精品尤物视频 | 欧美一级爽 | 亚洲精品午夜久久久久久久 | 成人av电影在线 | 亚洲精品字幕 | 91九色蝌蚪在线 | 婷婷综合国产 | 婷婷六月天在线 | 精品女同一区二区三区在线观看 | 操一草| 91丨精品丨蝌蚪丨白丝jk | 97国产在线播放 | 亚洲成人家庭影院 | 丁香五月缴情综合网 | 久久久久久久久亚洲精品 | 日韩在观看线 | 成人丁香花 | 亚洲男男gaygayxxxgv| 国产永久免费观看 | 国产精品99久久99久久久二8 | 在线免费成人 | 午夜.dj高清免费观看视频 | av一级一片 | 一级性生活片 | 麻豆视频免费网站 | 国产首页 | 亚av在线 | 日韩精品免费专区 | 深夜免费福利视频 | 色综合久久久久综合体 | 久久免费精品国产 | 欧美性生活免费 | 久久精品视频18 | 黄色av电影在线观看 | 中文字幕日韩高清 | 天天狠狠操| 日本黄色免费看 | 亚洲免费视频观看 | 99热免费在线| 不卡国产视频 |