web-dev-qa-db-fra.com

Est-il possible d'écrire verticalement dans un textview dans Android?

Supposons que vous avez un TextView normal, avec "Stackoverflow" écrit, est-il possible de faire pivoter le TextView de -90 °, pour avoir le S en bas et le W en haut de l'écran? Bien sûr Je pourrais écrire mon texte en tant qu’image, le faire pivoter et l’utiliser de cette façon, mais je suis intéressé par le texte en ce moment… .. Merci.

27
Sephy

Vous pouvez définir votre textview comme vous le feriez normalement 

par exemple:

 <TextView Android:id="@+id/txtview"
    Android:layout_height="fill_parent"
    Android:layout_width="wrap_content" />

et écrire une fonction dans votre activité

  • inverser les caractères de votre texte
  • insère \n après chaque caractère

puis définissez le texte sur TextView. 

Si vous ne voulez pas insérer le \n, vous devrez définir la taille de Android:layout_width et jouer avec la taille de la police pour que 2 caractères ne soient pas insérés sur la même ligne et sans troncature.

Edit Si je vous ai bien compris, vous pouvez obtenir ce que vous voulez en utilisant l’animation.

Par exemple 

Sous res/animation/myanim.xml:

<rotate  xmlns:Android="http://schemas.Android.com/apk/res/Android"
           Android:fromDegrees="0" 
           Android:toDegrees="-90"
           Android:pivotX="50%"
           Android:duration="0" />

Vous devrez jouer avec ce fichier pour définir où vous voulez placer votre vue texte.

Dans votre activité:

  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);
37
ccheneson

A travaillé pour moi:

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:

<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" />
17
Yura Shinkarev

Essaye ça. Ça fonctionne bien pour moi. Il peut afficher une ligne de texte verticalement, mais une seule ligne. les couleurs, la taille, les rembourrages, les marges et le fond fonctionnent parfaitement.

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);
    }
}
8
alexhilton

Si vous utilisez API 11 ou une version ultérieure, vous pouvez essayer:

TextView t = (TextView) findViewById(R.id.txtview);
String txt = "Stackoverflow";         
t.setText(txt);
t.setRotation(90); // 90 degree rotation
5
Chris623

Nous pouvons définir la rotation avec la vue XML 

 <TextView Android:id="@+id/txtview"
        Android:rotation="-90"
        Android:text="123"
        Android:layout_height="wrap_content"
        Android:layout_width="wrap_content" />
4
EminenT

Je vais vous montrer mon exemple de bouton vertical personnalisé avec le TextView pivoté:

<!--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>

Et voici à quoi ça ressemble dans Android Studio:

 And this is how it looks in Android Studio:

Et bien sûr, vous devez modifier ce code pour qu'il fonctionne pour vous. (dans des attributs tels qu'Android: layout_width, Android: layout_height, etc.)

1
Andrij

J'ai fourni une solution dans un autre StackOverflow question . Vous pouvez obtenir TextView vertical en étendant de View et en remplaçant ses méthodes onMeasure() et onDraw(). Cependant, il ne supportera pas toutes les fonctionnalités de TextView, mais ses principales comme le rembourrage, la taille, la couleur et la police.

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);
        }
    }
}
0
Sa Qada