本文來(lái)自 Crocutax 的博客 , 轉(zhuǎn)載請(qǐng)注明出處 http://www.crocutax.com
本篇文章主要是記錄一下日常開(kāi)發(fā)中,對(duì)TextView控件的一些使用過(guò)的技巧的整理,僅限自己開(kāi)發(fā)中用到的一些點(diǎn),并不全面,也沒(méi)有太多技術(shù)含量.只是為了方便一些程序員小伙伴用到得時(shí)候,搜到之后拿來(lái)即用。如發(fā)現(xiàn)有錯(cuò)誤,煩請(qǐng)幫忙指證,謝謝!
本文主要羅列了以下技巧點(diǎn):
- 通過(guò)換行符換行
- 在TextView中引入圖片資源
- 動(dòng)態(tài)變換TextView中的圖片資源
- 設(shè)置字體和樣式
- 加載自定義字體
- 限制TextView字符數(shù)
- 多文字展示中常見(jiàn)的【顯示全部-收起】
- 價(jià)格標(biāo)簽與下劃線
- 文字描邊與陰影
- 跑馬燈效果
- 設(shè)置字間距與行間距
Demo動(dòng)態(tài)圖如下:
1.通過(guò)換行符換行
非?;A(chǔ)的換行符“\n”的使用,有些時(shí)候在一些復(fù)雜ItemView中,會(huì)有上下兩行TextView羅列用來(lái)展示內(nèi)容的情況,如果兩行TextView的字體樣式一致,并且數(shù)據(jù)來(lái)源固定或統(tǒng)一,此時(shí)可以考慮用一個(gè)TextView搞定,能少繪制一個(gè)TextView,甚至是用來(lái)包裹他們的LineaLayout也省了。
代碼:
<!--普通換行-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="'好好學(xué)習(xí)\n天天向上" />
效果圖:
2.在TextView中引入圖片資源
一個(gè)圖片+幾個(gè)文字的的控件搭配在任何項(xiàng)目中都太常見(jiàn)了,比如
這個(gè)可以用LineaLayout來(lái)水平包裹ImageView+TextView,也可以直接通過(guò)TextView的drawableXxx屬性來(lái)將圖片資源嵌入TextView中。其中Xxx是指圖片擺放的位置,包括
- drawableLeft 左側(cè)
- drawableRight 右側(cè)
- 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="點(diǎn)下試試" />
效果圖:
3.動(dòng)態(tài)變換TextView中的圖片資源
上面談到的圖片+文字的兩種布局方式中,LinearLayout水平包裹的方式雖然略顯臃腫,但是動(dòng)態(tài)替換其中的圖片比較方便,直接操作包裹的ImageView即可。而TextView內(nèi)嵌圖片的方式,在動(dòng)態(tài)替換圖片資源時(shí),略顯繁瑣,不過(guò)也很簡(jiǎn)單,主要是對(duì)Drawable對(duì)象的操作。
代碼:
//1.通過(guò)圖片資源獲取Drawable對(duì)象
Drawable showPwdDrawable = getResources().getDrawable(R.drawable.password_show);
//2.設(shè)置Drawable對(duì)象的顯示范圍
showPwdDrawable.setBounds(0, 0, showPwdDrawable.getMinimumWidth(), showPwdDrawable.getMinimumHeight());
//3.將Drawable設(shè)置給TextView(方法中的4個(gè)參數(shù),分別對(duì)應(yīng)Drawable相對(duì)于文字而言放置的位置:左上右下四個(gè)位置)
textview.setCompoundDrawables(null, null, showPwdDrawable, null);
效果圖:
4.設(shè)置字體和樣式
TextView的typeface屬性可以用來(lái)設(shè)置字體,默認(rèn)有4種類(lèi)型
- normal
- sans
- serif
- monospace
textStyle屬性可以用來(lái)設(shè)置樣式,默認(rèn)有3種類(lèi)型:
- bold 粗體
- italic 斜體
- normal 正常(默認(rèn))
代碼:
<!--粗體+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" />
效果圖:
5.加載自定義字體
除了系統(tǒng)默認(rèn)提供的幾種字體以外,還可以加載自定義的字體.
注意:字體文件必須是真正的ttf(TrueTypeFont)文件,否則要么沒(méi)有效果 , 要么直接拋java.lang.RuntimeException: Font asset not found fonts異常,.
步驟:
1.將ttf字體文件放在Module的src/main/assets/fonts/目錄下
2.加載字體文件到內(nèi)存,并設(shè)置給TextView
//通過(guò)Typeface的靜態(tài)方法加載字體資源到內(nèi)存
Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/華文行楷.ttf");
//將typeface設(shè)置給TextView
tvCustomTypeface.setTypeface(typeface);
效果圖:
6.限制TextView字符數(shù)
為了UI效果或者屏幕適配等因素,經(jīng)常需要對(duì)TextView展示出來(lái)的字?jǐn)?shù)做限制,其實(shí)也很簡(jiǎn)單通過(guò)3個(gè)屬性就可以搞定:
- ellipsize 省略位置
- maxEms 最大字符數(shù),一個(gè)漢字占1個(gè)字符,1個(gè)英文/符號(hào)占半個(gè)字符;從第maxEms+1位置開(kāi)始用省略號(hào)代替
- maxLines 行數(shù)限制(singleLine也行,但是已被標(biāo)記為Deprecated)
<!--限制字符數(shù)-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:maxEms="7"
android:text="@string/study" />
效果圖:
7.多文字展示中常見(jiàn)的【顯示全部-收起】
這個(gè)比較常見(jiàn),比如看個(gè)朋友圈或者微博,不會(huì)直接將文字內(nèi)容全部羅列展示出來(lái),而是末尾有個(gè)[更多]or[顯示全部],點(diǎn)擊后就會(huì)將文字內(nèi)容全部顯示出來(lái).(當(dāng)然也有點(diǎn)擊后跳轉(zhuǎn)頁(yè)面的,跟這次談的內(nèi)容無(wú)關(guān),這是舉個(gè)例子)
實(shí)現(xiàn)起來(lái)也比較簡(jiǎn)單,通過(guò)setMaxLines(int maxLines)方法即可達(dá)到目的.
每次點(diǎn)擊[顯示全部-收起]按鈕時(shí) , 執(zhí)行以下事件 , 即可實(shí)現(xiàn) . 效果圖請(qǐng)看文章開(kāi)頭的gif圖.
showAll = !showAll;
if(showAll){
tvShowAll.setMaxLines(2);
btnShowAll.setText("查看全部");
}else {
tvShowAll.setMaxLines(20);
btnShowAll.setText("收起");
}
注意
開(kāi)發(fā)中當(dāng)碰到上述問(wèn)題時(shí),同時(shí)必然存在一個(gè)前提場(chǎng)景,那就是根據(jù)數(shù)據(jù)內(nèi)容來(lái)動(dòng)態(tài)判斷是該展示 [顯示全部]按鈕.
此時(shí)需要?jiǎng)討B(tài)獲取textview加載了內(nèi)容后占據(jù)了幾行,比如我們需求規(guī)定超過(guò)3行,末尾就要省略+展示[顯示更多] . 此時(shí)需要用到TextView的getLineCount()方法.
getLineCount() 方法
Return the number of lines of text, or 0 if the internal Layout has not been built.返回TextView內(nèi)容的行數(shù) , 如果沒(méi)內(nèi)容則返回0
需要注意的時(shí),此方法不能直接在onCreate()中調(diào)用,因?yàn)榇藭r(shí)TextView的內(nèi)容可能還沒(méi)有加載完畢導(dǎo)致獲取到得行數(shù)為0.可以用如下方式來(lái)決定[顯示全部]按鈕是否顯示
textview.post(new Runnable() {
@Override
public void run() {
if(textview.getLineCount() > 3){
//textview內(nèi)容大于行數(shù)限制,展示[顯示全部]按鈕"
}else {
//textview內(nèi)容小于等于行數(shù)限制"
}
}
});
8.價(jià)格標(biāo)簽與下劃線
在商品交易類(lèi)模塊必然牽扯到商品價(jià)格 , 而一般出于促銷(xiāo)目的,會(huì)在界面上展示出商品原價(jià)和現(xiàn)價(jià) ,原價(jià)遠(yuǎn)高于現(xiàn)價(jià), 同時(shí)再把原價(jià)劃上一條橫線表示作廢以刺激客戶(hù)消費(fèi) . 這是很常見(jiàn)的 價(jià)格促銷(xiāo)UI.
這個(gè)效果需要TextView通過(guò)Paint對(duì)象來(lái)繪制,系統(tǒng)都封裝好了,我們簡(jiǎn)單使用即可.
第一步,正常定義XML
<!--價(jià)格標(biāo)簽-->
<!--中間橫線-->
<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" />
第二步,通過(guò)TextView的Paint對(duì)象來(lái)劃線
//中間橫線
tvLineMiddle.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG );
//下劃線
tvLineEnd.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
效果圖:
9.文字描邊與陰影
涉及屬性:
- 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" />
效果圖:
10.跑馬燈效果
現(xiàn)在這種效果用的越來(lái)越少了,不贅述了.
直接上代碼,效果圖見(jiàn)文章頂部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" />
11.設(shè)置字間距與行間距
涉及屬性:
- letterSpacing 字間距
- Must be a floating point value, such as "0.2". (0.0~1.0 stands for a letter) -----必須是0.0~1.0之間的小數(shù),以一個(gè)字母為空間標(biāo)準(zhǔn)
- 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). -----直接通過(guò)px,dp,sp等單位指定行距,例如14.5sp
- lineSpacingMultiplier 行間距的倍數(shù)
- Must be a floating point value, such as "1.2".----比如1.2倍
直接使用上述屬性,即可達(dá)到設(shè)置字間距,行間距的目的,代碼如下,效果圖見(jiàn)文章頂部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" />