本文主要介绍TextView添加链接的几种可行及不可行方式,并且分析为什么不可行。 示例APK可从这些地址下载:Google Play, 360手机助手, 百度手机助手, 小米应用商店, 豌豆荚 效果图如下:
一、可行方式
Java
1 2 3 4 5 6 7 8 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); trineaInfoTv.setMovementMethod(LinkMovementMethod.getInstance()); Spanned text = Html.fromHtml("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); trineaInfoTv.setText(text); |
显示链接样式,能点击,touch即点击
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); Spanned text = Html.fromHtml("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); trineaInfoTv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri web = Uri.parse("http://www.trinea.cn"); Intent i = new Intent(Intent.ACTION_VIEW, web); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(i); } }); |
显示链接样式,能点击。通过手动设置textView的OnClickListener完成点击响应。
Java
1 2 3 4 5 6 7 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:autoLink="all" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); trineaInfoTv.setText("个人主页:http://www.trinea.cn"); |
显示链接样式,并且能点击(只响应http://www.trinea.cn部分点击),不过不支持如下的href形式
Java
1 |
trineaInfoTv.setText("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); |
二、不可行方式
Java
1 2 3 4 5 6 7 8 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:autoLink="all" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); Spanned text = Html.fromHtml("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); trineaInfoTv.setText(text); |
显示链接样式,不能点击
Java
1 2 3 4 5 6 7 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); Spanned text = Html.fromHtml("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); trineaInfoTv.setText(text); |
显示链接样式,不能点击
Java
1 2 3 4 5 6 7 8 9 |
<TextView android:id="@+id/trineaInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:autoLink="all" /> trineaInfoTv = (TextView)activity.findViewById(R.id.trineaInfo); trineaInfoTv.setMovementMethod(LinkMovementMethod.getInstance()); Spanned text = Html.fromHtml("个人主页:<a href=\"http://www.trinea.cn\"> Trinea</a>"); trineaInfoTv.setText(text); |
不显示链接样式,不能点击
三、通过源码分析原因
TextView.setText函数主要源代码如下:
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
if (!isSuggestionUnderLineRefreshFlag) { if (type == BufferType.EDITABLE || mInput != null || needEditableForNotification) { Editable t = mEditableFactory.newEditable(text); text = t; setFilters(t, mFilters); InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null) imm.restartInput(this); } else if (type == BufferType.SPANNABLE || mMovement != null) { text = mSpannableFactory.newSpannable(text); } else if (!(text instanceof CharWrapper)) { text = TextUtils.stringOrSpannedString(text); } } if (mAutoLinkMask != 0) { Spannable s2; if (type == BufferType.EDITABLE || text instanceof Spannable) { s2 = (Spannable) text; } else { s2 = mSpannableFactory.newSpannable(text); } if (Linkify.addLinks(s2, mAutoLinkMask)) { text = s2; type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE; /* * We must go ahead and set the text before changing the * movement method, because setMovementMethod() may call * setText() again to try to upgrade the buffer type. */ mText = text; // Do not change the movement method for text that support text selection as it // would prevent an arbitrary cursor displacement. if (mLinksClickable && !textCanBeSelected()) { setMovementMethod(LinkMovementMethod.getInstance()); } } } |