Nhãn dọc (xoay) trong Android


110

Tôi cần 2 cách để hiển thị nhãn dọc trong Android:

  1. Nhãn nằm ngang quay 90 độ ngược chiều kim đồng hồ (các chữ cái ở bên cạnh)
  2. Nhãn ngang với các chữ cái bên dưới chữ cái kia (giống như bảng hiệu cửa hàng)

Tôi có cần phát triển các widget tùy chỉnh cho cả hai trường hợp (một trường hợp) không, tôi có thể tạo TextView để hiển thị theo cách đó không và cách tốt để làm điều gì đó như vậy nếu tôi cần phải hoàn toàn tùy chỉnh?


Có thể thực hiện điều này trong XML kể từ API 11 (Android 3.0). stackoverflow.com/questions/3774770/…
chobok

Câu trả lời:


239

Đây là cách triển khai văn bản dọc thanh lịch và đơn giản của tôi, mở rộng TextView. Điều này có nghĩa là tất cả các kiểu tiêu chuẩn của TextView đều có thể được sử dụng, vì nó là TextView mở rộng.

public class VerticalTextView extends TextView{
   final boolean topDown;

   public VerticalTextView(Context context, AttributeSet attrs){
      super(context, attrs);
      final int gravity = getGravity();
      if(Gravity.isVertical(gravity) && (gravity&Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
         setGravity((gravity&Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
         topDown = false;
      }else
         topDown = true;
   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
      super.onMeasure(heightMeasureSpec, widthMeasureSpec);
      setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
   }

   @Override
   protected boolean setFrame(int l, int t, int r, int b){
      return super.setFrame(l, t, l+(b-t), t+(r-l));
   }

   @Override
   public void draw(Canvas canvas){
      if(topDown){
         canvas.translate(getHeight(), 0);
         canvas.rotate(90);
      }else {
         canvas.translate(0, getWidth());
         canvas.rotate(-90);
      }
      canvas.clipRect(0, 0, getWidth(), getHeight(), android.graphics.Region.Op.REPLACE);
      super.draw(canvas);
   }
}

Theo mặc định, văn bản được xoay từ trên xuống dưới. Nếu bạn đặt android :vity = "bottom", thì nó sẽ được vẽ từ dưới lên trên.

Về mặt kỹ thuật, nó đánh lừa TextView bên dưới khi nghĩ rằng đó là xoay bình thường (hoán đổi chiều rộng / chiều cao ở một số nơi), trong khi vẽ nó xoay. Nó cũng hoạt động tốt khi được sử dụng trong bố cục xml.

EDIT: đăng phiên bản khác, bên trên có vấn đề với hình ảnh động. Phiên bản mới này hoạt động tốt hơn, nhưng mất một số tính năng của TextView, chẳng hạn như marquee và các đặc điểm tương tự.

public class VerticalTextView extends TextView{
   final boolean topDown;

   public VerticalTextView(Context context, AttributeSet attrs){
      super(context, attrs);
      final int gravity = getGravity();
      if(Gravity.isVertical(gravity) && (gravity&Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
         setGravity((gravity&Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
         topDown = false;
      }else
         topDown = true;
   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
      super.onMeasure(heightMeasureSpec, widthMeasureSpec);
      setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
   }

   @Override
   protected void onDraw(Canvas canvas){
      TextPaint textPaint = getPaint(); 
      textPaint.setColor(getCurrentTextColor());
      textPaint.drawableState = getDrawableState();

      canvas.save();

      if(topDown){
         canvas.translate(getWidth(), 0);
         canvas.rotate(90);
      }else {
         canvas.translate(0, getHeight());
         canvas.rotate(-90);
      }


      canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());

      getLayout().draw(canvas);
      canvas.restore();
  }
}

CHỈNH SỬA phiên bản Kotlin:

import android.content.Context
import android.graphics.Canvas
import android.text.BoringLayout
import android.text.Layout
import android.text.TextUtils.TruncateAt
import android.util.AttributeSet
import android.view.Gravity
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.graphics.withSave

class VerticalTextView(context: Context, attrs: AttributeSet) : AppCompatTextView(context, attrs) {
    private val topDown = gravity.let { g ->
        !(Gravity.isVertical(g) && g.and(Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM)
    }
    private val metrics = BoringLayout.Metrics()
    private var padLeft = 0
    private var padTop = 0

    private var layout1: Layout? = null

    override fun setText(text: CharSequence, type: BufferType) {
        super.setText(text, type)
        layout1 = null
    }

    private fun makeLayout(): Layout {
        if (layout1 == null) {
            metrics.width = height
            paint.color = currentTextColor
            paint.drawableState = drawableState
            layout1 = BoringLayout.make(text, paint, metrics.width, Layout.Alignment.ALIGN_NORMAL, 2f, 0f, metrics, false, TruncateAt.END, height - compoundPaddingLeft - compoundPaddingRight)
            padLeft = compoundPaddingLeft
            padTop = extendedPaddingTop
        }
        return layout1!!
    }

    override fun onDraw(c: Canvas) {
        //      c.drawColor(0xffffff80); // TEST
        if (layout == null)
            return
        c.withSave {
            if (topDown) {
                val fm = paint.fontMetrics
                translate(textSize - (fm.bottom + fm.descent), 0f)
                rotate(90f)
            } else {
                translate(textSize, height.toFloat())
                rotate(-90f)
            }
            translate(padLeft.toFloat(), padTop.toFloat())
            makeLayout().draw(this)
        }
    }
}

2
Giải pháp của bạn vô hiệu hóa các liên kết trong TextView. Trên thực tế, các liên kết được gạch dưới, nhưng không phản hồi khi nhấp chuột.
Gurnetko

5
điều này có vấn đề với nhiều dòng và thanh cuộn.
Cynichniy Bandera

1
xin lỗi vì câu hỏi cơ bản của tôi, Nếu tôi có một TextView (trong một tệp XML) và tôi muốn xoay nó, tôi phải gọi lớp VerticalTextView như thế nào?
blackst0ne 15/02/15

2
@ blackst0ne thay vì thẻ <TextView>, hãy sử dụng thẻ chế độ xem tùy chỉnh: <com.YOUR_PACKAGE_NAME.VerticalTextView>
Daiwik Daarun

1
hoạt động tuyệt vời, trong trường hợp của tôi, tôi phải mở rộng android.support.v7.widget.AppCompatTextView thay vì TextView để làm cho thuộc tính style của tôi hoạt động
Louis

32

Tôi đã triển khai điều này cho dự án ChartDroid của mình . Tạo VerticalLabelView.java:

public class VerticalLabelView extends View {
    private TextPaint mTextPaint;
    private String mText;
    private int mAscent;
    private Rect text_bounds = new Rect();

    final static int DEFAULT_TEXT_SIZE = 15;

    public VerticalLabelView(Context context) {
        super(context);
        initLabelView();
    }

    public VerticalLabelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalLabelView);

        CharSequence s = a.getString(R.styleable.VerticalLabelView_text);
        if (s != null) setText(s.toString());

        setTextColor(a.getColor(R.styleable.VerticalLabelView_textColor, 0xFF000000));

        int textSize = a.getDimensionPixelOffset(R.styleable.VerticalLabelView_textSize, 0);
        if (textSize > 0) setTextSize(textSize);

        a.recycle();
    }

    private final void initLabelView() {
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);
        mTextPaint.setColor(0xFF000000);
        mTextPaint.setTextAlign(Align.CENTER);
        setPadding(3, 3, 3, 3);
    }

    public void setText(String text) {
        mText = text;
        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(), text_bounds);
        setMeasuredDimension(
                measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = text_bounds.height() + getPaddingLeft() + getPaddingRight();

            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        mAscent = (int) mTextPaint.ascent();
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = text_bounds.width() + getPaddingTop() + getPaddingBottom();

            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        float text_horizontally_centered_origin_x = getPaddingLeft() + text_bounds.width()/2f;
        float text_horizontally_centered_origin_y = getPaddingTop() - mAscent;

        canvas.translate(text_horizontally_centered_origin_y, text_horizontally_centered_origin_x);
        canvas.rotate(-90);
        canvas.drawText(mText, 0, 0, mTextPaint);
    }
}

Và trong attrs.xml:

<resources>
     <declare-styleable name="VerticalLabelView">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

Rất hữu ích. Đây là một liên kết đến phiên bản trung kế của mã dự án của bạn.google.com
p/chartdroid/source/browse//

Không hữu ích, văn bản không được hiển thị đầy đủ .. nó bị cắt từ phần cuối và phần đầu.
Siddarth G

Cũng được làm việc ở trên phiên bản Android 28
Ajeet Choudhary

Phiên bản của bạn là lựa chọn tốt nhất cho dự án của tôi nhưng setTextColor không hoạt động, tôi cũng muốn áp dụng một kiểu (background và fontFamily) có thể thực hiện được không?
Pablo R.

9

Một cách để đạt được những điều này sẽ là:

  1. Viết chế độ xem tùy chỉnh của riêng bạn và ghi đè onDraw (Canvas). Bạn có thể vẽ văn bản trên canvas và sau đó xoay canvas.
  2. Tương tự như 1. ngoại trừ lần này sử dụng Đường dẫn và vẽ văn bản bằng drawTextOnPath (...)

Vì vậy, trước khi tôi đi theo lộ trình đó (tôi đã xem xét phương thức onDraw cho TextView - nó rất lớn), tôi nhận thấy rằng toàn bộ sự khác biệt giữa TextView và Nút mở rộng là ID kiểu nội bộ (com.android.internal.R.attr.buttonStyle) để chỉ cần xác định một kiểu tùy chỉnh và mở rộng TextView tương tự như Button? Tôi đoán rằng câu trả lời sẽ là không vì nó có lẽ không thể nhập văn bản phong cách để bố trí verticaly
Bostone

Cách tiếp cận này có thực sự hiệu quả không? Tôi đã không có thành công và không có anh chàng này ... osdir.com/ml/Android-Developers/2009-11/msg02810.html
nategood

1
2. drawTextOnPath () vẽ văn bản giống như được xoay, giống như 1. Để viết các chữ cái này dưới chữ cái kia, hãy sử dụng \nsau mỗi ký tự hoặc nếu bạn có phông chữ có độ rộng cố định, hãy giới hạn độ rộng TextView chỉ vừa với một ký tự.
blub

8

Đã thử cả hai lớp VerticalTextView trong câu trả lời đã được phê duyệt và chúng hoạt động hợp lý.

Nhưng cho dù tôi đã thử gì đi nữa, tôi vẫn không thể định vị các VerticalTextView đó ở trung tâm của bố cục chứa (một RelativeLayout là một phần của mục được thổi phồng lên cho RecyclerView).

FWIW, sau khi quan sát xung quanh, tôi đã tìm thấy lớp VerticalTextView của yoog568 trên GitHub:

https://github.com/yoog568/VerticalTextView/blob/master/src/com/yoog/widget/VerticalTextView.java

mà tôi đã có thể đặt vị trí như mong muốn. Bạn cũng cần đưa định nghĩa thuộc tính sau vào dự án của mình:

https://github.com/yoog568/VerticalTextView/blob/master/res/values/attr.xml


1
Tôi thấy việc triển khai này thực sự dễ dàng!
Hashim Akhtar

4
check = (TextView)findViewById(R.id.check);
check.setRotation(-90);

Điều này làm việc cho tôi, tốt. Đối với các chữ cái đi xuống theo chiều dọc - tôi không biết.


7
nhưng nó thậm chí còn chiếm không gian theo chiều ngang và xoay nó theo chiều dọc
Prabs 20/02

3

Có một số điều nhỏ cần được chú ý trên.

Nó phụ thuộc vào bộ ký tự khi chọn cách xoay hoặc đường dẫn. ví dụ: nếu bộ ký tự mục tiêu giống như tiếng Anh và hiệu ứng mong đợi trông giống như,

a
b
c
d

bạn có thể có được hiệu ứng này bằng cách vẽ từng ký tự một, không cần xoay hoặc đường dẫn.

nhập mô tả hình ảnh ở đây

bạn có thể cần xoay hoặc đường dẫn để có được hiệu ứng này.

phần khó khăn là khi bạn cố gắng hiển thị các ký tự như tiếng Mông Cổ. glyph trong Kiểu chữ cần được xoay 90 độ, vì vậy drawTextOnPath () sẽ là một ứng cử viên tốt để sử dụng.


Làm thế nào nó có thể được thực hiện wayaround khác cho từ leftside để rightside
Rakesh

3
textview.setTextDirection (View.TEXT_DIRECTION_RTL) hoặc textview.setTextDirection (View.TEXT_DIRECTION_ANY_RTL) có thể hoạt động trên API cấp 17. bạn có thể kiểm tra nó.
Zephyr

thông minh và đơn giản
Abdulrahman Abdelkader

1

Sau câu trả lời của Pointer Null , tôi đã có thể căn giữa văn bản theo chiều ngang bằng cách sửa đổi onDrawphương pháp theo cách này:

@Override
protected void onDraw(Canvas canvas){
    TextPaint textPaint = getPaint();
    textPaint.setColor(getCurrentTextColor());
    textPaint.drawableState = getDrawableState();
    canvas.save();
    if(topDown){
        canvas.translate(getWidth()/2, 0);
        canvas.rotate(90);
    }else{
        TextView temp = new TextView(getContext());
        temp.setText(this.getText().toString());
        temp.setTypeface(this.getTypeface());
        temp.measure(0, 0);
        canvas.rotate(-90);
        int max = -1 * ((getWidth() - temp.getMeasuredHeight())/2);
        canvas.translate(canvas.getClipBounds().left, canvas.getClipBounds().top - max);
    }
    canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
    getLayout().draw(canvas);
    canvas.restore();
}

Bạn có thể cần thêm một phần Chiều rộng đo được của TextView để căn giữa văn bản nhiều dòng.


1

Bạn chỉ có thể thêm vào TextView của mình hoặc giá trị xoay xml View khác. Đây là cách dễ nhất và đối với tôi làm việc chính xác.

<LinearLayout
    android:rotation="-90"
    android:layout_below="@id/image_view_qr_code"
    android:layout_above="@+id/text_view_savva_club"
    android:layout_marginTop="20dp"
    android:gravity="bottom"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

   <TextView
       android:textColor="@color/colorPrimary"
       android:layout_marginStart="40dp"
       android:textSize="20sp"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Дмитриевский Дмитрий Дмитриевич"
       android:maxLines="2"
       android:id="@+id/vertical_text_view_name"/>
    <TextView
        android:textColor="#B32B2A29"
        android:layout_marginStart="40dp"
        android:layout_marginTop="15dp"
        android:textSize="16sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/vertical_text_view_phone"
        android:text="+38 (000) 000-00-00"/>

</LinearLayout>

Kết quả


0

Cách tiếp cận ban đầu của tôi để hiển thị văn bản dọc bên trong LinearLayout dọc như sau (đây là Kotlin, trong sử dụng Java, setRoatationv.v.):

val tv = TextView(context)
tv.gravity = Gravity.CENTER
tv.rotation = 90F
tv.height = calcHeight(...)
linearLabels.addView(tv)

cách tiếp cận số 1

Như bạn có thể thấy, vấn đề là TextView đi theo chiều dọc nhưng vẫn xử lý chiều rộng của nó như thể nó được định hướng theo chiều ngang! = /

Do đó, phương pháp số 2 bao gồm việc chuyển đổi thêm chiều rộng và chiều cao theo cách thủ công để giải thích điều này:

tv.measure(0, 0)
// tv.setSingleLine()
tv.width = tv.measuredHeight
tv.height = calcHeight(...)

cách tiếp cận số 2

Tuy nhiên, điều này dẫn đến việc các nhãn quấn quanh dòng tiếp theo (hoặc bị cắt nếu bạn setSingleLine) sau chiều rộng tương đối ngắn. Một lần nữa, điều này dẫn đến nhầm lẫn x với y.

Do đó, cách tiếp cận số 3 của tôi là bọc TextView trong một RelativeLayout. Ý tưởng là cho phép TextView bất kỳ chiều rộng nào nó muốn bằng cách mở rộng nó sang trái và phải (ở đây là 200 pixel theo cả hai hướng). Nhưng sau đó tôi đưa ra biên âm RelativeLayout để đảm bảo nó được vẽ dưới dạng một cột hẹp. Đây là mã đầy đủ của tôi cho ảnh chụp màn hình này:

val tv = TextView(context)
tv.text = getLabel(...)
tv.gravity = Gravity.CENTER
tv.rotation = 90F

tv.measure(0, 0)
tv.width = tv.measuredHeight + 400  // 400 IQ
tv.height = calcHeight(...)

val tvHolder = RelativeLayout(context)
val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
    LinearLayout.LayoutParams.WRAP_CONTENT)
lp.setMargins(-200, 0, -200, 0)
tvHolder.layoutParams = lp
tvHolder.addView(tv)
linearLabels.addView(tvHolder)

val iv = ImageView(context)
iv.setImageResource(R.drawable.divider)
linearLabels.addView(iv)

cách tiếp cận số 3

Theo một mẹo chung, chiến lược để một chế độ xem "giữ" một chế độ xem khác đã thực sự hữu ích đối với tôi trong việc định vị mọi thứ trong Android! Ví dụ: cửa sổ thông tin bên dưới ActionBar sử dụng cùng một chiến thuật!

Đối với văn bản xuất hiện như bảng hiệu cửa hàng, chỉ cần chèn dòng mới sau mỗi ký tự, ví dụ: "N\nu\nt\ns"sẽ là:

bảng hiệu cửa hàng ví dụ


-1

Tôi thích cách tiếp cận của @ kostmo. Tôi đã sửa đổi nó một chút, vì tôi gặp sự cố - cắt bỏ nhãn được xoay theo chiều dọc khi tôi đặt các thông số của nó làWRAP_CONTENT . Do đó, một văn bản không được nhìn thấy đầy đủ.

Đây là cách tôi đã giải quyết nó:

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

Nếu bạn muốn có một văn bản từ trên xuống, sau đó sử dụng topToDown(true)phương pháp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.