首先看下新浪微博客户端界面如图:
每转发一次都会增加一个@xxx,而点击@xxx则进入该用户详细资料界面,点击其他地方则进入的是微博正文,这个怎么实现呢,只用TextView行吗?答案肯定是不行的!
先分析下它这个过程是怎么实现的,个人觉得,当发布一条微博后,这条微博记录所对应的服务端的表中,会有用户个人信息,以及转发时的评论内容即这一部分(这一部分内容其实可以是一个字符串),还应有一个被转发人列表可以是json格式的字段(包括被转发人的id和昵称),当下一个用户转发这条微博时,会获取这个被转发人列表字段,转发成功后会将自己的id及昵称保存在这个字段中并传给服务器;而客户端在显示被转发的微博时,除了获取到转发评论内容,还会获取到这个被转发人列表字段中包含的转发人id及昵称,然后通过特殊方法,将转发评论内容中的@XXX依据被转发人列表转换为可点击。
网上也有不少方法实现,但本人觉得不够全面,因此写下这篇文章及demo,供初学者学习,水平有限,不足之处还望各位见谅。
一下是本人demo运行效果图:
以下是主程序中的onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll=(LinearLayout) findViewById(R.id.ll);
ll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Toast.makeText(MainActivity.this, "点击了LinearLayout", Toast.LENGTH_SHORT).show();
}
});
tv = (TextViewFixTouchConsume) this.findViewById(R.id.myTextView);
List<String> textList=new ArrayList<String>();
textList.add("张三");
textList.add("李四");
textList.add("王五");
CharSequence str=replace("@张三:哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈//@李四:哈哈哈啊哈哈哈哈哈哈哈哈哈哈阿斯顿发生地方哈哈哈//@王五:你好啊哈哈哦啊好好",textList);
tv.setText(str);
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
其中TextViewFixTouchConsume为重写的TextView,textList其实就是上面所讲到的
被转发人列表,通过从服务端获取的数据解析后一一添加进list,然后在replace方法中会执行一个方法:
public String getLinkString(String text, List<String> textList) {
for(int i=0; i<textList.size();i++){
text=text.replace("@" + textList.get(i), "<a href='" + textList.get(i) + "'>" + "@" + textList.get(i) + "</a>");
}
return text;
}
即将转发评论内容中的所有@xxx根据获取的被转发人列表中的昵称替换为<a href=“
xxx”>
@xxx</a>,之后通过Html.fromHtml将其格式化,再通过以下操作:
SpannableStringBuilder builder = new SpannableStringBuilder(text);
if (text instanceof Spannable) {
int end = text.length();
// 其实就是得到sp1
Spannable sp = (Spannable) text;
// 得到其中所有的关键字的数组
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
// 清楚掉所有的关键字标志
builder.clearSpans();
for (URLSpan url : urls) {
// 将关键字数组中的文字添加到新生成的style中去
MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
builder.setSpan(myURLSpan, sp.getSpanStart(url),
sp.getSpanEnd(url),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return builder;
即达到效果,其中的MyURLSpan继承自ClickableSpan,其中重写了onClick点击事件:
public void onClick(View widget) {
//这里面可实现界面跳转等操作
String nickName = mUrl.trim().substring(0);
Toast.makeText(MainActivity.this, nickName, Toast.LENGTH_SHORT).show();
}
源码下载地址: http://download.csdn.net/detail/baiyuliang2013/7942089