是否可以在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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:45:09  来源:igfitidea点击:

Is it possible to write vertically in a textview in android?

androidtextviewvertical-text

提问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 \nafter 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_widthand 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 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);
        }
    }
}