一、需求描述
最近,公司要做国际化,而且有个界面的右上角要做成类似如下所示的样式,

最开始的这个右上角角标是UI直接出图给我的,然后发现UI给了我好几个国家的角标,每个国家两张图片,分别是 xdpi分辨率下和xxdpi分辨率的。这样的话,关这个角标就得十几张小图片,oh my god,虽然每张图片也不大,才2k左右,但是加起来也有几十k啊,如果以后要支持的国家越来越多咋办? 因此我决定还是优化一下,减少apk的体积。

二、看实现效果


三、实现过程
3.1 自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="RotateTextView"><!--文本旋转的角度--><attr name="degree" format="integer" /></declare-styleable>
</resources>

自定义一个属性【degree】,表示文本旋转的角度3.2 自定义旋转的TextView

package com.oyp.view;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.Gravity;/*** 实现一个可选择的TextView,作用是:右上角的角标45°文本提示* </p>* created by OuyangPeng at 2019/1/10 下午 08:19** @author OuyangPeng*/
public class RotateTextView extends android.support.v7.widget.AppCompatTextView {/*** 默认选择45°角*/private static final int DEFAULT_DEGREES = 45;/*** 文本旋转的角度*/private int mDegrees;public RotateTextView(Context context) {this(context, null);}public RotateTextView(Context context, AttributeSet attrs) {super(context, attrs);this.setGravity(Gravity.CENTER);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateTextView);mDegrees = a.getInteger(R.styleable.RotateTextView_degree, DEFAULT_DEGREES);a.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());}@Overrideprotected void onDraw(Canvas canvas) {canvas.save();canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());canvas.rotate(mDegrees, this.getWidth() / 2f, this.getHeight() / 2f);super.onDraw(canvas);canvas.restore();}/*** 改变文本选择的角度** @param degrees 文本旋转的角度*/public void setDegrees(int degrees) {mDegrees = degrees;invalidate();}}

这个自定义的RotateTextView,继承自TextView,将TextView的文本内容旋转指定的degree角度。

3.3 引用自定义的RotateTextView
在下面的布局文件中,引用自定义的RotateTextView,并设置好一张默认的背景图,背景图资源如下所示:backgroud.png

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.oyp.view.RotateTextViewandroid:id="@+id/rotate_textview"android:layout_width="100dp"android:layout_height="100dp"android:layout_alignParentRight="true"android:background="@drawable/backgroud"android:gravity="center"android:paddingBottom="45dp"android:text="欧阳鹏"android:textColor="#fff"android:textSize="20sp"app:degree="45" /><TextViewandroid:id="@+id/rotate_degrees"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/rotate_textview"android:gravity="center"android:padding="10dp" /><SeekBarandroid:id="@+id/sb_rotate"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/rotate_degrees"android:layout_marginTop="20dp"android:max="100"android:progress="30" /><Buttonandroid:id="@+id/bt_change_bg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/sb_rotate"android:layout_centerHorizontal="true"android:layout_marginTop="20dp"android:text="替换TextView背景" /></RelativeLayout>

3.4 在Activity中控制旋转角度,以及替换背景

package com.oyp.view;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;public class MainActivity extends Activity {RotateTextView mText;TextView degrees;boolean isFirst = true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mText = (RotateTextView) findViewById(R.id.rotate_textview);degrees = (TextView) findViewById(R.id.rotate_degrees);SeekBar sbLean = (SeekBar) findViewById(R.id.sb_rotate);sbLean.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {mText.setDegrees(progress);degrees.setText("倾斜度:" + progress);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}});findViewById(R.id.bt_change_bg).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mText.setBackgroundResource(isFirst ? R.drawable.backgroud2 : R.drawable.backgroud);isFirst = !isFirst;}});}}

四、源代码
https://github.com/ouyangpeng/RotaTextView
五、提升
写完后,后来发现github上有个很好的例子,如下所示:
实现方式更好,完全由paint画出来的,这样又可以节省背景图片资源,并且以后如果UI替换背景颜色之类的,只需要修改相应的颜色值即可,完全不用加新的背景颜色。 我已经在项目中替换成下面的这种完全自定义TextView的方式了。

大家可以参考下!

https://github.com/HeZaiJin/SlantedTextView
我fork后,加入了注释便于理解,修改了一些代码,可参考下

https://github.com/ouyangpeng/SlantedTextView


自定义的属性

斜边展示的模式

如何自定义一个45度旋转的TextView,实现类似右上角文字角标的效果相关推荐

  1. 【我的Android进阶之旅】如何自定义一个45度旋转的TextView,实现类似右上角文字角标的效果

    一.需求描述 最近,公司要做国际化,而且有个界面的右上角要做成类似如下所示的样式, 最开始的这个右上角角标是UI直接出图给我的,然后发现UI给了我好几个国家的角标,每个国家两张图片,分别是 xdpi分 ...

  2. 自定义支持360度旋转的车模View

    自定义Touch360ImageView的代码如下: package com.example.myapplication;import android.content.Context; import ...

  3. 45度斜角地图菱形坐标转换

    !!! 此文章内容为转载,没有真实实践,只给需要的朋友提供思路,具体详细算法需要自己根据项目需求变动 !!! 我们要做一个45度游戏地图中,那么如何判断鼠标点中了哪一个碎片呢??如图:   也许你想到 ...

  4. COCOS2D-X中45度地图通过位置获得对应行列数中的三角变换理解

    晚上看COCOS2d-X的瓦片地图集这块,发现有2种地图,普通的和45度视角的.普通的通过位置获取所在行列数比较简单,大概就是具体的位置除以图素的宽高,而45度脚的方法则能够实现2.5D的效果,理解起 ...

  5. python添加文字水印中间旋转45度_pythonpdf添加水印

    0.用到两个扩展模块:ReportLab.PyPDF2. 1.创建水印PDF. 1).创建文字水印pdf文件 代码: #encoding=utf-8 #author: walker #date: 20 ...

  6. 45度地图之整体旋转

    假设有如下一幅地图(左边为数组地图,右边为对应的位图地图),这幅地图对应的是一个一维数组int map[16],且我们知道总共有4行,4列,对于数组中的元素我们可以通过下面的公式求出它所在的行列, 第 ...

  7. div旋转45度_为什么不要买旋转式电动牙刷:欧乐B电动牙刷D12开箱与体验

    引言 众所周知,电动牙刷主要分为声波式与旋转式.自从米家声波电动牙刷发布以来,我一直使用它作为宿舍主力牙刷,每次长假回家也会不嫌麻烦地带上它,不知不觉已经过去了3年,它并没有什么质量问题,仅仅是出现过 ...

  8. python添加文字水印中间旋转45度,Python添加pdf水印

    1.创建水印PDF. 1).创建文字水印pdf文件 代码:#encoding=utf-8 #author: walker #date: 2014-03-17 #function: 创建文字水印pdf ...

  9. 怎么将图片旋转45度?

    怎么将图片旋转45度?相信很多小伙伴在学习和工作的过程中,时常会需要将图片旋转45度,这个时候很多人习惯使用word和美图秀秀操作,或者使用系统自带的编辑器处理,但他们可能会很容易的把图片旋转90度, ...

最新文章

  1. [置顶] Android面试题目之三: 字符串转整形
  2. docker 部署 nginx+php+mysql
  3. 从一个实际的例子来了解线程套间模型(.NET and COM interop)
  4. 降低网站跳出率的技巧分享!
  5. idea 整合SSM(spring spring-mvc mybatis)
  6. linux c 多态原理,看了所谓的面向对象中靠继承多态实现的所谓重用 哥笑了
  7. 三十二楼层选几层最好_买房楼层怎么选?建筑学家建议:一栋楼不管几层,最好避开这3层...
  8. 关于Debug和Release之本质区别的讨论(转载)
  9. 2021 Axios 各种请求方式传递参数格式整理
  10. vc访问远程mysql_利用vc远程连接mysql一例
  11. OPPO Reno6系列将推Bobbi Brown联名版
  12. 中国荔枝市场趋势报告、技术动态创新及市场预测
  13. JAVA基础:从一道面试题看逻辑运算符与、|与||的区别
  14. oracle直接生成xlsx,【玩转Excel】Oracle PLSQL处理生成XLSX文件
  15. curl的安装及使用
  16. 如何彻底干净地卸载McAfee Agent
  17. 三插头内部结构图_三孔插座内部结构
  18. 2018-06-27 关于小米电力猫小猫一直黄灯闪烁不匹配的问题
  19. 12张图,二手房数据分析及可视化
  20. 利用iTerm2+oh-my-zsh+Dracula主题打造我的Mac终端利器

热门文章

  1. 【Materials Studio学习四】表面建模(沿某个晶面方向进行切面、表面吸附结构)
  2. vlive显示服务器不流畅,为什么手机登录vlive出现这个一直进不去
  3. Live_2014/12/21
  4. 清理磁盘有效方法(亲测)
  5. Ubunto系统安装BOA嵌入式web服务器
  6. python快速生成列表_python-用range()函数快速生成列表
  7. 五行字两张图描述拦截器
  8. 核磁共振光谱使帕金森氏蛋白质在分子水平研究实现突破
  9. Rainbond:如何制作一个可分享的云市应用?
  10. 时间状语前不用介词的几种情况