自定义TextView实现内容的旋转和偏移

在一些设计上,设计师会要求我们的文字以45度显示,或者135度显示(如下图“抽奖”),可是android本身并没有提供TextView在布局文件中实现旋转的标签,这时候就需要我们去自定义TextView,并且重写onDraw()方法实现效果。


下面,让我们去实现这个效果吧。


首先我们熟悉一下android view坐标系,android采用的X,Y横纵坐标系,X轴向右为正方向,Y轴向下为正方向,旋转方向为顺时针,如下图。


默认我们的文字是在TextView左上角显示的,我们要旋转的也就是这个文字,而文字绘制的时候也是有一个范围的,例如下图,文字外面我标识出来的方框。而我们的操作的都是以TextView坐标系的原点进行移动和旋转。


这样我们就确定我们要进行的操作,针对onDraw()对canvas进行translate(移动)或者rotate(旋转)操作坐标系,这里要说明的一点是,按我的习惯来,肯定是先进行偏移再进行旋转,旋转后的坐标系,想必你看着也会很难受吧。


下面是我重写的TextView的代码和效果图以及布局中的使用。我在Xml中自定义了标签,但是没有对标签内容进行约束,因为比较懒。。

package com.example.rtv;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * text旋转的textview
 * @author Kenneth
 *
 */
public class RotateTextView extends TextView {
	private static final   String NAME_SPACE = "http://www.baidu.com/apk/res/custom";
	
	private static final String ATTR_ROTATE = "rotate";
	private static final int DEFAULT_VALUE_ROTATE = 0;
	
	
	private static final String ATTR_TRANSLATE_X= "translateX";
	private static final String ATTR_TRANSLATE_Y = "translateY";
	private static final float DEFAULT_VALUE_TRANSLATE_X = 0f;
	private static final float DEFAULT_VALUE_TRANSLATE_Y = 0f;
	
	private int rotate = DEFAULT_VALUE_ROTATE;
	
	private float translateX = DEFAULT_VALUE_TRANSLATE_X;
	private float translateY = DEFAULT_VALUE_TRANSLATE_Y;
	
	public RotateTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		rotate = attrs.getAttributeIntValue(NAME_SPACE, ATTR_ROTATE, DEFAULT_VALUE_ROTATE);//旋转度数
		
		translateX = attrs.getAttributeFloatValue(NAME_SPACE, ATTR_TRANSLATE_X, DEFAULT_VALUE_TRANSLATE_X);//获取在布局中的x轴偏移百分比
		translateY = attrs.getAttributeFloatValue(NAME_SPACE, ATTR_TRANSLATE_Y, DEFAULT_VALUE_TRANSLATE_Y);//获取在布局中的y轴偏移百分比
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.translate(getMeasuredWidth()*translateX, getMeasuredHeight()*translateY);
		//首先偏移在旋转,是因为,如果先旋转,本身xy坐标系也会跟着旋转,之后在偏移会不方便我们的控制,也不直观
		canvas.rotate(rotate);
		super.onDraw(canvas);
	}
	
}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://www.baidu.com/apk/res/custom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.rtv.MainActivity$PlaceholderFragment" >

    <com.example.rtv.RotateTextView
        android:id="@+id/rotateTextView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:text="@string/hello_world"
        custom:rotate="45" />

    <com.example.rtv.RotateTextView
        android:id="@+id/rotateTextView2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/rotateTextView1"
        android:layout_alignParentTop="true"
        android:text="@string/hello_world"
        custom:rotate="135"
        custom:translateX="1" />

    <com.example.rtv.RotateTextView
        android:id="@+id/rotateTextView3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/rotateTextView1"
        android:layout_alignParentBottom="true"
        android:text="@string/hello_world"
        custom:rotate="135"
        custom:translateX="0.5"
        custom:translateY="0.5" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/rotateTextView2"
        android:layout_alignBottom="@+id/rotateTextView2"
        android:layout_toRightOf="@+id/rotateTextView2"
        android:text="向X轴正方向偏移100%,旋转135°" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/rotateTextView1"
        android:layout_marginTop="14dp"
        android:layout_toRightOf="@+id/rotateTextView1"
        android:text="原地不动,旋转45°" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/rotateTextView3"
        android:layout_marginTop="15dp"
        android:layout_toRightOf="@+id/rotateTextView3"
        android:text="x轴y轴偏移50%,旋转135°" />

    <com.example.rtv.RotateTextView
        android:id="@+id/RotateTextView01"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="@string/hello_world"
        />

</RelativeLayout>


  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android自定义TextView中显示全部内容,可以使用以下两种方法: 1. 使用setEllipsize()方法 通过设置setEllipsize()方法,可以在TextView的末尾添加省略号,从而指示文本被截断。你可以使用以下代码来实现: ``` yourTextView.setEllipsize(TextUtils.TruncateAt.END); yourTextView.setSingleLine(true); ``` 上述代码将设置TextView只显示一行并在末尾添加省略号。 2. 自定义TextView 你可以从TextView类继承一个新类,并覆盖onMeasure()方法以测量控件的高度和宽度。 你可以使用以下代码实现: ``` public class CustomTextView extends TextView { public CustomTextView(Context context) { super(context); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取TextView内容 CharSequence text = getText(); if (text != null) { //测量TextView的高度 int width = getMeasuredWidth(); int height = getMeasuredHeight(); int lineCount = getLineCount(); int lineHeight = getLineHeight(); int totalHeight = lineCount * lineHeight; if (totalHeight > height) { setMeasuredDimension(width, totalHeight); } } } } ``` 上述代码将测量TextView的高度,如果文本的高度超出了TextView的高度,则调整TextView的高度以适应文本。然后你可以使用此自定义TextView来显示你的文本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值