QQ空间点评列表效果实现
来源:互联网 发布:淘宝怎么弄金牌卖家 编辑:程序博客网 时间:2024/05/29 10:08
首先,我们要实现的效果是这样的:
1. 评论人和被评论人颜色与评论内容颜色不同。
通过重写ClickabSpan的updateDrawState方法来实现。
@Overridepublic void updateDrawState(TextPaint ds) {ds.setUnderlineText(false);ds.setColor(Color.BLUE);}
2. 点击评论人名字C(onClick,onLongClick),触发相应的操作,点击有selector效果。
3. 点击评论内容D(onClick,onLongClick),触发相应的操作,点击有selector效果。
4. 点击layout B(onClick,onLongClick),触发相应的操作,点击有selector效果。
5. 点击layout A(onClick,onLongClick),触发相应的操作,点击有selector效果。
要求A,B,C的点击效果不冲突(B和D的点击效果一致)。可以操作QQ空间体验一下。
主要是实现Layout B的效果。
B是一个包含TextView的RelativeLayout。而这个TextView的text使用了ClickableSpan,当点击ClickableSpan指向的内容时,会执行ClickableSpan的onClick方法。而当点击TextView中非ClickableSpan指向的内容时,却不会执行RelativeLayout的点击行为。
我们首先来解决这个问题。
我们要达到的目标是:当点击TextView中ClickableSpan指向的内容时,响应的是ClickableSpan的onClick方法。而当点击TextView中非ClickableSpan指向的内容时,响应的是RelativeLayout的点击事件。
怎么才能实现呢?
最直观的想法就是重写TextView的onTouchEvent方法,当触摸到ClickableSpan指向的内容时,onTouchEvent返回true,当触摸到非ClickableSpan指向的内容时,onTouchEvent需要返回false,让其父view,也就是RelativeLayout去处理。(涉及到事件传递方面的知识)。
最关键的问题来了,怎么判断用户点触的是ClickableSapn指向的内容?
我们想,当我们点击到ClickableSpan指向的内容时,ClickableSpan可以响应,它是怎么判断的?
我们在使用ClickableSpan的时候必须要设置LinkMoventMethod,否则点击ClickableSpan是没有效果的。
public void setHtmlText(String str) {Spannable span = setClickableSpan(str);if (null != span) {setMovementMethod(LinkMovementMethod.getInstance());setText(span);} else {setText(str);}}
(里建议在有ClickableSpan的时候才设置LinkMovementMethod。)
我们再看下TextView的onTouchEvent方法,其中有这样一段代码:
if (mMovement != null) { handled |= mMovement.onTouchEvent(this, (Spannable) mText, event); }
mMovement就是设置的LinkMovementMethod,我们再去看下LinkMovementMethod的源代码:
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); Layout layout = widget.getLayout(); int line = layout.getLineForVertical(y); int off = layout.getOffsetForHorizontal(line, x); ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); }
就是在这个方法中触发的ClickableSpan的onClick事件。我们可以借鉴这个方法的代码来判断是否点击到ClickableSpan指向的区域。
基于此,我们重写TextView,命名为MyTextView:
主要方法有两个:
@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean result = super.onTouchEvent(event);int action = event.getAction();int x = (int) event.getX();int y = (int) event.getY();x -= getTotalPaddingLeft();y -= getTotalPaddingTop();x += getScrollX();y += getScrollY();Layout layout = getLayout();int line = layout.getLineForVertical(y);int off = layout.getOffsetForHorizontal(line, x);CharSequence text = getText();if (TextUtils.isEmpty(text) || !(text instanceof Spannable)) {return result;}Spannable buffer = (Spannable) text;ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);if (link.length > 0) {return true;} else {return false;}}
@Overridepublic boolean hasFocusable() {return false;}
ok,测试,搞定。
RelativeLayout可以通过设置background来设置selector,那点击ClickableSpan的时候,selector效果是怎么实现?
ClickableSpan没有API可以调用去设置selector,我们可以通过在onTouchEvent方法中通过监听ACTION_DOWN和ACTION_UP来设置不同的background来达到这种效果。
我们通过BackgroundSpan来设置背景颜色。
那贴上我们加上selector效果后MyTextView的onTouchEvent方法代码:
@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean result = super.onTouchEvent(event);int action = event.getAction();int x = (int) event.getX();int y = (int) event.getY();x -= getTotalPaddingLeft();y -= getTotalPaddingTop();x += getScrollX();y += getScrollY();Layout layout = getLayout();int line = layout.getLineForVertical(y);int off = layout.getOffsetForHorizontal(line, x);CharSequence text = getText();if (TextUtils.isEmpty(text) || !(text instanceof Spannable)) {return result;}Spannable buffer = (Spannable) text;ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);if (link.length != 0) {if (action == MotionEvent.ACTION_DOWN) {mStart = buffer.getSpanStart(link[0]);mEnd = buffer.getSpanEnd(link[0]);if (mStart >= 0 && mEnd >= mStart) {buffer.setSpan(new BackgroundColorSpan(Color.GRAY), mStart, mEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {if (mStart >= 0 && mEnd >= mStart) {buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), mStart, mEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);Selection.removeSelection(buffer);mStart = -1;mEnd = -1;}}return true;} else {if (mStart >= 0 && mEnd >= mStart) {buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), mStart, mEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);Selection.removeSelection(buffer);mStart = -1;mEnd = -1;}return false;}}
ok,测试,搞定。
注意,当使用ListView的onItemClick和onItemLongClick来处理点击事件时,会造成ListView的子View与Item的点击事件冲突。可以使用在getView的时候,通过设置View的onClick事件和onLongClick事件来达到效果。
Demo地址:QQ空间点评列表效果Demo- QQ空间点评列表效果实现
- java实现QQ空间日志列表获取
- 实现QQ空间评论列表样式
- QQ空间图片查看效果实现
- 实现QQ空间中显示照片效果
- jQuery实现QQ空间图片展示效果
- android仿QQ列表的效果实现
- Android ExpandableListView实现QQ好友列表效果
- 组TableView实现QQ好友列表效果
- JS实现QQ空间打开照片的效果源代码
- ScrollView的阻尼回弹效果实现(仿qq空间)
- Android评论工具类,实现QQ空间文字评论效果
- Android自定义ListView实现QQ空间顶部效果
- 【转载】android仿QQ列表的效果实现
- android实现仿照QQ好友列表滑动效果
- tableview实现qq好友列表点击拉伸的效果
- 利用Scroller实现防QQ列表侧滑效果
- 使用RecyclerView 简单实现QQ好友列表展开效果
- 如何让有物理键的手机在ActionBar始终显示更多菜单menu键
- string.Format格式化
- 毕业设计---background
- wince下流式驱动的编写
- linux 静态ip 设置
- QQ空间点评列表效果实现
- android高分段进阶攻略(7)音乐播放器UI设计——抽屉效果
- AE属性查询(c#)
- HashMap的工作原理
- 在深圳网络营销培训学习中:让你的心情靓丽起来吧
- C++类定义
- 一切都会好起来的
- informatica9.5.1后最一步出错(ICMD_10033,INFACMD_10053)
- Hadoop 2.2.0 测试出错处理