Android - 사용자 지정 컨트롤 수직 TextView
@Override
protected void onDraw(Canvas canvas) {
canvas.rotate(-90);
canvas.translate(-getHeight(), 0);
super.onDraw(canvas);
}
이상의 실현은 내용을 수직으로 표시할 수 있지만 너비와 높이가 어울리지 않는 문제가 존재한다. 예를 들어 지정한 너비에서 수직으로 보이는 문자가 줄을 바꿀 수 있는데 이것은 내가 원하는 결과가 아니다.나중에 인터넷에서 한 친구의 글을 찾았는데 마침 이 문제를 해결하여 대신께 경의를 표합니다.몇 가지 정리와 수정을 한 후에 최종 코드는 다음과 같다.
package com.example.sportdemo;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
public class VerticalTextView extends View {
private final static int DEFAULT_TEXT_SIZE = 18;
private final static int DEFAULT_TEXT_COLOR = 0x00000000;
private final static int DIRECTION_TTB = 0;
private final static int DIRECTION_BTT = 1;
private String mText = "H";
private TextPaint mTextPaint = new TextPaint();
private Rect mTextRect = new Rect();
private Path path = new Path();
private int mDirection;
public VerticalTextView(Context context) {
super(context);
init();
}
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalTextView);
CharSequence text = a.getString(R.styleable.VerticalTextView_text);
if (text != null) {
mText = text.toString();
}
int textSize = a.getDimensionPixelOffset(R.styleable.VerticalTextView_textSize, DEFAULT_TEXT_SIZE);
if (textSize > 0) {
mTextPaint.setTextSize(textSize);
}
int textColor = a.getColor(R.styleable.VerticalTextView_textColor, DEFAULT_TEXT_COLOR);
mTextPaint.setColor(textColor);
mDirection = a.getInt(R.styleable.VerticalTextView_direction, DIRECTION_BTT);
a.recycle();
}
@SuppressLint("NewApi")
private final void init() {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);
mTextPaint.setColor(DEFAULT_TEXT_COLOR);
mTextPaint.setTextAlign(Align.CENTER);
}
public void setText(String text) {
mText = text;
requestLayout();
invalidate();
}
public void setText(int resId) {
mText = getContext().getResources().getText(resId).toString();
requestLayout();
invalidate();
}
public void setTextSize(int size) {
mTextPaint.setTextSize(size);
requestLayout();
invalidate();
}
public void setTextColor(int color) {
mTextPaint.setColor(color);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mTextPaint.getTextBounds(mText, 0, mText.length(), mTextRect);
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
private int measureWidth(int measureSpec) {
int width = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
width = specSize;
} else {
// width = mTextRect.height() + getPaddingLeft() + getPaddingRight();
width = mTextRect.height();
if (specMode == MeasureSpec.AT_MOST) {
width = Math.min(width, specSize);
}
}
return width;
}
private int measureHeight(int measureSpec) {
int height = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
height = specSize;
} else {
// height = mTextRect.width() + getPaddingTop() + getPaddingBottom();
height = mTextRect.width();
if (specMode == MeasureSpec.AT_MOST) {
height = Math.min(height, specSize);
}
}
return height;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int startX = 0;
int startY = 0;
int stopY = getHeight();
if (mDirection == DIRECTION_TTB) {
startX = (getWidth() >> 1) - (mTextRect.height() >> 1);
path.moveTo(startX, startY);
path.lineTo(startX, stopY);
}
else {
startX = (getWidth() >> 1) + (mTextRect.height() >> 1);
path.moveTo(startX, stopY);
path.lineTo(startX, startY);
}
canvas.drawTextOnPath(mText, path, 0, 0, mTextPaint);
}
}
Xml 레이아웃 파일:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.sportdemo.VerticalTextView
xmlns:demo="http://schemas.android.com/apk/res/com.example.sportdemo"
android:id="@+id/vtv"
android:layout_width="40dp"
android:layout_height="120dp"
android:background="@color/black"
demo:text="helloworld"
demo:textColor="@color/white"
demo:textSize="20sp"
demo:direction="bottomtotop" />
LinearLayout>
여기서 강조해야 할 것은drawTextOnPath가 4.1 이전 시스템에서 하드웨어 가속을 켜는 상황에서 우리가 원하는 효과를 얻지 못했기 때문에 그 결과 그려진 텍스트가 표시되지 않기 때문에 아래 코드를 통해 하드웨어 가속을 사용하지 않는다는 것이다.
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
순전히 학습 노트이니 시정을 환영합니다.
전재 대상:https://www.cnblogs.com/biyaxiong/p/3784246.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.