一、什么是TextView
TextView可显示文本给用户,但是其基本类配置为不允许编辑。相当于一个UI里的Label。
二、设置TextView样式
设置样式有两种方式,一种是设置xml的属性,另一种是用SpannableStringBuilder。区别是前者不是对文本的部分指定内容设置样式而是全部,后者可以对部分文本设置特定样式。
1、背景色
(1)xml属性
android:background="#FF0000"
(2)BackgroundColorSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上[ 0,1 )上的文本添加红色背景 spannableStringBuilder.setSpan(new BackgroundColorSpan(Color.parseColor("#FF0000")),0,1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); //为textView上( 1,2 ]上的文本添加绿色背景 spannableStringBuilder.setSpan(new BackgroundColorSpan(Color.parseColor("#00FF00")),1,2,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); textView.setText(spannableStringBuilder); } }
2、前景色(即字体颜色)
(1)xml属性
android:textColor="#F43281"
(2)ForegroundColorSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上[ 0,1 )上的文本添加红色字体色 spannableStringBuilder.setSpan(new ForegroundColorSpan(Color.parseColor("#FF0000")),0,1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); //为textView上( 1,2 ]上的文本添加绿色字体色 spannableStringBuilder.setSpan(new ForegroundColorSpan(Color.parseColor("#00FF00")),1,2,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); textView.setText(spannableStringBuilder); } }
3、删除线
(1)textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
TextView textView=findViewById(R.id.textView);
textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);//textView所有文本都被加上了删除线
(2)StrikethroughSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上[ 0,5 ]上的文本添加删除线 spannableStringBuilder.setSpan(new StrikethroughSpan(),0,5, Spanned.SPAN_INCLUSIVE_INCLUSIVE); textView.setText(spannableStringBuilder); } }
4、下划线
(1)textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
TextView textView=findViewById(R.id.textView); textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);//textView所有文本都被加上了下划线
(2)UnderlineSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上( 0,5 )上的文本添加下划线 spannableStringBuilder.setSpan(new UnderlineSpan(),0,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder); } }
5、字体大小
(1)xml属性
android:textSize="30sp"
(2)AbsoluteSizeSpan & RelativeSizeSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上( 0,5 )上的文本修改绝对大小(单位:px) spannableStringBuilder.setSpan(new AbsoluteSizeSpan(30),0,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //为textView上( 5,10 )上的文本修改相对大小(单位:倍) spannableStringBuilder.setSpan(new RelativeSizeSpan(2),5,10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder); } }
6、字体样式(粗体/斜体)
(1)xml属性[bold:粗体][italic:斜体][normal:正常]
android:textStyle="bold"
或
android:textStyle="italic"
(2)StyleSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上( 0,5 )上的文本修改为:【Typeface.BOLD:粗体】【Typeface.BOLD_ITALIC:粗斜体】【Typeface.ITALIC:斜体】 spannableStringBuilder.setSpan(new StyleSpan(Typeface.ITALIC),0,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder); } }
(3)html标签格式化文字
TextView textView=findViewById(R.id.textView); String str="我们来测试一下html格式化文本的功能:<u>下划线</u>、<s>删除线</s>、<i>斜体</i>、<b>粗体</b>、<font color=‘red‘>红色字</font>"; textView.setText(Html.fromHtml(str));
7、字体
(1)xml属性
android:fontFamily="monospace"
fontFamily的属性值参考如下:(这些都是系统自带的字体)
(2)自定义字体文本
i. 单击app文件夹,鼠标右键New->Folder->Assets Folder->finish
ii. 把android视图切换到project视图,找到app/src/main/assets,单击assets右键New->Directory新建一个fonts文件夹把C:\Windows\Fonts这个文件夹下你喜欢的字体包复制app/src/main/assets/fonts
iii. 修改java代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); //从asset 读取字体 AssetManager myassetManager = getAssets(); //根据路径得到Typeface Typeface tf = Typeface.createFromAsset(myassetManager, "fonts/FZSJ-HLPPJW.TTF"); textView.setTypeface(tf); } }
如果还不太清楚怎么设置,可以参考这篇:Android更换APP字体—TextView各种字体样式
(3)TypefaceSpan
因为系统自带的字体比较丑,所以我还是选择自定义一个TypefaceSpan,创建fonts文件夹的步骤同上这里不赘述。之所以用TypefaceSpan是为了一个TextView可以有多种字体
首先,新建 MyTypefaceSpan.java,因为类TypefaceSpan继承MetricAffectingSpan,所以我们只要继承这个类并重写父类抽象方法
public class MyTypefaceSpan extends MetricAffectingSpan { private final Typeface typeface; public MyTypefaceSpan(final Typeface typeface){ this.typeface=typeface; } @Override public void updateMeasureState(@NonNull TextPaint textPaint) { apply(textPaint); } @Override public void updateDrawState(TextPaint tp) { apply(tp); } private void apply(final Paint paint){ final Typeface oldTypeface=paint.getTypeface(); final int oldStyle = oldTypeface != null ? oldTypeface.getStyle() : 0; final int fakeStyle = oldStyle & ~typeface.getStyle(); if ((fakeStyle & Typeface.BOLD) != 0) { paint.setFakeBoldText(true); } if ((fakeStyle & Typeface.ITALIC) != 0) { paint.setTextSkewX(-0.25f); } paint.setTypeface(typeface); } }
然后我们利用SpannableStringBuilder设置MyTypefaceSpan
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=findViewById(R.id.textView); AssetManager myassetManager = getAssets(); //根据路径得到Typeface Typeface tf = Typeface.createFromAsset(myassetManager, "fonts/FZSJ-HLPPJW.TTF"); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上( 0,5 )上的文本修改为自定义字体 spannableStringBuilder.setSpan(new MyTypefaceSpan(tf),0,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//如果这里想用系统自带的字体,可以这样写(不用自定义MyTypefaceSpan,也不用得到Typeface的对象)。
spannableStringBuilder.setSpan(new TypefaceSpan("monospace"),5,10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableStringBuilder);
}
}
以上自定义TypefaceSpan我参考的这篇文章:(原创)如何在spannableString中使用自定义字体
8、行间距 : 第一个为10sp的固定行间距,第二个为2倍行间距,两个属性一起用会叠加让间距更大
android:lineSpacingExtra="10sp"
android:lineSpacingMultiplier="2"
9、上下标
TextView textView = findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //把textView上第二个字符变成上标 spannableStringBuilder.setSpan(new SuperscriptSpan(),1,2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); //把textView上第三个字符变成下标 spannableStringBuilder.setSpan(new SubscriptSpan(),2,3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder);
10、文字阴影
(1)xml属性
android:shadowColor="#000000"
android:shadowDx="10"
android:shadowDy="10"
android:shadowRadius="10"
关于阴影的这四个属性以及取值问题可参考这篇:Android TextView加上阴影效果
(2)setShadowLayer(float radius,float dx,float dy,int color);
TextView textView=findViewById(R.id.textView); textView.setShadowLayer(10,-10,-10,Color.argb(255,0,0,0));
11、文字缩放【向X轴缩放(变胖变瘦)】
(1)xml属性 【一般不用android:scaleX和android:scaleY这两个属性改变文字,因为这是针对整个控件的,所以可能会使textView超出界面或四周留白】
android:textScaleX="1.5f"
(2)ScaleXSpan 【类似上面的textScaleX,但是可以对指定字符缩放】
TextView textView=findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上( 0,5 )上的文本修改为:向X轴缩放原来的3.7倍 spannableStringBuilder.setSpan(new ScaleXSpan(3.7f),0,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder);
(3)setTextScaleX(float scaleX)
TextView textView=findViewById(R.id.textView);
textView.setTextScaleX(0.5f);
12、文字旋转
(1)xml属性(rotation:顺时针旋转 | rotationX:以X轴为轴心旋转 | rotaionY:以Y轴为轴心旋转)
android:rotation="45"
(2)setRotation(float rotation)
textView.setRotation(45);
【setPivotX(float pivotX) & setPivotY(float pivotY) :这两个方法可以设置旋转中心 or 缩放中心,一般都默认为textView中心为旋转中心,可以通过如下设置改为左上角作为旋转中心】
TextView textView=findViewById(R.id.textView); textView.setPivotX(0); textView.setPivotY(0); textView.setRotation(45);
对修改旋转中心感兴趣的可以看看这篇:使用View的setPivotX(float pivotX)、setPivotY(float pivotY)方法设置轴点
13、图文混排
(1)ImageSpan
TextView textView = findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); Drawable drawable=getResources().getDrawable(R.drawable.ic_launcher_foreground); drawable.setBounds(0,0,200,200);//设置图片大小,相当于setBounds(int x,int y,int width,int height) //图片会占用一个字符,所以字符串里放置图片的位置最好由空格代替,这里[0 ,1)为图片位置(即第1个字符) spannableStringBuilder.setSpan(new ImageSpan(drawable),0,1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder);
14、图片环绕
(1)xml属性
android:drawableLeft="@mipmap/ic_launcher_round"
android:drawableTop="@mipmap/ic_launcher_round"
android:drawableRight="@mipmap/ic_launcher_round"
android:drawableBottom="@mipmap/ic_launcher_round"
(2)setCompoundDrawables(Drawable left,Drawable top,Drawable right,Drawable bottom)
TextView textView = findViewById(R.id.textView); Drawable myicon=getResources().getDrawable(R.mipmap.ic_launcher); myicon.setBounds(0,0,50,50);//设置图片的起始位置为(0,0)大小为50*50 textView.setCompoundDrawables(myicon,null,myicon,myicon);
15、超链接
(1)xml属性
android:text="点击链接直接百度https://www.baidu.com/" android:autoLink="web"
android:textColorLink="#0000ff"
autoLink的取值如下,属性值查看这里:TextView的autoLink属性设置超链接的问题
(2)URLSpan
TextView textView = findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); //为textView上[ 0,4 )上的文本添加URLSpan,点击链接可以打电话 spannableStringBuilder.setSpan(new URLSpan("tel:10086"),0,4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder);
//让URLSpan可以点击 textView.setMovementMethod(LinkMovementMethod.getInstance());
(3)ClickableSpan 需要textView除了点击还要有其他响应操作:TextView添加ClickableSpan和LinkMovementMethod之间的关系
TextView textView = findViewById(R.id.textView); SpannableStringBuilder spannableStringBuilder=new SpannableStringBuilder(textView.getText()); ClickableSpan clickableSpan=new ClickableSpan(){ @Override public void onClick(@NonNull View widget) { //设置点击ClickableSpan后的事件,这里以页面跳转为例,新建New->Activity->Empty Activity(即这里的Main2Activity) Intent myintent=new Intent(); myintent.setClass(getApplicationContext(),Main2Activity.class); startActivity(myintent); } }; //为textView上[ 0,5 )上的文本修改为具有点击事件的ClickableSpan spannableStringBuilder.setSpan(clickableSpan,0,5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableStringBuilder);
//这句必须有,不然点击无效 textView.setMovementMethod(LinkMovementMethod.getInstance());
16、走马灯
(1)xml属性 属性参考:View的onClick、focusable、focusableInTouchMode属性详解以及跑马灯的实现 marquee_forever是为了让跑马灯一直循环
android:singleLine="true"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
(2)setEllipsize(TextUtils.TruncateAt.MARQUEE) 关于request Focus() :Android控件获取焦点 关于多个TextView跑马灯:Android TextView跑马灯设置的两种方法
TextView textView = findViewById(R.id.textView); textView.setSingleLine(true); textView.setEllipsize(TextUtils.TruncateAt.MARQUEE); textView.setFocusable(true); textView.setFocusableInTouchMode(true);
textView.setMarqueeRepeatLimit(Integer.MAX_VALUE);
textView.requestFocus();
17、长文本的多行显示
(1)单行
单行时省略号ellipsize可取值:[ start | middle | end | marquee | none ]
android:singleLine="true"
android:ellipsize="middle"
(2)多行 【android:lines 不管有多少行都显示固定行数 | android:maxLines 当行数大于这个最大值时只显示设置的最大值的行数】
多行有省略号:ellipsize="end",多行时只有当这个省略号在 "end" 结尾可以显示省略号,多行下省略号在其他位置无效
android:maxLines="3"
android:ellipsize="end"
18、textView的边框和背景
在app/res/drawable,右键单击drawable文件夹:New->Drawable Resource File->[ File name:textviewbg & Root element:shape ]->ok
textviewbg.xml (以椭圆形为例,需要矩形或圆角矩形的话:android:shape="rectangle")
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#D0104C"/><!--填充色--> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp"/><!--内容与边框的间距--> <stroke android:dashGap="2dp" android:dashWidth="2dp" android:color="#DCB879" android:width="2dp"/><!--设置描边为虚线[dashGap虚线间距|dashWidth虚线长度];描边的粗细和颜色--> <gradient android:startColor="#FEDFE1" android:endColor="#EB7A77" android:type="linear" android:angle="270"/><!--线性渐变[渐变>填充]--> <size android:height="50sp" android:width="60sp"/><!--height=width时为圆形,否则为椭圆--> </shape>
然后设置TextView属性
android:background="@drawable/textviewbg"
19、textView镜像翻转 参考:android镜像翻转
为TextView的父级控件LinearLayout添加id
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/L1" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity">
在java代码的onCreate方法设置linearlayout翻转
LinearLayout L1=findViewById(R.id.L1);
L1.setScaleY(-1);
关于SpannableStringBuilder和SpannableString的区别:TextView图文混排 这篇文章有点长,想看区别的在文章右侧的目录直接点SpannableStringBuilder
关于各种Span:TextView使用SpannableString设置复合文本
精力有限,我就写这么多关于textView的样式吧,等以后有新的需求我再更新。