TextView 是我們最常用的View,經(jīng)常使用它進(jìn)行顯示文字嘁傀,但使用TextView來顯示圖片變顯的不那么方便了,為此我們需要實現(xiàn)可用于處理要需要格式化TextView赌蔑、可設(shè)置圖片、文字的顏色然走,尺寸弥鹦,及可點擊的事件迄本、簡單的圖文混排的TextView.
格式化需求
開發(fā)中常要使用文字組合來填充TextView,如金額:100元
而經(jīng)常變動的是TextView100
數(shù)字這部分文字胚委,并非全部的文字挟鸠。這種場景下,標(biāo)簽化TextView十分必要亩冬。在沒引入標(biāo)簽化之前對于這種需求我們需要格式化字串然后設(shè)置到TextView中艘希。
//xml中的TextView
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
//設(shè)置文字
setText(String.format("金額:%1$S元","100"))
經(jīng)常寫格式化這部分代碼,不適合聰明(懶惰)的你的設(shè)定硅急,于是我們可以把格式這部分代碼固定到TextView的xml中覆享,然后實現(xiàn)setTextFormat()
方法使用xml中的format
字段去格式化字符再設(shè)置到TextView中,如下:
//xml中的標(biāo)簽化的TextView
<cn.ymex.view.label.TextLabel
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:format="金額:%1$s元" />
//設(shè)置文字
setTextFormat("100")
標(biāo)簽固定化
這里我們通過標(biāo)簽化基本上可以解決一部分這種需要求营袜,但產(chǎn)品經(jīng)理說我覺得這應(yīng)該在金額后面加上個vip圖標(biāo)(金額: 假裝vip圖標(biāo) 100元
)
如果要實現(xiàn)這種加圖標(biāo)的需求撒顿,至少我們會在再增加一個TextView 到布局中,格式化的文字也要更改荚板。像這樣:
//xml 增加vip圖標(biāo)
<LinearLayout
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:text="金額"
android:drawableRight="@mipmap/ic_vip"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
//格式化文字改變凤壁。
textView.setText(String.format(":%1$s元"),"100)
小小的需求,我們至少要變動兩個地方的代碼,我的需求屏蔽這種變動跪另,我們知道TextView 其實可以用SpannableString
和ImageSpan
設(shè)置圖文的客扎。我們可以嘗試封裝一個固定的頭和尾部到TextView中,通過頭部與尾部和中間文字的組合來屏蔽這種變動罚斗,于是我們可像下面這樣寫代碼徙鱼。
//xml中的標(biāo)簽化的TextView
<cn.ymex.view.label.TextLabel
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="100"
app:startDrawable="@mipmap/ic_vip"
app:startDrawableInLast="true"
app:startDrawableSize="24dp"
app:endText="元"
app:startText=" 金額:" />
//設(shè)置文字
setText("100")
SpanCell與文字事件
我們偶爾會遇到那種部分文字改變顏色和部分文字可點擊。對于這種需求我們經(jīng)常是通過textView組合或使用設(shè)置html代碼來實現(xiàn)。
通過上面的種種對于文字與圖片需求袱吆,歸根是一種對于圖文和文字排序的問題厌衙,是的,表象下隱藏的東西就這么明顯绞绒。圖片文字組合變化不外乎兩種婶希,圖片在前文字在后 或文字在前圖片在后。 于我們把圖片和文字放在一塊蓬衡,這就是SpanCell喻杈。SpaaCell由一個文字單元和一個圖片單元組成。一個圖片單元只能放一張圖片狰晚,文字單元實現(xiàn)了對文字設(shè)置顏色筒饰,大小,事件等壁晒。
所以對于文字點擊的需求變的再簡單不過瓷们。
SpanCell spanCell = SpanCell.build()
.textColor(Color.parseColor("#887acc"))
.text("《用戶協(xié)議》");
spanCell.setClickableSpan(new SpanCell.OnClickListener() {
@Override
public void onClick(View view, SpanCell spanCell) {
//... 事件處理
}
});
textLabel.setText(spanCell);
TextView使用Spancell
普通的TextView 是可以使用Spancell
的,但注意的是如果 是ListView中的TextView使用Spancell,會有事件沖突的問題(使用TextLabel代替就能解決)秒咐。
SpanCell spanCell = SpanCell.build()
.textColor(Color.parseColor("#887acc"))
.text("《用戶協(xié)議》");
spanCell.setClickableSpan(new SpanCell.OnClickListener() {
@Override
public void onClick(View view, SpanCell spanCell) {
//... 事件處理
}
});
//textview 設(shè)置 spanCell
textView.setText(spanCell.getSpannable());
圖文混排
有SpanCell,我們只要組合多個SpanCell谬晕,那么這可實現(xiàn)基于的混排效果。
ImageSpannable forgimg = new ImageSpannable(context, R.mipmap.frog);
SpanCell span1 = SpanCell.build()
.text("一只小青蛙")
.imageSpanInLast(true)
.imageSpan(forgimg);
ImageSpannable deerimg = new ImageSpannable(context, R.mipmap.deer);
SpanCell span2 = SpanCell.build()
.text(",發(fā)現(xiàn)了一只受傷的小鹿")
.imageSpan(deerimg)
.imageSpanInLast(true);
ImageSpannable hippoimg = new ImageSpannable(context, R.mipmap.hippo, ImageSpannable.ALIGN_FONTCENTER);
hippoimg.setSize(64,64);
SpanCell span3 = SpanCell.build()
.text("于是它去尋求小牛")
.imageSpanInLast(true)
.imageSpan(hippoimg);
ImageSpannable owlimg = new ImageSpannable(context, R.mipmap.owl, ImageSpannable.ALIGN_FONTCENTER);
owlimg.setSize(160, 160);
SpanCell span4 = SpanCell.build()
.imageSpanInLast(true).
text("的幫助携取。小牛說攒钳,不幫不幫就不幫。雷滋。于是小青蛙又去向其他 動物尋求幫助不撑。于是它找到了貓頭鷹").imageSpan(owlimg);
SpanCell span5 = SpanCell.build()
.text(",于是他們一起愉快的喝可樂 !呵呵");
textLabel.setText(span1,span2,span3,span4,span5);
總結(jié):
TextLabel 雖然實現(xiàn)能應(yīng)對圖文排序的變化惊豺,但還是保留了一個固定的頭片段(spancell)和一個尾片段及其他便利的特性燎孟。這樣做的目的是方便有固定化標(biāo)簽、格式化的場景尸昧。這些設(shè)計都是無痛的揩页,只要你愿意,完全可使用TextLabel代替TextView烹俗。
GitHub源碼地址:github.com/ymex/textlabel