Android Canvas的drawText()和文字居中方案

自定義View是繪制文本有三類方法:

// 第一類
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)// 第二類
public void drawPosText (String text, float[] pos, Paint paint)
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)// 第三類
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

說明:

  • drawText():最常用
  • drawPosText():是根據一個個坐標點指定文字位置
  • drawTextOnPath():是根據路徑繪制。

其中drawText()的x,y參數是干嘛的呢?


先來看下下面這段代碼的運行效果:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint=new Paint();paint.setStyle(Paint.Style.FILL);paint.setStrokeWidth(12);paint.setTextSize(100);String text="測試:my text";canvas.drawText(text, 200, 400, paint);//畫兩條線標記位置paint.setStrokeWidth(4);paint.setColor(Color.RED);canvas.drawLine(0, 400, 2000, 400, paint);paint.setColor(Color.BLUE);canvas.drawLine(200, 0, 200, 2000, paint);
}

左對齊-left

左對齊-left

可以看到,x,y并不是指定文字的中點位置,并且x,y與文字對齊方式有關(通過setTextAlign()指定,默認為left)


居中對齊-center

居中對齊-center

右對齊-right

右對齊-right

注:為了使文字完整,上面調整了下x,y的值。


從上面三種情況得出結論,x所對應的豎線:

  • 左對齊 — 文字的左邊界
  • 居中對齊 — 文字的中心位置
  • 右對齊 — 文字的左邊界

y對應的橫線并不是文字的下邊界,而是基準線Baseline

在這里插入圖片描述

  • Top:文字的最頂部
  • Baseline:基準線
  • Bottom:文字的底部

那這些值如何獲取呢?

	Paint.FontMetrics fontMetrics=paint.getFontMetrics();fontMetrics.topfontMetrics.ascentfontMetrics.descentfontMetrics.bottom

記得要在設置完Paint的文字大小,寬度之類屬性后再獲取FontMetrics,Baseline對應對應值為0,在它下面的descent和bottom值為正,top和ascent為負。

那文字的高度為: bottom - top

在這里插入圖片描述
所以,實際繪制的時候取決于基線上一個點來繪制文字,而這個點有三種分別對應為left,center,right。

在這里插入圖片描述
好啦,把drawText()中x,y參數講清楚后實現文字居中就很容易了。

直接上代碼:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);//矩形背景Paint bgRect=new Paint();bgRect.setStyle(Paint.Style.FILL);bgRect.setColor(Color.YELLOW);RectF rectF=new RectF(200, 200, 800, 600);canvas.drawRect(rectF, bgRect);Paint textPaint=new Paint();textPaint.setStyle(Paint.Style.FILL);textPaint.setStrokeWidth(8);textPaint.setTextSize(50);textPaint.setTextAlign(Paint.Align.CENTER);String text="測試:my text";//計算baselinePaint.FontMetrics fontMetrics=textPaint.getFontMetrics();float distance=(fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline=rectF.centerY()+distance;canvas.drawText(text, rectF.centerX(), baseline, textPaint);
}

效果:
在這里插入圖片描述
將對齊方式設置為center,那要讓文字居中顯示,x值就為矩形中心x值,y值也就是Baseline的計算看下圖:
在這里插入圖片描述
y = 矩形中心y值 + 矩形中心與基線的距離

距離 = 文字高度的一半 - 基線到文字底部的距離(也就是bottom)= (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446933.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446933.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446933.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IntelliJ IDEA配置Tomcat

查找該問題的童鞋我相信IntelliJ IDEA,Tomcat的下載,JDK等其他的配置都應該完成了,那我直接進入正題了。 1、新建一個項目 2、由于這里我們僅僅為了展示如何成功部署Tomcat,以及配置完成后成功運行一個jsp文件,我僅勾…

C++對于文件的相關操作 創建、讀寫、刪除代碼

創建 /*** brief 創建文件:在密碼設備內部創建用于存儲用戶數據的文件* param pucFileName 緩沖區指針,用于存放輸入的文件名,最大長度128字節* param uiNameLen 文件名長度* param uiFileSize 文件所占存儲空間的長度*/void CreateFile(sdf_uint8_t…

Android開發之Path詳解

目錄一、xxxTo方法1、lineTo(float x, float y)2、moveTo(float x, float y)3、arcTo3.1、arcTo(RectF oval, float startAngle, float sweepAngle)3.2、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)3.3、arcTo(float left, float top, float r…

git大文件拷貝代碼命令

git clone 鏈接 --recursive

Android APK打包流程

目錄一、概述二、打包流程1、打包資源文件,生成R.java文件2、處理aidl文件,生成相應的Java文件3、編譯項目源代碼,生成class文件4、轉換所有的class文件,生成classes.dex文件5、打包生成APK文件6、對APK文件進行簽名7、對簽名后的…

使用openssl,實現輸入和輸出都是字符串的類型,注意:輸入最好是16的倍數

頭文件crypto_util.h #pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]);std::string aes_encrypt_to_string(const std::string &string,const std::string &password);std::s…

Android Studio 安裝ASM插件

目錄一、安裝步驟1、Android Studio -> Preferences...2、Plugins -> Browse repositories...3、搜索ASM -> 選中要安裝的插件 -> 右側點擊Install4、安裝完后點擊Restart Android Studio5、Android Studio重啟后右側會有個ASM圖標6、找一個類右鍵 -> Show Byte…

使用openssl完成aes-cbc模式的數據加解密,輸入和輸出都是字符串的形式

代碼 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…

Android 網絡異常

目錄前言一、UnknownHostException1、網絡斷開驗證2、DNS 服務器意外掛掉驗證3、DNS 服務器故障驗證4、所需診斷信息二、ConnectTimeoutException三、SocketTimeoutException1、子錯誤 - 讀超時2、子錯誤 - SSL 握手超時3、子錯誤 - 未知原因四、HttpHostConnectException1、服…

Android ViewRoot、DecorViewWindow淺析

目錄簡介目錄1、VeiwRoot1.1、簡介1.2、特別注意2、DecorView2.1、定義2.2、作用2.3、特別說明3、Window4、Activity5、之間關系5.1、總結5.2、之間的關系簡介 DecorView為整個Window界面的最頂層View。DecorView只有一個子元素為LinearLayout。代表整個Window界面&#xff0c;…

Java集合Stream類

Java集合Stream類 ----按條件對集合進行過濾filter public class Test {public static void main(String[] args) {List<String>allnew ArrayList<>();all.add("ghjt");all.add("ghjiiii");Stream<String>streamall.stream();List<S…

使用openssl完成aes-ecb模式的數據加解密,輸入和輸出都是字符串類型

代碼 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…

Java Stream MapReduce大數據開發模型

實現一個購買商品后,對數據進行處理統計的功能. 將購買的商品信息保存在Orders類中 public class Orders {private String name;private double price;private int amount;public Orders(String name, double price, int amount) {this.name name;this.price price;this.am…

隨機函數的生成

函數代碼 #include <string>bool GenerateRandom(std::string *str,unsigned int len) {srand(time(NULL));for(unsigned int i0;i<len;i){switch(rand()%3){case 1:(*str).push_back(Arand()%26);break;case 2:(*str).push_back(arand()%26);break;default:(*str).p…

Android 為控件設置陰影

在Android中設置一個陰影很簡單&#xff0c;只需要兩步&#xff1a; 設置eleavation值&#xff08;高度&#xff09;添加一個背景或者outline &#xff08;即陰影的形狀&#xff09; 說明&#xff1a; View的大小位置都是通過x&#xff0c;y確定的&#xff0c;而現在有了z軸的…

Android在代碼中設置drawableLeft(Right/Top/Bottom)

根據業務的需要&#xff0c;要在代碼中設置控件的drawableLeft&#xff0c;drawableRight&#xff0c;drawableTop&#xff0c;drawableBottom屬性。 我們知道在xml中設置的方法為&#xff1a; android:drawableLeft"drawable/xxxxx"但是在代碼中并沒有相關的setDr…

Java 冒泡排序

冒泡排序–時間復雜度n^2 對數組序列從前向后依次比較相鄰兩個元素的大小,若逆序則兩個元素交換位置如果一趟下來沒有發生交換,則說明序列有序,可以在序列中設置一個標志flag判斷元素是否發生交換,從而來減少不必要的比較(在寫完排序算法后再寫)小結:一共進行數組大小-1次的外…

使用openssl開源AES算法,實現aes、aes-cbc和aes-ecb對字符串的加解密

注意事項 對于用戶輸入的密碼進行了md5運算&#xff0c;從而保證數據格式的統一性 內部調用的隨機函數&#xff0c;參考我的其他博文 參考鏈接 頭文件crypto_util.h #pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::strin…

Android學習指南

目錄核心分析內容1、學什么1.1、Android基礎 & 常用1.2、Android進階1.3、與時俱進、熱門技術1.4、編程語言&#xff1a;Java與Java虛擬機1.5、計算機基礎1.6、總結2、怎么學2.1、學習路徑&#xff1a;如何循序漸進、階段性的學習Android的理論知識&#xff1f;2.2、獲取途…

使用memcmp函數判斷兩個函數的前n位字節數是否相等

memcmp函數的介紹 頭文件&#xff1a;#include <string.h>定義函數&#xff1a;int memcmp (const void *s1, const void *s2, size_t n);函數說明&#xff1a;memcmp()用來比較s1 和s2 所指的內存區間前n 個字符。字符串大小的比較是以ASCII 碼表上的順序來決定&#x…