为指定文字添加背景
从上面的例子中我们可以总结出 设置字符串中的某个子字符串的样式(变成可单击的链接、设置字体等)步骤如下:
将字符串转换成SpannableString或者SpannableBuilder对象
获得要设置样式的子字符串在原字符串中的位置和子字符串后面的字符的位置,即start和end
创建一个Span对象(所有android.text.style包中的XXXSpan类创建的对象的统称,XXX标识URL、BackGround等类的前缀)
使用setSpan方法设置一个span对象,即将要设置样子的子字符串转换为Span对象
用处理完的SpannableString或者SpannableBuilder对象设置相应的控件(例如TextView、EditText、Button等)
在SDK的android.text.style有很多现成的Span对象,例如BackgroundColorSpan,该类的功能是设置指定字符串的背景色。
例如:
TextView textView = (TextView)findViewById(R.id.textView); String text = "<没有背景><黄色背景>"; // 第一步:将字符串转换成为SpannableString对象 SpannableString s = new SpannableString(text); // 第二步:确定要设置的子字符串的star和end int start = 6 ; int end = 12 ; // 第三步: 创建BackgroundColorSpan对象 BackgroundColorSpan b = new BackgroundColor(Color.YELLOW); // 第四步:使用setSpan将指定的子字符串转换成BackgroundColorSpan对象 s.setSpan(b,start,end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 第五步:用SpannableString对象设置TextView控件 textView.setText(s);
BackgroundColorSpan只能够设置文字的背景色,为了更加的通用,自定义一个ColorSpan类,使其能够同时设置文字颜色和背景色(android.text.style.ForegroundColorSpan可以设置文字颜色,但并没有可以同事设置背景和文字颜色的Span类)。
如果需要处理链接动作,必须要继承ClickableSpan类,本例我们只是设置文字和背景颜色,并不需要处理任何动作,因此只需要从CharacterStyle类继承即可。事实上,ClickableSpan也是CharacterStyle的子类。
代码如下:
import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.text.SpannableString; import android.text.Spanned; import android.text.TextPaint; import android.text.style.BackgroundColorSpan; import android.text.style.CharacterStyle; import android.widget.TextView; import com.turing.base.R; public class AddBackgroundAct extends Activity { private TextView tv_addbBackground; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_background); initView(); } private void initView() { tv_addbBackground = (TextView) findViewById(R.id.id_tv_addBackground); String text = "<没有背景><黄色背景>\n\n<蓝色背景,红色文字>"; SpannableString spannableString = new SpannableString(text); int start = 6; int end = 12; BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.YELLOW); spannableString.setSpan(backgroundColorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // <蓝色背景,红色文字> (每个 “\n”算一个长度) start = 14; end = text.length(); // 创建ColorSpan ColorSpan colorSpan = new ColorSpan(Color.RED, Color.BLUE); // 将文字转换为ColorSpan对象 spannableString.setSpan(colorSpan, start,end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv_addbBackground.setText(spannableString); TextView tv = (TextView)findViewById(R.id.id_tv_tv2); tv.setText("一整个字符串的普通的背景设置,文字颜色设置"); tv.setBackgroundColor(Color.GREEN); tv.setTextColor(Color.DKGRAY); } /** * 自定义Span类,可以同时设置文字颜色和背景色 */ class ColorSpan extends CharacterStyle { private int mTextColor; private int mBackgroundColor; public ColorSpan(int mTextColor, int mBackgroundColor) { this.mTextColor = mTextColor; this.mBackgroundColor = mBackgroundColor; } // 重写updateDrawState方法 @Override public void updateDrawState(TextPaint tp) { tp.bgColor = mBackgroundColor; tp.setColor(mTextColor); } } }
总结:
将android:autoLink的属性值设置为true,系统会自动识别E-mail、电话、网址等特殊文本
使用Html标签,例如 <font> <img>等,不要设置android:autoLink属性
在java代码中直接使用Span对象来设置文本样式。这种方法需要将文本转换成为一个SpannableString或者SpannableBuilder对象,然后在SpannableString或者SpannableBuilder对象中使用setSpan方法将需要设置样式的文本转换成相应的Span对象
在字符串资源中,使用<a>标签(仅支持a标签)设置可点击的链接,不要设置android:autoLink属性。例如
<string name="link_text"> <a href="tel:123456">打电话</a> </string>
然后在TextView标签中引用
..... android:text="@string/link_text"
带边框的TextView
两种方式:
- 编写一个继承TextView类的自定义控件,重写onDraw()绘制边框
- 使用9-patch(*.9.png)格式的图像作为TextView的背景图来设置边框(这个背景图需要有一个边框)
通过第一中方式实现:
public class BorderTextView extends TextView { public BorderTextView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); // 设置所绘制的边框颜色为黑色 paint.setColor(Color.BLACK); // 绘制上边框 canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint); // 绘制左边框 canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint); // 绘制右边框 canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint); // 绘制下边框 canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, paint); } }
XML:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.turing.base.activity.textViewAct.BorderTextView android:id="@+id/id_tv_borderTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:gravity="center" android:text="自定义TextView绘制边框"/> </RelativeLayout>
设置行间距
如果TextView控件中显示了多行文本,会有一个默认的行间距。
如果要改默认的行间距,三种方法:
- 布局文件中使用android:lineSpacingExtra 或者 android:lineSpacingMultiplier属性设置行间距。
android:lineSpacingExtra设置精确的行间距,例如
android:lineSpacingExtra="20dp"
android:lineSpacingMultiplier 属性设置的是默认行间距的倍数。
如果同时设置了这两个属性,以较大行间距为准。
- 使用Style资源设置行间距
- 使用setLineSpacing方法设置行间距。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#000"> <!--使用android:lineSpacingExtra属性设置行间距--> <TextView android:id="@+id/id_tv_lineSpace" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_margin="10dp" android:background="#FFF" android:lineSpacingExtra="20dp" android:textColor="#000" android:text="第一行的文本\n第二行的文本(20dp)"/> <!--使用android:lineSpacingMultipile属性设置行间距--> <TextView android:id="@+id/id_tv_lineSpace2" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_margin="10dp" android:background="#FFF" android:lineSpacingMultiplier="1.8" android:textColor="#000" android:text="第一行的文本\n第二行的文本(行间距是默认行间距的1.8倍)"/> <!--使用style定义行间距--> <TextView android:id="@+id/id_tv_lineSpace3" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_margin="10dp" android:background="#FFF" style="@style/line_space" android:textColor="#000" android:text="第一行的文本\n第二行的文本(style设置的,行间距是默认行间距的1.5倍)"/> <!--使用代码设置--> <TextView android:id="@+id/id_tv_lineSpace4" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_margin="10dp" android:background="#FFF" android:textColor="#000" android:text="第一行的文本\n第二行的文本(代码设置)"/> </LinearLayout>
<style name="line_space"> <item name="android:lineSpacingMultiplier">1.5</item> </style>
public class LineSpaceTextViewAct extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_line_space_text_view); TextView tv = (TextView)findViewById(R.id.id_tv_lineSpace4); tv.setLineSpacing(50,1.2f); } }
setSpacing 方法:
/** * Sets line spacing for this TextView. Each line will have its height * multiplied by <code>mult</code> and have <code>add</code> added to it. * * @attr ref android.R.styleable#TextView_lineSpacingExtra * @attr ref android.R.styleable#TextView_lineSpacingMultiplier */ public void setLineSpacing(float add, float mult) { if (mSpacingAdd != add || mSpacingMult != mult) { mSpacingAdd = add; mSpacingMult = mult; if (mLayout != null) { nullLayouts(); requestLayout(); invalidate(); } } }
第一个参数相当于 android:lineSpacingExtra属性,第二个参数相当于android:lineSpaceingMultiplier属性。系统会采用哪个参数作为最终的行间距,取决于哪个参数值所表示的行间距大了。
在未显示完的文本后面加省略号(…)
当文本内容太多的时候,控件一行显示不开的时候,系统默认的会在最后显示一个省略号(…)
通过android:ellipsize属性可以设置省略号的位置,当属性值为none的时候则不显示省略号,默认在对后面加省略号。
需要设置 android:singleLine=”true”
代码设置如下:
textView.setEllipsize(TextUtils.TruncateAt.END);
xml报文设置:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" android:orientation="vertical"> <TextView android:id="@+id/id_tv_ignore1" android:layout_width="150dp" android:layout_height="wrap_content" android:background="#FFF" android:ellipsize="start" android:singleLine="true" android:layout_margin="10dp" android:text="维基百科的目标是建立拥有人类全部知识的百科全书" /> <TextView android:id="@+id/id_tv_ignore2" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFF" android:ellipsize="middle" android:singleLine="true" android:layout_margin="10dp" android:text="维基百科的目标是建立拥有人类全部知识的百科全书dddddddddddddddddddddd" /> <TextView android:id="@+id/id_tv_ignore3" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFF" android:ellipsize="end" android:singleLine="true" android:layout_margin="10dp" android:text="维基百科的目标是建立拥有人类全部知识的百科全书ddddddddddddddddddd" /> </LinearLayout>
用TextView实现走马灯的效果
- TextView必须要获取焦点 ( android:focusable=”true”android:focusableInTouchMode=”true”)
- android:ellipsize=”marquee”
- android:marqueeRepeatLimit
- android:singleLine=”true”
android:marqueeRepeatLimit=“marquee_forever”或者是大于0的整数,marquee_forever表示永远循环显示。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFF" android:ellipsize="marquee" android:focusable="true" android:focusableInTouchMode="true" android:marqueeRepeatLimit="marquee_forever" android:singleLine="true" android:text="李克勤(Hacken Lee),生于香港,籍贯广东新会崖西,中国香港歌手,演员,主持人" /> </LinearLayout>
垂直滚动TextView中的文本(让TextView出现滚动条)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000"> <TextView android:id="@+id/id_tv_scroll" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFF" android:singleLine="false" android:maxLines="4" android:scrollbars="vertical" android:scrollbarStyle="outsideOverlay" android:scrollbarFadeDuration="2000" android:padding="10dp" android:text="周杰伦, 生于中华民国台北县林口乡,是台湾著名国语流行音乐男歌手、演员、导演及音乐创作人。 周杰伦于2000年正式出道并发行其个人首张同名国语专辑《Jay》,翌年凭借该张专辑获得第十二届台湾金曲奖“最佳流行音乐演唱专辑奖”ddddddddddddddddddddddddddddddddddddddddddddddd。"/> </RelativeLayout>
public class ScrollTextViewAct extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scroll_text_view); TextView textView = (TextView) findViewById(R.id.id_tv_scroll); textView.setMovementMethod(ScrollingMovementMethod.getInstance()); } }
android:scrollbars=”vertical” : 垂直滚动必须为vertical
android:scrollbarStyle=”outsideOverlay” :滚动条在文字的右侧显示。如果insideOVerlay滚动条会在右侧文字上显示(会覆盖文字的一部分)。
android:scrollbarFadeDuration=”2000” 滚动条从出现到消失(以渐变的方式)的时间,单位是毫秒