很多時(shí)候我們也需要制作一些彩色字體的文本英上,文本的霓虹燈效果胧瓜,以及鏈接字體哈,字體背景色跺株,下標(biāo)之類(lèi)的复濒,而很多時(shí)候我們卻用多個(gè)textview去達(dá)到這個(gè)效果脖卖,可以說(shuō)是很浪費(fèi)時(shí)間浪費(fèi)經(jīng)精力的,這時(shí)候怎么辦呢巧颈?下面就有詳解胚嘲。
文章結(jié)構(gòu):1.自定義TextView實(shí)現(xiàn)彩色字體與霓虹燈字體 2.一個(gè)可以字體實(shí)現(xiàn)多項(xiàng)效果的類(lèi)(封裝好了,可直接使用)
先上圖看看我們要做的效果
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述
一洛二、自定義TextView之彩色字體,直接上代碼解釋
package com.demo.myview.colourfulFontOrNeonTextView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by 符柱成 on 2016/8/19.
*/
public class ColourfulFontTextview extends TextView {
int TextViewWidth; //TextView的寬度
private LinearGradient mLinearGradient; //渲染器
private Paint paint;
public ColourfulFontTextview(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//在 onSizeChanged 方法中獲取到寬度馋劈,并對(duì)各個(gè)類(lèi)進(jìn)行初始化
if (TextViewWidth == 0) {
TextViewWidth = getMeasuredWidth();
if (TextViewWidth > 0) {
//得到 父類(lèi) TextView 中寫(xiě)字的那支筆
paint = getPaint();
//初始化線性渲染器
mLinearGradient = new LinearGradient(0, 0, TextViewWidth, 0,
new int[]{Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN, Color.GRAY}, null, Shader.TileMode.CLAMP);
//把渲染器給筆套上
paint.setShader(mLinearGradient);
}
}
}
}
2.在xml中的引用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".colourfulFontOrNeonTextView.ColourfulFontOrNeonAcitivity">
<com.demo.myview.colourfulFontOrNeonTextView.colourfulFontTextview
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="彩色字體!彩色字體!彩色字體!"
android:textSize="28sp" />
<!-- 霓虹燈字體,一會(huì)就不貼xml了-->
<com.demo.myview.colourfulFontOrNeonTextView.NenoTextview
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="霓虹燈字體晾嘶!霓虹燈字體妓雾!霓虹燈字體!"
android:textSize="28sp" />
<!-- 多項(xiàng)字體效果垒迂,一會(huì)就不貼xml了-->
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_marginTop="10dp"
android:background="@color/colorPrimary"
android:text="baiduoryouku正常粗體斜體粗斜體上標(biāo)下標(biāo)前景色背景色圖片"
android:textSize="25sp"/>
</LinearLayout>
二械姻、自定義TextView之霓虹燈字體,直接上代碼解釋啦
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by 符柱成 on 2016/8/19.
*/
public class NenoTextview extends TextView {
int mViewWidth; //TextView的寬度
private LinearGradient mLinearGradient; //渲染器
private Matrix mMatrix; //圖片變換處理器
private Paint mPaint; //字體的筆
int mTranslate=0; //表示平移的速度
public NenoTextview(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//在 onSizeChanged 方法中獲取到寬度机断,并對(duì)各個(gè)類(lèi)進(jìn)行初始化
if (mViewWidth == 0) {
mViewWidth = getMeasuredWidth();
if (mViewWidth > 0) {
//得到 父類(lèi) TextView 中寫(xiě)字的那支筆.楷拳,注意是繼承Textview
mPaint = getPaint();
//初始化線性渲染器 不了解的請(qǐng)看上面連接
mLinearGradient = new LinearGradient(0, 0, mViewWidth, 0,
new int[]{Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN}, null, Shader.TileMode.CLAMP);
//把渲染器給筆套上
mPaint.setShader(mLinearGradient);
//初始化 Matrix,Matrix的原意是對(duì)一個(gè)Bitmap的圖片變化進(jìn)行處理吏奸,它本身不能對(duì)圖像或者View進(jìn)行變換欢揖,但是可以與其他的API結(jié)合進(jìn)行圖形和View的變換,比如Canvas
mMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
//先讓父類(lèi)方法執(zhí)行奋蔚,由于上面我們給父類(lèi)的 Paint 套上了渲染器她混,所以這里出現(xiàn)的文字已經(jīng)是彩色的了
super.onDraw(canvas);
if (mMatrix != null) {
//利用 Matrix 的平移動(dòng)作實(shí)現(xiàn)霓虹燈的效果,這里是每次滾動(dòng)1/10
mTranslate += mViewWidth / 10;
//如果滾出了控件邊界泊碑,就要拉回來(lái)重置開(kāi)頭坤按,這里重置到了屏幕左邊的空間
if (mTranslate > mViewWidth) {
mTranslate = -mViewWidth/2;
}
//設(shè)置平移距離
mMatrix.setTranslate(mTranslate, 0);
//平移效果生效
mLinearGradient.setLocalMatrix(mMatrix);
//延遲 100 毫秒再次刷新 View 也就是再次執(zhí)行本 onDraw 方法
postInvalidateDelayed(50);
}
}
}
xml中的引用已經(jīng)在上面給出了。
三馒过、多項(xiàng)字體效果臭脓,下面將給出一個(gè)封裝好的類(lèi)以及調(diào)用方法
package com.demo.myview.colourfulFontOrNeonTextView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.StyleSpan;
import android.text.style.SubscriptSpan;
import android.text.style.SuperscriptSpan;
import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import com.demo.myview.R;
/**
* Created by 符柱成 on 2016/8/19.
*/
//封裝好了Textview多種字體
public class SpannableStringFont {
public static SpannableString changeFont(Context context, String content) {
SpannableString ss = new SpannableString(content);
// flag:標(biāo)識(shí)在 Span 范圍內(nèi)的文本前后輸入新的字符時(shí)是否把它們也應(yīng)用這個(gè)效果
// Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、
// Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括腹忽,后面不包括)来累、
// Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)留凭、
// Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
//設(shè)置字體(default,default-bold,monospace,serif,sans-serif)
ss.setSpan(new TypefaceSpan("monospace"), 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置網(wǎng)絡(luò)超鏈接
ss.setSpan(new URLSpan("http://www.baidu.com"), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new URLSpan("http://www.youku.com"), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置字體顏色
ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff0000")), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(Color.parseColor("#0000FF")), content.indexOf("or"), content.indexOf("youku"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff00ff")), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置字體大小
ss.setSpan(new AbsoluteSizeSpan(sp2px(context, 25)), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new AbsoluteSizeSpan(sp2px(context, 30)), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置下劃線
ss.setSpan(new MyUnderlineSpan(), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//設(shè)置字體樣式正常佃扼,粗體偎巢,斜體蔼夜,粗斜體
ss.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), content.indexOf("正常"), content.indexOf("粗體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //正常
ss.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), content.indexOf("粗體"), content.indexOf("斜體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗體
ss.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), content.indexOf("斜體"), content.indexOf("粗斜體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //斜體
ss.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), content.indexOf("粗斜體"), content.indexOf("上標(biāo)"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗斜體
//設(shè)置上下標(biāo)
ss.setSpan(new SubscriptSpan(), content.indexOf("上標(biāo)"), content.indexOf("下標(biāo)"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下標(biāo)
ss.setSpan(new SuperscriptSpan(), content.indexOf("下標(biāo)"), content.indexOf("前景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //上標(biāo)
//設(shè)置字體前景色
ss.setSpan(new ForegroundColorSpan(Color.MAGENTA), content.indexOf("前景色"), content.indexOf("背景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設(shè)置前景色為洋紅色
//設(shè)置字體背景色
ss.setSpan(new BackgroundColorSpan(Color.CYAN), content.indexOf("背景色"), content.indexOf("圖片"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設(shè)置背景色為青色
//設(shè)置圖片
Drawable drawable = context.getDrawable(R.drawable.home_serve_dot_pressed);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ss.setSpan(new ImageSpan(drawable), content.indexOf("圖片"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return ss;
}
//這里是干嘛的呢?為了設(shè)置下劃線唄
static class MyUnderlineSpan extends UnderlineSpan {
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(true);
}
}
//這又是干嘛的呢压昼?計(jì)算字體大小嘛
private static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
嗯求冷,瘤运,還缺個(gè)調(diào)用,為了方便新手使用匠题,下面也貼出來(lái):
public class ColourfulFontOrNeonAcitivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_colourful_font_or_neon_acitivity);
initView();
}
private void initView(){
TextView textView = (TextView) findViewById(R.id.tv_content);
String content = textView.getText().toString();
textView.setText(SpannableStringFont.changeFont(ColourfulFontOrNeonAcitivity.this,content));
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}