답변:
paint.getTextBounds () (객체 메소드) 는 어떻습니까 ?
필요한 것에 따라 높이를 측정하는 방법은 여러 가지가 있습니다.
적은 양의 고정 텍스트를 정확하게 가운데에 맞추는 것과 같은 일을하는 경우 원할 것 getTextBounds
입니다. 이처럼 경계 사각형을 얻을 수 있습니다
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();
다음 이미지에서 볼 수 있듯이 문자열마다 다른 높이가 표시됩니다 (빨간색으로 표시).
텍스트의 크기에 관계없이 일정한 높이가 필요한 경우에 따라 높이가 다른 것이 단점이 될 수 있습니다. 다음 섹션을 참조하십시오.
글꼴 메트릭에서 글꼴의 높이를 계산할 수 있습니다. 높이는 특정 텍스트 문자열이 아닌 글꼴에서 가져 오기 때문에 항상 동일합니다.
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;
기준선은 텍스트가있는 선입니다. 하강은 일반적으로 캐릭터가 선 아래로 가장 먼 곳이며 상승은 일반적으로 캐릭터가 선 위로 가장 먼 곳입니다. 높이를 얻으려면 음수 가기 때문에 상승을 빼야합니다. (기준선이다 y=0
및 y
스크린까지 descreases).
다음 이미지를보십시오. 두 문자열의 높이는입니다 234.375
.
텍스트 높이가 아닌 선 높이를 원하면 다음을 수행 할 수 있습니다.
float height = fm.bottom - fm.top + fm.leading; // 265.4297
이것 bottom
과 top
라인입니다. 선행 (인라인 간격)은 일반적으로 0이지만 어쨌든 추가해야합니다.
위의 이미지는 이 프로젝트 에서 나온 것입니다 . 이것으로 놀아서 Font Metrics의 작동 방식을 볼 수 있습니다.
여러 줄 문자의 높이를 측정하려면을 사용해야합니다 StaticLayout
. 이 답변 에서 그것에 대해 자세히 이야기 했지만이 높이를 얻는 기본 방법은 다음과 같습니다.
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);
int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);
float height = myStaticLayout.getHeight();
getTextSize()
은 픽셀 단위로 글꼴 크기를 제공합니다 (단위와 반대 sp
). @androiddeveloper
@bramp의 대답은 정확합니다. 부분적으로 계산 된 경계가 암시 적 시작 좌표가 0, 0 인 텍스트를 완전히 포함하는 최소 사각형이라는 점은 언급하지 않았기 때문입니다.
즉, 예를 들어 "Py"의 높이는 픽셀 단위로 다른 높이가 필요하기 때문에 "py"또는 "hi"또는 "oi"또는 "aw"의 높이와 다릅니다.
이것은 결코 고전적인 자바의 FontMetrics와 동등하지 않습니다.
텍스트의 너비는 고통스럽지 않지만 높이는 큽니다.
특히, 그려진 텍스트를 세로로 가운데 정렬해야하는 경우, 그리려는 텍스트를 사용하는 대신 따옴표없이 텍스트 "a"의 경계를 가져와보십시오. 나를 위해 작동합니다 ...
여기 내가 의미하는 바가있다 :
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(textSize);
Rect bounds = new Rect();
paint.getTextBounds("a", 0, 1, bounds);
buffer.drawText(this.myText, canvasWidth >> 1, (canvasHeight + bounds.height()) >> 1, paint);
// remember x >> 1 is equivalent to x / 2, but works much much faster
텍스트를 세로로 가운데 정렬한다는 것은 경계 사각형을 세로로 가운데 정렬하는 것을 의미합니다. 이는 텍스트 (대문자, 긴 글자 등)마다 다릅니다. 그러나 실제로 원하는 것은 렌더링 된 텍스트의 기준선을 정렬하여 높이가 높거나 그루브가 나타나지 않도록하는 것입니다. 따라서 가장 작은 문자의 중심 (예 : "a")을 알고있는 한 나머지 텍스트에 대한 정렬을 재사용 할 수 있습니다. 그러면 모든 텍스트가 중앙 정렬되고 기본 정렬됩니다.
x >> 1
오랫동안 보지 못했습니다 . 그것만 찬성 :)
x / 2
최적화합니다.x >> 1
x / 2
은 Chris의 의견을 고려하여 코드를 읽을 때 훨씬 더 친숙합니다.
buffer
이 예에서? 그것은 canvas
에 전달 draw(Canvas)
방법은?
getTextSize () 메서드를 사용하여 Paint 객체의 텍스트 크기를 간단히 얻을 수 있습니다. 예를 들면 다음과 같습니다.
Paint mTextPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
//use densityMultiplier to take into account different pixel densities
final float densityMultiplier = getContext().getResources()
.getDisplayMetrics().density;
mTextPaint.setTextSize(24.0f*densityMultiplier);
//...
float size = mTextPaint.getTextSize();
24.0f
왔습니까?
여전히 문제가있는 사람은 이것이 내 코드입니다.
정사각형 (너비 = 높이) 인 사용자 정의보기가 있고 문자를 할당하고 싶습니다. onDraw()
문자를 사용하지 않지만 높이를 얻는 방법을 보여줍니다. 화면 중간에 문자가 표시됩니다.
public class SideBarPointer extends View {
private static final String TAG = "SideBarPointer";
private Context context;
private String label = "";
private int width;
private int height;
public SideBarPointer(Context context) {
super(context);
this.context = context;
init();
}
public SideBarPointer(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
public SideBarPointer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init();
}
private void init() {
// setBackgroundColor(0x64FF0000);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
height = this.getMeasuredHeight();
width = this.getMeasuredWidth();
setMeasuredDimension(width, width);
}
protected void onDraw(Canvas canvas) {
float mDensity = context.getResources().getDisplayMetrics().density;
float mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
Paint previewPaint = new Paint();
previewPaint.setColor(0x0C2727);
previewPaint.setAlpha(200);
previewPaint.setAntiAlias(true);
Paint previewTextPaint = new Paint();
previewTextPaint.setColor(Color.WHITE);
previewTextPaint.setAntiAlias(true);
previewTextPaint.setTextSize(90 * mScaledDensity);
previewTextPaint.setShadowLayer(5, 1, 2, Color.argb(255, 87, 87, 87));
float previewTextWidth = previewTextPaint.measureText(label);
// float previewTextHeight = previewTextPaint.descent() - previewTextPaint.ascent();
RectF previewRect = new RectF(0, 0, width, width);
canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
canvas.drawText(label, (width - previewTextWidth)/2, previewRect.top - previewTextPaint.ascent(), previewTextPaint);
super.onDraw(canvas);
}
public void setLabel(String label) {
this.label = label;
Log.e(TAG, "Label: " + label);
this.invalidate();
}
}