Android Canvas drawText 텍스트 가운데 에 있 는 일 들(도해)
사용자 정의 컨트롤 을 실현 하 는 과정 에서 중간 문 자 를 그 리 는 수요 가 많 기 때문에 인터넷 에서 관련 블 로 그 를 찾 아 보 았 습 니 다.항상 어 리 석 은 얼굴 로 자신 이 분석 해 보 겠 다 고 생각 했 습 니 다.여기 서 기록 하면 도움 이 되 었 으 면 좋 겠 습 니 다.
2.텍스트 그리 기
먼저 좌표 원점 을 컨트롤 센터 로 이동 합 니 다(기본 좌표 원점 은 화면 왼쪽 상단 에 있 습 니 다).이렇게 하면 직관 적 으로 보 이 는 다음 에 x,y 축 을 그립 니 다.이때 원점 은 위로 y 를 마이너스 로 하고 아래 y 를 플러스 로 하 며 왼쪽 x 를 마이너스 로 하고 오른쪽 x 를 플러스 로 하 며(0,0)좌표 로 텍스트 를 그립 니 다.
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
//
canvas.translate(getWidth() / 2, getHeight() / 2);
// x
canvas.drawLine(-getWidth() / 2, 0, getWidth() / 2, 0, paint);
// y
canvas.drawLine(0, -getHeight() / 2, 0, getHeight() / 2, paint);
//
paint.setTextSize(sp2px(50));
canvas.drawText("YangLe", 0, 0, paint);
}
그림%1 개의 캡 션 을 편 집 했 습 니 다.텍스트 그리 기
어,왜 그 려 진 텍스트 가 첫 번 째 상한 선 에 있 습 니까?y 좌 표 는 지정 한 0 이 아 닙 니까?왜 텍스트 는 x 축의 위 나 아래 가 아니 라 x 축 을 통과 하고 이런 의문 을 가지 고 계속 아래 를 보 았 습 니까?
우선 중요 한 종 류 를 보 세 요.
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
FontMetrics 클래스 는 Paint 의 내부 클래스 로 텍스트 를 그 릴 때의 관건 적 인 좌표 위 치 를 정의 합 니 다.이 값 들 이 무엇 을 대표 하 는 지 보 세 요.관건 좌표
그림 을 보고 말 하기:
다음은 drawText 라 는 방법 을 살 펴 보 겠 습 니 다.
/**
* Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted
* based on the Align setting in the paint.
*
* @param text The text to be drawn
* @param x The x-coordinate of the origin of the text being drawn
* @param y The y-coordinate of the baseline of the text being drawn
* @param paint The paint used for the text (e.g. color, size, style)
*/
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
super.drawText(text, x, y, paint);
}
x,y 매개 변수의 의 미 를 중점적으로 보십시오.인자 전송(0,10)이 있 으 면 텍스트 를 그 리 는 baseline 은 x 축 에서 10px 를 아래로 이동 합 니 다.즉,y10 을 텍스트 로 하 는 baseline 으로 그립 니 다.y10 은 텍스트 를 그 리 는 baseline 이 y 축 방향 에 있 는 위치 입 니 다.
메모:baseline 은 텍스트 를 그 리 는 기선 입 니 다.텍스트 영역 을 그 리 는 것 에 비해 x 축 에 해당 합 니 다.위로 마이너스(top,ascent)이 고 아래로 플러스(descent,bottom)입 니 다.그러나 이 x 축 은 컨트롤 의 x 축 이 아 닙 니 다.기억 하 세 요!!
우리 가 윗글 에서 제기 한 의문 을 기억 하 십 니까?이제 설명 할 수 있 습 니 다.
왜 그 려 진 텍스트 가 첫 번 째 상한 에 있 습 니까?
우 리 는 좌표 원점 을 컨트롤 센터 로 옮 겼 기 때문에 텍스트 의 baseline 은 x 축 이 고 top,ascent 값 은 마이너스 이기 때문에 그 려 진 텍스트 는 첫 번 째 상한 에 있 습 니 다.
y 좌 표 는 지정 한 0 이 아 닙 니까?왜 텍스트 는 x 축의 위 나 아래 가 아니 라 x 축 을 통과 합 니까?
drawText 방법 은 기본 x 축 방향 을 왼쪽 에서 오른쪽으로 그립 니 다.y 축 방향 은 baseline 을 기준 으로 그립 니 다.글 의 baseline 은 x 축 이 고 baseline 을 기준 으로 텍스트 를 그 리 는 데 아직 거리 가 있 기 때문에 텍스트 는 x 축 을 통과 합 니 다.
3.가운데 텍스트 그리 기
앞에서 우 리 는 텍스트 를 어떻게 그 리 는 지,그리고 그 중의 매개 변수 와 좌표 의 의 미 를 배 웠 습 니 다.그 다음 에 본론 에 들 어가 서 가운데 텍스트 를 어떻게 그 릴 수 있 는 지 보 겠 습 니 다.
먼저 그림 을 보 세 요.이때 텍스트 의 baseline 은 x 축 입 니 다.텍스트 를 가운데 에 표시 하려 면 텍스트 의 너비 와 높이 를 계산 해 야 합 니 다.
현재 너비 가 있 습 니 다.텍스트 를 그 리 는 x 좌 표를 왼쪽으로 이동(너비/2)하면 수평 으로 가운데 로 이동 할 수 있 습 니 다.그러나 수직 방향 은 이렇게 할 수 없습니다.우 리 는 텍스트 를 아래 에서 baseline 을 텍스트 중심 으로 이동 하 는 거리,즉(높이/2-fontMetrics.descent)입 니 다.다음 그림 과 같 습 니 다.
계산 baseLine Y
현재 의 공식 은:
float baseLineY
= (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent;
= -fontMetrics.ascent / 2 - fontMetrics.descent / 2;
= -(fontMetrics.ascent + fontMetrics.descent) / 2;
= Math.abs(fontMetrics.ascent + fontMetrics.descent) / 2;
Paint 에서 도 ascent 와 descent 값 을 얻 는 방법 이 있 기 때문에 공식 은 다음 과 같다.float baseLineY = Math.abs(paint.ascent() + paint.descent()) / 2;
메모:이 공식 은 좌표 원점 에 비해 컨트롤 센터 에서 계산 합 니 다.좌표 원점 이 왼쪽 상단 에 있 으 면 baseLiney 는 컨트롤 높이 의 절반 을 더 해 야 합 니 다.
float baseLineY = height / 2 + Math.abs(paint.ascent() + paint.descent()) / 2;
코드 보기:
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
//
canvas.translate(getWidth() / 2, getHeight() / 2);
// x
canvas.drawLine(-getWidth() / 2, 0, getWidth() / 2, 0, paint);
// y
canvas.drawLine(0, -getHeight() / 2, 0, getHeight() / 2, paint);
//
paint.setTextSize(sp2px(50));
paint.setColor(Color.GRAY);
//
float textWidth = paint.measureText("YangLe'Blog");
// baseline y
float baseLineY = Math.abs(paint.ascent() + paint.descent()) / 2;
canvas.drawText("YangLe'Blog", -textWidth / 2, baseLineY, paint);
}
가운데 보 셨 나 요?가운데 텍스트 그리 기
큰 성 과 를 거두다.
4.여러 줄 가운데 에 있 는 텍스트 그리 기
메모:drawText 방법 은 여러 줄 의 텍스트 그리 기 를 지원 하지 않 습 니 다.
4.1 방식 1
자동 줄 바 꾸 기 를 지원 하 는 StaticLayout 사용 하기:
/**
* ( 1)
*
* @param canvas
*/
private void drawCenterMultiText1(Canvas canvas) {
String text = "ABC";
//
TextPaint textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.GRAY);
// 50dp
StaticLayout staticLayout = new StaticLayout(text, textPaint, dp2px(50),
Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
canvas.save();
// StaticLayout (0,0)
// , Canvas
canvas.translate(-staticLayout.getWidth() / 2, -staticLayout.getHeight() / 2);
staticLayout.draw(canvas);
canvas.restore();
}
Static Layout 의 구조 방법 파라미터 의 의 미 를 보십시오.
public StaticLayout(CharSequence source, TextPaint paint, int width, Alignment align,
float spacingmult, float spacingadd, boolean includepad) {
this(source, 0, source.length(), paint, width, align, spacingmult, spacingadd, includepad);
}
StaticLayout
static Layout 를 사용 하면 줄 마다 설정 한 폭 이 같 습 니 다.줄 마다 길이 가 다른 텍스트 를 표시 해 야 할 때 이 방식 은 사용 할 수 없습니다.걱정 하지 마 세 요.이어서 두 번 째 방식 을 살 펴 보 겠 습 니 다.
4.2 방식 2
drawText 를 순환 하 는 방식 으로 그립 니 다.그림 을 보고 말 합 니 다.
계산 baseLine Y
현재 A,B,C 세 줄 의 텍스트 를 그 려 야 합 니 다.빨간색 A 는 각 줄 의 텍스트 의 기본 적 인 그리 기 위 치 를 대표 합 니 다.녹색 선 은 각 줄 의 텍스트 의 baseline 을 대표 하고 x 축 은 빨간색 A 의 baseline 입 니 다.지금 은 세 가지 상황 으로 나 눌 수 있 습 니 다.
/**
* ( 2)
*
* @param canvas
*/
private void drawCenterMultiText2(Canvas canvas) {
String[] texts = {"A", "B", "C"};
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
// top
float top = Math.abs(fontMetrics.top);
// ascent
float ascent = Math.abs(fontMetrics.ascent);
// descent,
float descent = fontMetrics.descent;
// bottom,
float bottom = fontMetrics.bottom;
//
int textLines = texts.length;
//
float textHeight = top + bottom;
//
float textTotalHeight = textHeight * textLines;
//
float basePosition = (textLines - 1) / 2f;
for (int i = 0; i < textLines; i++) {
//
float textWidth = paint.measureText(texts[i]);
// baseline y
float baselineY;
if (i < basePosition) {
// x ,
// /2 - - top ( )
baselineY = -(textTotalHeight / 2 - textHeight * i - top);
} else if (i > basePosition) {
// x ,
// /2 - - bottom ( )
baselineY = textTotalHeight / 2 - textHeight * (textLines - i - 1) - bottom;
} else {
// x ,
//
baselineY = (ascent - descent) / 2;
}
canvas.drawText(texts[i], -textWidth / 2, baselineY, paint);
}
}
위의 그림 을 대조 하고 코드 를 보면 이해 하기 쉽 습 니 다.코드 중의 공식 이 최적화 할 수 있 는 부분 이 있다 고 생각 합 니 다.좋 은 방법 이 있 으 면 메 시 지 를 남 겨 주세요.중국어 버 전의 여러 줄 텍스트 를 보 세 요:
다 중 줄 가운데 텍스트
5.TextAlign
Paint 의 TextAlign 속성 은 drawText 방법 에서 x 매개 변수의 상대 적 인 위 치 를 결정 합 니 다.
밤 을 들다
Paint.Align.LEFT
Paint.Align.CENTER
Paint.Align.RIGHT
6.텍스트 가운데 공식
좌표 원점 은 컨트롤 센터 에 있 습 니 다:
float baseLineY = Math.abs(paint.ascent() + paint.descent()) / 2;
좌표 원점 은 컨트롤 왼쪽 상단 에 있 습 니 다:
float baseLineY = height / 2 + Math.abs(paint.ascent() + paint.descent()) / 2;
7.마지막 에 쓴다
소스 코드 가 GitHub 에 올 라 왔 습 니 다.Fork 를 환영 합 니 다.괜 찮 은 것 같 으 면 Start 하 세 요!
GitHub 전송 문
본문 Demo 의 Apk 를 눌 러 주세요.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.