文字格式化-----String.format()
Android官方推薦TextView在設置內容的時候應該通過String文件來設置內容,而通過String文件獲取內容,如:
getResources().getString(R.string.tv_content,"內容1","內容2")
實際上是通過String.Format( )(注:java中的方法)格式化文字,所以這裏記錄下String.Format( )格式化主要用到的幾個點,
佔位符說明
佔位符完整格式爲: %[index$][標識]*[最小寬度][.精度]轉換符 。
針對不同數據類型的格式化,佔位符的格式將有所裁剪。
% ,佔位符的其實字符,若要在佔位符內部使用%,則需要寫成 %% 。
[index$] ,位置索引從1開始計算,用於指定對索引相應的實參進行格式化並替換掉該佔位符。
[標識] ,用於增強格式化能力,可同時使用多個 [標識] ,但某些標識是不能同時使用的。
[最小寬度] ,用於設置格式化後的字符串最小長度,若使用 [最小寬度] 而無設置 [標識] ,那麼當字符串長度小於最小寬度時,則以左邊補空格的方式湊夠最小寬度。
[.精度] ,對於浮點數類型格式化使用,設置保留小數點後多少位。
轉換符 ,用於指定格式化的樣式,和限制對應入參的數據類型。
常用的轉換符說明:
%a 浮點數 (除了BigDecimal) 浮點數的十六進制輸出
%b 任何類型 如果爲非空則爲“true”,爲空則爲“false”
%c 字符 Unicode字符
%d 證書(包括byte, short, int, long, bigint) 十進制整數
%e 浮點數 科學計數的十進制數
%f 浮點數 十進制數
%g 浮點數 十進制數,根據值和精度可能以科學計數法顯示
%h 任何類型 通過hashCode()方法輸出的16進制數
%n 無 平臺相關的換行符
%o 整數(包括byte, short, int, long, bigint) 八進制數
%s 任何類型 字符串
%t 日期/時間 (包含long, Calendar, Date 和TemporalAccessor) %t是日期/時間轉換的前綴。後面還需要跟其他的標識,請參考下面的日期/時間轉換。
%x 整數(包含byte, short, int, long, bigint) 十六進制字符串
常見的空格佔位符(轉)
  == 普通的英文半角空格
  == ==   == no-break space (普通的英文半角空格但不換行)
  == 中文全角空格 (一箇中文寬度)
  ==   == en空格 (半個中文寬度)
  ==   == em空格 (一箇中文寬度)
  == 四分之一em空格 (四分之一中文寬度)
相比平時的空格( ),nbsp擁有不間斷(non-breaking)特性。即連續的nbsp會在同一行內顯示。即使有100個連續的nbsp,瀏覽器也不會把它們拆成兩行
加載Html
常見支持的html標籤
<b> 表示粗體文本。
<i> 表示斜體文本。
<u> 表示 下劃線 文本
TextView是可以加載html的不過需要一些轉換,如下
String string = "<a><u>你好啊</u></a>";
Spanned spanned = Html.fromHtml(string);
textView.setText(spanned);
如果要是在資源文件String中的話需要注意2點
1,在資源文件中所有的 < 都要用 <
替代,
在上面的String string = "<a><u>你好啊</u></a>"; 在資源文件中應該這樣表示
<string name="text_content"><a><u>你好啊</u></a></string>
2,在給TextView設置文字的時候還要用 html轉一下否則無法 html標籤不起作用 因爲:String.format(String, Object…) 方法會去除字符串中的所有樣式信息
所以在資源文件中寫html的方法如下
<string name="text_content"><a><u>你好啊</u></a></string>
textView.setText(Html.fromHtml(getResources().getString(R.string.text_content)));
TextView富文本
TextView富文本即是修改TextView的樣式,Android中提供修改TextView的樣式的類都在android.text.style包中,而設置富文本的方式是通過SpannableString.setSpan()或者是SpannableStringBuilder.setSpan()方法給文字設置樣式,最後再將SpannableString或者SpannableStringBuilder設置進TextView中
方法說明,SpannableString,SpannableStringBuilder的setSpan方法說明
void setSpan(Object what, int start, int end, int flags)
參數
what 要設置的字體樣式
start樣式的開始位置
end 樣式的結束位置
flags 是否包含開始位置,結束位置
flags的狀態(Spanned接口中的值)
SPAN_EXCLUSIVE_EXCLUSIVE 不包括起點和終點
SPAN_EXCLUSIVE_INCLUSIVE 包括終點但是不包括起點
SPAN_INCLUSIVE_EXCLUSIVE 包括起點但是不包括終點
SPAN_INCLUSIVE_INCLUSIVE 包括起點和終點
EXCLUSIVE 排除的意思
INCLUSIVE 包含的意思 這樣是不是好記憶了
字體樣式的類主要有:
AbsoluteSizeSpan 設置字體大小 按照絕對大小
使用:
xml:
<TextView
android:id="@+id/tv_content"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試" +
"本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new AbsoluteSizeSpan(10, true), 0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableString.setSpan(new AbsoluteSizeSpan(30, true), 4, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannableString);
效果:
AbsoluteSizeSpan(int size)
設置文本大小 單位px
AbsoluteSizeSpan(int size, boolean dip)
設置文本大小 是否是dp 不是dp則單位是px 是dp單位是dp
RelativeSizeSpan 設置字體相對大小,相對沒有設置RelativeSizeSpan的字體大小 比如1.5f是其他字體大小的1.5倍##
使用
`String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試" +
"本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new RelativeSizeSpan(0.5f),0,10,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableString.setSpan(new RelativeSizeSpan(1.5f),11,20,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannableString);`
效果:
注意:
RelativeSizeSpan(float proportion) proportion是相對沒有設置RelativeSizeSpan的字體的相對大小,1.5f是其大小的1.5倍
AlignmentSpan.Standard 改變文字的對齊方式
使用
String str = "我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
AlignmentSpan.Standard alignmentSpan = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
spannableString.setSpan(alignmentSpan, 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
效果是將對齊方式改爲之前對齊方式對立面 比如中文是左對齊,代碼運行後是右對齊(前提是TextView的大小要大於文字的大小,否則看不出對齊方式)
構造函數
AlignmentSpan.Standard(Layout.Alignment align)
填入對齊方式
ALIGN_NORMAL,
ALIGN_OPPOSITE,//對立
ALIGN_CENTER, //居中
/** @hide */
ALIGN_LEFT,
/** @hide */
ALIGN_RIGHT,
PS:說明感覺這個沒什麼用,因爲我們完全可以通過gravity熟悉來設置對齊方式
BackgroundColorSpan 改變字體的背景顏色
使用
String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試" +
"本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#FF0000"));
spannableString.setSpan(backgroundColorSpan, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
效果:
構造函數:
BackgroundColorSpan(int color)
直接傳入要顯示背景顏色即可
ForegroundColorSpan 改變字體的顏色##
使用:
` String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試" +
"本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.red)),2,12,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);`
效果
ClickableSpan 實現點擊TextView不同的地方實現不同的點擊效果 並且可以設置可點擊字體顏色
這個一般用來實現話題 @人 之類的社交產品中 如微博 QQ等
使用,說明查找 “#…#” 然後點擊 "#…#"彈出相應的文字
String str = "刪庫跑路,是對程序員的一種調侃,#我是話題1#多用於程序員壓力大的一種自我調侃或者#我是話題2#是開玩笑的話。" +
"實際上很少有刪庫跑路的現象出現,即便有類似情況,最後也都被法律制裁。近日有一家公司因爲員工的“鎖庫跑路”,導致公司最終被迫解散," +
"老闆身負重債無奈打工#我是話題3#";
SpannableString spannableString = new SpannableString(str);
String pa = "#[^#]*#";
Pattern pattern = Pattern.compile(pa);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String group = matcher.group();
int start = matcher.start();
int end = start + group.length();
spannableString.setSpan(new CustomClickableSpan(group), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannableString);
//設置文字高亮顏色,去除點擊後的背景顏色
textView.setHighlightColor(getResources().getColor(R.color.translate));
ClickableSpan類
class CustomClickableSpan extends ClickableSpan {
private String text;
public CustomClickableSpan(String text) {
this.text = text;
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
//設置是否有下劃線
ds.setLinearText(false);
//設置點擊文字的顏色
ds.setColor(getResources().getColor(R.color.red));
}
@Override
public void onClick(@NonNull View widget) {
AppCompatTextView textView = (AppCompatTextView) widget;
Toast.makeText(Main2Activity.this, "點擊了" + text, Toast.LENGTH_SHORT).show();
}
}
說明:
-
ClickableSpan是個抽象類 需要我們自己集成並且實現其onClick方法,傳入的參數widget是整個TextView,注意是整個TextView對象
-
當我們設置ClickableSpan之後還需要設置MovementMethod,否則點擊無效,即是
textView.setMovementMethod(LinkMovementMethod.getInstance());
-
點擊後可能會出現背景色,這個背景色是文字高亮顏色需要我們手動設置其顏色爲透明色(或者你想要的其他顏色),即是
textView.setHighlightColor(getResources().getColor(R.color.translate));
效果如下:暫時不上gif了 麻煩
DrawableMarginSpan
在文字前面添加一個Drawable 文字在該drawable的右側,很雞肋的一個功能類
使用:
String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new DrawableMarginSpan(getResources().getDrawable(R.mipmap.icon),100),0,str.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setBackgroundColor(getResources().getColor(R.color.red));
textView.setText(spannableString);
說明:
DrawableMarginSpan有兩個構造函數, DrawableMarginSpan(Drawable drawable)
參數是要設置的drawable DrawableMarginSpan(Drawable drawable, int pad)
參數1是要設置的drawable 參數2是圖片和文字之間的間距
效果如下:
DynamicDrawableSpan 實現在文本中添加圖片資源的抽象類##
注意這是一個抽象類,如果我們要使用它,需要實現它的抽象方法abstract Drawable getDrawable()
用來提供可繪製的drawable資源,我們簡單使用的話,可以這樣使用
class MyDynamicDrawableSpan extends DynamicDrawableSpan {
private final Context mContext;
private final int mResourceId;
public MyDynamicDrawableSpan(Context context, @DrawableRes int resourceId) {
mContext = context;
mResourceId = resourceId;
}
@Override
public Drawable getDrawable() {
Drawable drawable = mContext.getDrawable(mResourceId);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
return drawable;
}
}
但是官方給我們提供了一個實現子類ImageSpan,我們可以直接使用它
ImageSpan 實現文本中添加圖片,DynamicDrawableSpan的實現類
使用:我們在一段文字的不同位置插入圖片,這是在4個位置插入4張圖片
` String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new ImageSpan(this,R.mipmap.icon,DynamicDrawableSpan.ALIGN_BOTTOM),2,5,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ImageSpan(this,R.mipmap.icon,DynamicDrawableSpan.ALIGN_BASELINE),10,11,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ImageSpan(this,R.mipmap.icon,DynamicDrawableSpan.ALIGN_BASELINE),30,31,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ImageSpan(this,R.mipmap.icon,DynamicDrawableSpan.ALIGN_BASELINE),18,19,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);`
效果圖如下:
注意:
- 如果我們想要控制圖片的大小 我們可以重寫 getDrawable方法 壓縮bitmap
- 如果我們需要更改圖片和文字的對齊方式,可以重寫 draw 方法 進而更改圖片的對齊方式
- 我們需要插入多少圖片就要new出來多少個ImageSpan,ImageSpan不可複用,複用後只能顯示最後設置的位置
- 圖片插入的位置是在start之後
TextAppearanceSpan 設置文本樣式(字體大小,顏色等等,該樣式要通過style來設置)
使用
`
<style name="text1" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:textSize">15sp</item>
<item name="android:textColor">#f00</item>
</style>
<style name="text2" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:textSize">30sp</item>
<item name="android:textColor">#00f</item>
</style>
String str = "我是測試文本,我是測試文本我是測試文本我是測試文本我是測試文本我是測試" +
"本我是測試文本我是測試文本我是測試文本";
TextView textView = findViewById(R.id.tv_content);
SpannableString spannableString = new SpannableString(str);
spannableString.setSpan(new TextAppearanceSpan(this,R.style.text1),0,10,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableString.setSpan(new TextAppearanceSpan(this,R.style.text2),11,20,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannableString);`
效果: