一、需求展示
有时会需要,像社交网站评论一样的效果。因为Android的所有控件其实都是矩形的,导致如果使用两个或者以上的TextView控件来做的话会导致类似一下的排版:
用户:我是评论我是评论我是评论我是评论我是评论
我是评论我是评论我是评论我是评论我是评论
我是评论我是评论我是评论我是评论我是评论
以上的排版有个很不好的地方,就是没法自然的换行,因为左右分别是一个控件,而我们想达到的效果是:
用户:我是评论我是评论我是评论我是评论我是评论
我是评论我是评论我是评论我是评论我是评论是评论
我是评论我是评论我是评论我是评论我是评论是评论
而且,我们希望用户可以点击跳转。这样的排版显然用一个TextView比较容易实现,那么要想用户二字单独分离出来就需要用到一个属性:android:autoLink
。这其实不是什么新东西,就是在TextView中链接网址,电话或者其他什么链接的属性。
那么,首先先看效果吧:

点击李四后,会跳转到另一个activity,并把李四传过去,当然,你可以随便传数据,比如整个实体类什么的,也可以uri拼接的时候把这个拼接到uri里,参数传其他的都可以,随你。
那么点击后,跳转后的展示如下:

二、代码及原理
1.新建一个android项目
2.修改代码
代码一共新增/修改了6个文件,包括manifest。
①steings.xml
只是一些字符串常量,存在里面(里面两个冒号是为了验证是否只匹配其中第一个真正的用户名):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TextViewLink</string>
<string name="hello_world">李四:我是评论我是评:论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论我是评论</string>
<string name="action_settings">Settings</string>
<string name="waiting">加载中</string>
</resources>
②activity_main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.BigBoom.textviewlink.MainActivity" >
<!-- 只加了android:autoLink属性和id -->
<TextView
android:id="@+id/tv_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:autoLink="web|phone|email" />
</RelativeLayout>
③activity_user.xml 跳转后activity的布局文件,同样很简单,只有一个控件,为了展示,传值的效果
<?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" >
<TextView
android:id="@+id/tv_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/waiting"/>
</LinearLayout>
④MainActivity.java
本功能最重要的修改,通过修改uri来实现activity之间的跳转和传值
package com.BigBoom.textviewlink;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.app.Activity;
import android.os.Bundle;
import android.text.util.Linkify;
import android.text.util.Linkify.MatchFilter;
import android.text.util.Linkify.TransformFilter;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tvLink;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLink = (TextView) findViewById(R.id.tv_link);
extractMention2Link(tvLink);
}
/**
* 实现单TextView同时展示用户和评论并实现传值跳转
* @param v 展示用TextView
*/
private void extractMention2Link(TextView v){
v.setAutoLinkMask(0);
//匹配规则
Pattern pattern = Pattern.compile("(.*?):");
//用于跳转
String scheme = "bigboom://bigboom";
Linkify.addLinks(v, pattern, scheme, new MatchFilter() {
@Override
public boolean acceptMatch(CharSequence s, int start, int end) {
//只有第一个进行匹配
return start == 0;
}
}, new TransformFilter() {
@Override
public String transformUrl(Matcher match, String url) {
//传值
return "?username="+match.group(1);
}
});
}
}
⑤UserActivity.java
跳转后取值,并展示
package com.BigBoom.textviewlink;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
public class UserActivity extends Activity {
private TextView tvUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
tvUser = (TextView) findViewById(R.id.tv_user);
Intent intent = getIntent();
if(intent != null){
Uri uri = intent.getData();
if(uri == null){
return;
}
String username = uri.getQueryParameter("username");
tvUser.setText(username);
}
}
}
⑥最后manifest文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.BigBoom.textviewlink"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UserActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="bigboom" android:host="bigboom"/>
</intent-filter>
</activity>
</application>
</manifest>
三、总结
其实这是一个非常简单又实用的功能,其最核心的东西只有android:autoLink
和类Linkify
而已。可以做很多延伸,比如微博@人的功能和##话题功能。
网友评论