是否可以在android的textview中垂直书写?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2888780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to write vertically in a textview in android?
提问by Sephy
Let's say you have a normal TextView, with "Stackoverflow" written in it, Is it possible to rotate the TextView by -90°, to have the S at the bottom and the W at the top of the screen? Of course I could write my text as an image, rotate it and use it that way, but I am interested in the text right now. Thanks.
假设您有一个普通的 TextView,上面写着“Stackoverflow”,是否可以将 TextView 旋转 -90°,使 S 位于屏幕底部,W 位于屏幕顶部?当然,我可以将我的文本写成图像,旋转它并以这种方式使用它,但我现在对文本感兴趣。谢谢。
回答by ccheneson
You can set your textview as you would normally do
您可以像往常一样设置 textview
for example:
例如:
<TextView android:id="@+id/txtview"
android:layout_height="fill_parent"
android:layout_width="wrap_content" />
and write a function in your activity to
并在您的活动中编写一个函数
- reverse the characters in your text
- insert
\n
after every characters
- 反转文本中的字符
\n
在每个字符后插入
and then set the text to the TextView.
然后将文本设置为 TextView。
If you dont want to insert the \n
, you will have to set the size of android:layout_width
and play with font size not to have 2 characters fitting on the same line and no truncation
如果您不想插入\n
,则必须设置 的大小android:layout_width
并调整字体大小,以使 2 个字符不适合在同一行上且不会被截断
EditIf I have understood you correctly, you can get what you want by using animation.
编辑如果我对你的理解正确,你可以通过使用动画来得到你想要的。
For example
例如
Under res/anim/myanim.xml
:
下res/anim/myanim.xml
:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="-90"
android:pivotX="50%"
android:duration="0" />
You will have to play with this file to define where you want your text view to be placed.
你必须使用这个文件来定义你想要放置文本视图的位置。
In your activity:
在您的活动中:
TextView t = (TextView)findViewById(R.id.txtview);
String txt = "Stackoverflow";
t.setText(txt);
RotateAnimation ranim = (RotateAnimation)AnimationUtils.loadAnimation(this, R.anim.myanim);
ranim.setFillAfter(true); //For the textview to remain at the same place after the rotation
t.setAnimation(ranim);
回答by Yura Shinkarev
Worked for me:
为我工作:
public class VerticalTextView extends TextView {
private int _width, _height;
private final Rect _bounds = new Rect();
public VerticalTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalTextView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// vise versa
_height = getMeasuredWidth();
_width = getMeasuredHeight();
setMeasuredDimension(_width, _height);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(_width, _height);
canvas.rotate(-90);
TextPaint paint = getPaint();
paint.setColor(getTextColors().getDefaultColor());
String text = text();
paint.getTextBounds(text, 0, text.length(), _bounds);
canvas.drawText(text, getCompoundPaddingLeft(), (_bounds.height() - _width) / 2, paint);
canvas.restore();
}
private String text() {
return super.getText().toString();
}
}
xml:
xml:
<VerticalTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:background="@color/feedback_background"
android:padding="4dip"
android:text="@string/feedback"
android:textColor="@color/feedback_text_color"
android:textSize="@dimen/text_xlarge" />
回答by EminenT
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="xyz"
android:rotation="-90"
android:gravity="fill_vertical"/>
回答by alexhilton
Try this. It works fine for me. It can display one line of text vertically, but just one line. colors, size, paddings, margins and background all work fine.
尝试这个。这对我来说可以。它可以垂直显示一行文本,但只能显示一行。颜色、大小、填充、边距和背景都可以正常工作。
public class VerticalTextView extends TextView {
public VerticalTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalTextView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
final ColorStateList csl = getTextColors();
final int color = csl.getDefaultColor();
final int paddingBottom = getPaddingBottom();
final int paddingTop = getPaddingTop();
final int viewWidth = getWidth();
final int viewHeight = getHeight();
final TextPaint paint = getPaint();
paint.setColor(color);
final float bottom = viewWidth * 9.0f / 11.0f;
Path p = new Path();
p.moveTo(bottom, viewHeight - paddingBottom - paddingTop);
p.lineTo(bottom, paddingTop);
canvas.drawTextOnPath(getText().toString(), p, 0, 0, paint);
}
}
回答by Chris623
If you are using API 11 or later, you may try:
如果您使用的是 API 11 或更高版本,您可以尝试:
TextView t = (TextView) findViewById(R.id.txtview);
String txt = "Stackoverflow";
t.setText(txt);
t.setRotation(90); // 90 degree rotation
回答by Andrij
I'll show for you guys my example of custom vertical button with the rotated TextView in it:
我将向你们展示我的自定义垂直按钮示例,其中包含旋转的 TextView:
<!--Undo button-->
<LinearLayout
android:id="@+id/undo_points_pr_a"
android:layout_width="@dimen/zero_dp"
android:gravity="center"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
android:background="@color/timerUndoButton">
<ImageView
android:layout_width="@dimen/large"
android:layout_height="@dimen/large"
android:src="@drawable/undo_icon"
android:rotation="-90"
android:layout_marginBottom="@dimen/medium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/undo"
android:textSize="@dimen/small_medium_text"
android:rotation="-90"/>
</LinearLayout>
And this is how it looks in Android Studio:
这就是它在 Android Studio 中的样子:
And of course you have to modify this code to make it works for you. (in attributes like android:layout_width, android:layout_height, etc.)
当然,您必须修改此代码以使其适合您。(在 android:layout_width、android:layout_height 等属性中)
回答by Cameron A
I think the simplest answer to your question to write "Stackoverflow" vertically is to use an ordinary TextView, and since the text will wrap to the next line when narrowed, play around with the width of the TextView so there is one letter is on each line and if you need more space on the edge as a buffer increase the "padding" and/or "margin" of the TextView.
我认为对您垂直编写“Stackoverflow”的问题的最简单答案是使用普通的 TextView,并且由于文本在变窄时会换行到下一行,因此请使用 TextView 的宽度,以便每个字母上都有一个字母行,如果您需要更多的边缘空间作为缓冲区,请增加 TextView 的“填充”和/或“边距”。
回答by Ayaz Alifov
I provided a solution in another StackOverflow question. You can get vertical TextView by extending from View and overriding its onMeasure()
and onDraw()
methods. However, it will not support all TextView features, rather its main ones like padding, size, color and font.
我在另一个 StackOverflow问题中提供了解决方案。您可以通过从 View 扩展并覆盖其onMeasure()
和onDraw()
方法来获得垂直 TextView 。但是,它不会支持所有 TextView 功能,而是支持其主要功能,如填充、大小、颜色和字体。
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Build;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class VerticalLabelView extends View
{
private final String LOG_TAG = "VerticalLabelView";
private final int DEFAULT_TEXT_SIZE = 30;
private int _ascent = 0;
private int _leftPadding = 0;
private int _topPadding = 0;
private int _rightPadding = 0;
private int _bottomPadding = 0;
private int _textSize = 0;
private int _measuredWidth;
private int _measuredHeight;
private Rect _textBounds;
private TextPaint _textPaint;
private String _text = "";
private TextView _tempView;
private Typeface _typeface = null;
private boolean _topToDown = false;
public VerticalLabelView(Context context)
{
super(context);
initLabelView();
}
public VerticalLabelView(Context context, AttributeSet attrs)
{
super(context, attrs);
initLabelView();
}
public VerticalLabelView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initLabelView();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public VerticalLabelView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
initLabelView();
}
private final void initLabelView()
{
this._textBounds = new Rect();
this._textPaint = new TextPaint();
this._textPaint.setAntiAlias(true);
this._textPaint.setTextAlign(Paint.Align.CENTER);
this._textPaint.setTextSize(DEFAULT_TEXT_SIZE);
this._textSize = DEFAULT_TEXT_SIZE;
}
public void setText(String text)
{
this._text = text;
requestLayout();
invalidate();
}
public void topToDown(boolean topToDown)
{
this._topToDown = topToDown;
}
public void setPadding(int padding)
{
setPadding(padding, padding, padding, padding);
}
public void setPadding(int left, int top, int right, int bottom)
{
this._leftPadding = left;
this._topPadding = top;
this._rightPadding = right;
this._bottomPadding = bottom;
requestLayout();
invalidate();
}
public void setTextSize(int size)
{
this._textSize = size;
this._textPaint.setTextSize(size);
requestLayout();
invalidate();
}
public void setTextColor(int color)
{
this._textPaint.setColor(color);
invalidate();
}
public void setTypeFace(Typeface typeface)
{
this._typeface = typeface;
this._textPaint.setTypeface(typeface);
requestLayout();
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
try
{
this._textPaint.getTextBounds(this._text, 0, this._text.length(), this._textBounds);
this._tempView = new TextView(getContext());
this._tempView.setPadding(this._leftPadding, this._topPadding, this._rightPadding, this._bottomPadding);
this._tempView.setText(this._text);
this._tempView.setTextSize(TypedValue.COMPLEX_UNIT_PX, this._textSize);
this._tempView.setTypeface(this._typeface);
this._tempView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
this._measuredWidth = this._tempView.getMeasuredHeight();
this._measuredHeight = this._tempView.getMeasuredWidth();
this._ascent = this._textBounds.height() / 2 + this._measuredWidth / 2;
setMeasuredDimension(this._measuredWidth, this._measuredHeight);
}
catch (Exception e)
{
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
Log.e(LOG_TAG, Log.getStackTraceString(e));
}
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (!this._text.isEmpty())
{
float textHorizontallyCenteredOriginX = this._measuredHeight / 2f;
float textHorizontallyCenteredOriginY = this._ascent;
canvas.translate(textHorizontallyCenteredOriginY, textHorizontallyCenteredOriginX);
float rotateDegree = -90;
float y = 0;
if (this._topToDown)
{
rotateDegree = 90;
y = this._measuredWidth / 2;
}
canvas.rotate(rotateDegree);
canvas.drawText(this._text, 0, y, this._textPaint);
}
}
}