本文来自 Crocutax 的博客 , 转载请注明出处 http://crocutax.com
本篇文章主要是记录一下日常开发中,对TextView
控件的一些使用过的技巧的整理,仅限自己开发中用到的一些点,并不全面,也没有太多技术含量.只是为了方便一些程序员小伙伴用到得时候,搜到之后拿来即用。如发现有错误,烦请帮忙指证,谢谢!
本文主要罗列了以下技巧点:
- 通过换行符换行
- 在TextView中引入图片资源
- 动态变换TextView中的图片资源
- 设置字体和样式
- 加载自定义字体
- 限制TextView字符数
- 多文字展示中常见的【显示全部-收起】
- 价格标签与下划线
- 文字描边与阴影
- 跑马灯效果
- 设置字间距与行间距
Demo动态图如下:
通过换行符换行
非常基础的换行符“\n”
的使用,有些时候在一些复杂ItemView中,会有上下两行TextView罗列用来展示内容的情况,如果两行TextView的字体样式一致,并且数据来源固定或统一,此时可以考虑用一个TextView搞定,能少绘制一个TextView,甚至是用来包裹他们的LineaLayout也省了。
代码:
<!--普通换行-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="'好好学习\n天天向上" />
效果图:
在TextView中引入图片资源
一个图片+几个文字的的控件搭配在任何项目中都太常见了,比如
这个可以用LineaLayout来水平包裹ImageView+TextView,也可以直接通过TextView的drawableXxx属性来将图片资源嵌入TextView中。其中Xxx是指图片摆放的位置,包括
- drawableLeft 左侧
- drawableRight 右侧
- drawableTop 上方
- drawableBottom 下方
- drawableStart 控件空间的起始位置
- drawableEnd 控件空间的末尾
代码:
<TextView
android:id="@+id/tv_drawable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:drawablePadding="10dp"
android:drawableRight="@drawable/password_hide"
android:gravity="center"
android:text="点下试试" />
效果图:
动态变换TextView中的图片资源
上面谈到的图片+文字的两种布局方式中,LinearLayout水平包裹的方式虽然略显臃肿,但是动态替换其中的图片比较方便,直接操作包裹的ImageView即可。而TextView内嵌图片的方式,在动态替换图片资源时,略显繁琐,不过也很简单,主要是对Drawable对象的操作。
代码:
//1.通过图片资源获取Drawable对象
Drawable showPwdDrawable = getResources().getDrawable(R.drawable.password_show);
//2.设置Drawable对象的显示范围
showPwdDrawable.setBounds(0, 0, showPwdDrawable.getMinimumWidth(), showPwdDrawable.getMinimumHeight());
//3.将Drawable设置给TextView(方法中的4个参数,分别对应Drawable相对于文字而言放置的位置:左上右下四个位置)
textview.setCompoundDrawables(null, null, showPwdDrawable, null);
效果图:
设置字体和样式
TextView的typeface
属性可以用来设置字体,默认有4种类型
- normal
- sans
- serif
- monospace
textStyle
属性可以用来设置样式,默认有3种类型:
- bold
- italic
- normal
代码:
<!--粗体+serif样式-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/study"
android:textStyle="bold"
android:typeface="serif" />
<!--斜体 + monospace样式-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/study"
android:textStyle="italic"
android:typeface="monospace" />
效果图:
加载自定义字体
除了系统默认提供的几种字体以外,还可以加载自定义的字体.
注意:字体文件必须是真正的ttf(TrueTypeFont)文件,否则要么没有效果 , 要么直接抛java.lang.RuntimeException: Font asset not found fonts
异常,.
步骤:
1.将ttf字体文件放在Module的src/main/assets/fonts/
目录下
2.加载字体文件到内存,并设置给TextView
//通过Typeface的静态方法加载字体资源到内存
Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/华文行楷.ttf");
//将typeface设置给TextView
tvCustomTypeface.setTypeface(typeface);
效果图:
限制TextView字符数
为了UI效果或者屏幕适配等因素,经常需要对TextView展示出来的字数做限制,其实也很简单通过3个属性就可以搞定:
- ellipsize 省略位置
- maxEms 最大字符数,一个汉字占1个字符,1个英文/符号占半个字符;从第maxEms+1位置开始用省略号代替
- maxLines 行数限制(singleLine也行,但是已被标记为Deprecated)
<!--限制字符数-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:maxEms="7"
android:text="@string/study" />
效果图:
多文字展示中常见的【显示全部-收起】
这个比较常见,比如看个朋友圈或者微博,不会直接将文字内容全部罗列展示出来,而是末尾有个[更多]or[显示全部],点击后就会将文字内容全部显示出来.(当然也有点击后跳转页面的,跟这次谈的内容无关,这是举个例子)
实现起来也比较简单,通过setMaxLines(int maxLines)方法即可达到目的.
每次点击[显示全部-收起]按钮时 , 执行以下事件 , 即可实现 . 效果图请看文章开头的gif图.
showAll = !showAll;
if(showAll){
tvShowAll.setMaxLines(2);
btnShowAll.setText("查看全部");
}else {
tvShowAll.setMaxLines(20);
btnShowAll.setText("收起");
}
注意
开发中当碰到上述问题时,同时必然存在一个前提场景,那就是根据数据内容来动态判断是该展示 [显示全部]按钮.
此时需要动态获取textview加载了内容后占据了几行,比如我们需求规定超过3行,末尾就要省略+展示[显示更多] . 此时需要用到TextView的getLineCount()
方法.
getLineCount() 方法
Return the number of lines of text, or 0 if the internal Layout has not been built.返回TextView内容的行数 , 如果没内容则返回0
需要注意的时,此方法不能直接在onCreate()中调用,因为此时TextView的内容可能还没有加载完毕导致获取到得行数为0.可以用如下方式来决定[显示全部]按钮是否显示
textview.post(new Runnable() {
@Override
public void run() {
if(textview.getLineCount() > 3){
//textview内容大于行数限制,展示[显示全部]按钮"
}else {
//textview内容小于等于行数限制"
}
}
});
价格标签与下划线
在商品交易类模块必然牵扯到商品价格 , 而一般出于促销目的,会在界面上展示出商品原价和现价 ,原价远高于现价, 同时再把原价划上一条横线表示作废以刺激客户消费 . 这是很常见的 价格促销UI.
这个效果需要TextView通过Paint对象来绘制,系统都封装好了,我们简单使用即可.
第一步,正常定义XML
<!--价格标签-->
<!--中间横线-->
<TextView
android:id="@+id/tv_line_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥20.00"
android:textColor="@android:color/holo_red_dark" />
<!--底部横线-->
<TextView
android:id="@+id/tv_line_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="¥20.00"
android:textColor="@android:color/holo_red_dark" />
第二步,通过TextView的Paint对象来划线
//中间横线
tvLineMiddle.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG );
//下划线
tvLineEnd.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
效果图:
文字描边与阴影
涉及属性:
- shadowColor : Place a blurred shadow of text underneath the text, drawn with the specified color.用指定颜色在文字下方绘制模糊的阴影
- shadowDx Horizontal offset of the text shadow. 文字阴影的横向/水平偏移量
- shadowDy Vertical offset of the text shadow. 文字阴影的纵向/垂直偏移量
- shadowRadius Blur radius of the text shadow. 阴影的半径范围
<!--文字描边与阴影-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shadowColor="#ff0000"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="5"
android:text="@string/study" />
效果图:
跑马灯效果
现在这种效果用的越来越少了,不赘述了.
直接上代码,效果图见文章顶部gif:
<!--跑马灯效果-->
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="@string/poem" />
设置字间距与行间距
涉及属性:
- letterSpacing 字间距
- Must be a floating point value, such as “0.2”. (0.0~1.0 stands for a letter) —–必须是0.0~1.0之间的小数,以一个字母为空间标准
- lineSpacingExtra 行距
- Must be a dimension value, which is a floating point number appended with a unit such as “14.5sp”. Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters). —–直接通过px,dp,sp等单位指定行距,例如14.5sp
- lineSpacingMultiplier 行间距的倍数
- Must be a floating point value, such as “1.2”.—-比如1.2倍
直接使用上述属性,即可达到设置字间距,行间距的目的,代码如下,效果图见文章顶部gif
<!--字间距0.5字符-->
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/darker_gray"
android:letterSpacing="0.5"
android:text="@string/poem" />
<!--行间距10sp-->
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/holo_green_light"
android:lineSpacingExtra="10sp"
android:text="@string/poem" />
<!--行间距1.8倍-->
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:lineSpacingMultiplier="1.8"
android:text="@string/poem" />