2010-05-22 58 views
26

假設你有一個正常的TextView,在其中寫入了「Stackoverflow」,是否可以將TextView旋轉-90°,讓S位於底部,W位於屏幕頂部? 當然,我可以把我的文字寫成圖片,旋轉並使用它,但我現在對文字很感興趣。 謝謝。是否有可能在android中的textview中垂直寫入?

+1

現在有可能做到這一點的XML:http://stackoverflow.com/questions/3774770/sideways-view-with-xml-android – chobok 2013-08-17 06:19:18

回答

36

你可以設置你的TextView,你通常會做

例如:

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

,寫在你的活動

  • 功能反轉字符在文本
  • 在每個字符後插入\n

然後將文本設置爲TextView。

如果你不想插入\n,你必須設置的android:layout_width大小和字體大小玩不要有2個字符在同一行,並沒有截斷

編輯 如果我裝修已經正確理解了你,你可以通過使用動畫來獲得你想要的。

例如

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" /> 

你將不得不與這個文件進行播放來定義您希望您的文本視圖放置。

在你的活動:

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); 
+0

是的,我雖然有關但這不是我解釋實際上,我不希望每個角色都在另一個角色之上,但他們都是-90°旋轉......這是可能的嗎? – Sephy 2010-05-22 19:02:46

+1

aha ok - 我想我知道你現在的意思 - 我不知道該怎麼做,但我會考慮它 – ccheneson 2010-05-22 21:53:58

+0

是的,這是個好主意。 – Sephy 2010-05-31 09:41:55

8

試試這個。這對我來說可以。它可以垂直顯示一行文本,但只顯示一行。顏色,尺寸,襯墊,邊距和背景都可以正常工作。

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

我在xml中使用類,它不起作用。你能告訴我如何使用它嗎?謝謝! – herbertD 2013-01-10 07:20:36

+0

您是否獲得解決方案herbertD? – 2013-09-18 11:34:25

+0

沒有爲我工作,文本沒有正確顯示 – Lancelot 2016-06-15 08:53:47

5

如果您正在使用API​​ 11或更高版本,您可以嘗試:

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

這將有問題與textview界限。 onMeasure()應該重新定義它。 – 2013-04-14 08:43:45

+0

我認爲這不是問題,是嗎?只需切換寬度和高度... – Chris623 2017-09-15 05:11:06

16

爲我工作:

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" /> 
+2

我知道這不是什麼大不了的事情,但是如果有一天像我一樣的n00b嘗試實現它並獲得一些錯誤,請嘗試使用:而不是僅僅是' '。無論如何,你的答案幫了我很多!謝謝! – xadun 2015-12-28 20:06:39

+0

完美的作品。謝謝! – Lancelot 2016-06-15 08:53:59

+0

如何旋轉到90度而不是-90? – Dharmendra 2016-06-22 10:48:53

3

我們可以設置使用XML視圖旋轉

<TextView android:id="@+id/txtview" 
     android:rotation="-90" 
     android:text="123" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content" /> 
+0

這有效,但之後很難使用UI編輯器 – Louis 2017-12-06 16:09:33

0

我在另一個StackOverflow question中提供了一個解決方案。您可以通過從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); 
     } 
    } 
}