微博点击不同文字,触发不同事件
2014-07-14 00:07
316 查看
主要的实现功能, 对微博中的 @XXX #话题# http://www.baidu.com 和 显示出搜索微博特殊字标记为红色效果, 点击普通文字,响应Item事件。
转载文章: http://www.cnblogs.com/TerryBlog/archive/2013/04/02/2994815.html 地址
需要注意,现在的匹配正则的时候, 需要,对@XX 和 #话题# 后面需要留一个空字符串, 这样正则才知道什么时候结束,
转载文章: http://www.cnblogs.com/TerryBlog/archive/2013/04/02/2994815.html 地址
需要注意,现在的匹配正则的时候, 需要,对@XX 和 #话题# 后面需要留一个空字符串, 这样正则才知道什么时候结束,
package com.maizi.activity.test; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import com.maizi.activity.R; import com.maizi.adapter.test.WeiboAdapter; import com.maizi.vo.test.Weibo; public class WeiboActivity extends Activity { private ListView listView; private ArrayList<Weibo> weiboList; private WeiboAdapter adapter; private LinearLayout ll; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); listView = (ListView) findViewById(R.id.lv_test); ll = (LinearLayout) findViewById(R.id.ll_top); weiboList = new ArrayList<Weibo>(); Weibo weibo = null; for (int i = 0; i < 10; i++) { weibo = new Weibo(); weibo.setContent("@weibo" + i + " " + "----#话题--" + i + "#" + " http://t.cn/nimashenshou 我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息v我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息我在测试这个微博数据信息"); weiboList.add(weibo); } adapter = new WeiboAdapter<Weibo>(this, weiboList); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(WeiboActivity.this, "onItemClick", 3000).show(); } }); listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case OnScrollListener.SCROLL_STATE_IDLE: Log.i("tag","已经停止:SCROLL_STATE_IDLE"); if(listView.getLastVisiblePosition() == (listView.getCount() - 1)){ if(ll.isShown()){ ll.setVisibility(View.GONE); Animation animation = AnimationUtils.loadAnimation(WeiboActivity.this, R.anim.out); animation.setFillAfter(true); animation.setFillBefore(false); ll.startAnimation(animation); } }else if(listView.getFirstVisiblePosition() == 0){ // 显示的位置是第三个的时候, 显示出来 if(!ll.isShown()){ ll.setVisibility(View.VISIBLE); Log.i("tag", "listView.getFirstVisiblePosition()"); Animation animation = AnimationUtils.loadAnimation(WeiboActivity.this, R.anim.in); animation.setFillAfter(true); animation.setFillBefore(false); // 显示最后的结果 ll.startAnimation(animation); } } break; case OnScrollListener.SCROLL_STATE_FLING: Log.i("tag","开始滚动:SCROLL_STATE_FLING"); break; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: Log.i("tag","正在滚动:SCROLL_STATE_TOUCH_SCROLL"); break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } }
package com.maizi.util; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.text.TextPaint; import android.text.method.LinkMovementMethod; import android.text.method.Touch; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.ImageSpan; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.maizi.activity.R; import com.maizi.activity.R.drawable; import com.maizi.vo.test.Weibo; import com.maizi.weight.WeiboText; public class WeiboUtils { /** * * @param mContext * @param textview * @param content * @param hasClick * 是否添加click */ public static void textViewSpan(Context mContext, WeiboText textview, String content, boolean hasClick, String search) { ArrayList<String> images = getImages(mContext); List<PositionItem> list = paresString(content, search); Spannable span = new SpannableString(content); String imageName = ""; for (PositionItem pi : list) { if (pi.getPrefixType() == 4) { if (images != null) { for (int i = 0; i < images.size(); i++) { if (images.get(i).equals(pi.getContent())) { imageName = images.get(i); imageName = imageName.substring(1, imageName.length() - 1); break; } } } try { Field f = (Field) R.drawable.class .getDeclaredField(imageName); int eId = f.getInt(R.drawable.class); Drawable drawable = mContext.getResources() .getDrawable(eId); if (drawable != null) { drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); ImageSpan imgSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE); span.setSpan(imgSpan, pi.start, pi.end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } else { span.setSpan(new ForegroundColorSpan(Color.GREEN), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } catch (Exception e) { span.setSpan(new ForegroundColorSpan(Color.GREEN), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } else if (pi.getContent().equals(search)) { span.setSpan(new ForegroundColorSpan(Color.RED), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { if (hasClick) { span.setSpan(new TextClickSapn(mContext, pi), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new ForegroundColorSpan(Color.GREEN), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { span.setSpan(new ForegroundColorSpan(Color.GREEN), pi.start, pi.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } textview.setText(span); if (hasClick) // textview.setMovementMethod(LinkMovementMethod.getInstance()); textview.setMovementMethod(LocalLinkMovementMethod.getInstance()); } /** * 这个是处理一条信息有多个#... 正则匹配相应的数据, 如果有查询的字, 显示红色 * * @param content * @return */ public static List<PositionItem> paresString(String content, String search) { String regex = "@[^\\s::《]+([\\s::《]|$)|#(.+?)#|http://t\\.cn/\\w+|\\[(.*?)\\]"; if (search != null) { regex = regex + "|" + search; } Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); boolean b = m.find(); List<PositionItem> list = new ArrayList<PositionItem>(); int count = 0; int lastIndex = 0; while (b) { int start = m.start(); int end = m.end(); String str = m.group(); if (str.startsWith("#")) { count++; if (count % 2 == 0) { b = m.find(lastIndex); continue; } } list.add(new PositionItem(start, end, str, content.length())); b = m.find(m.end() - 1); try { lastIndex = m.start() + 1; } catch (Exception e) { } } return list; } private static class TextClickSapn extends ClickableSpan { private PositionItem item; private Context mContext; public TextClickSapn(Context context, PositionItem item) { this.item = item; this.mContext = context; } @Override public void onClick(View widget) { switch (item.getPrefixType()) { case 1: Toast.makeText(mContext, item.getContentWithoutPrefix(), 3000) .show(); break; case 2: Toast.makeText(mContext, item.getContentWithoutPrefix(), 3000) .show(); break; case 3: // 直接使用调用浏览器 // 这个是短链 ,还需要条用微博接口,转成原始连接 才能访问 // 先使用短链去调用接口,获取长链,再启动浏览器 Intent intent = new Intent(); // intent.setAction("android.intent.action.VIEW"); Uri content_url = Uri.parse(item.getContentWithoutPrefix()); intent = new Intent(Intent.ACTION_VIEW); intent.setData(content_url); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); Toast.makeText(mContext, item.getContentWithoutPrefix(), 3000) .show(); break; default: break; } } @Override public void updateDrawState(TextPaint ds) { ds.setColor(Color.argb(255, 54, 92, 124)); ds.setUnderlineText(false); // 去掉下划线 } } public static class PositionItem { public int start; public int end; private int prefixType; private String content; private int strLenght; public PositionItem(int start, int end, String content, int strLenght) { this.start = start; this.end = end; this.content = content; this.strLenght = strLenght; } public PositionItem(int start, int end, String content) { this.start = start; this.end = end; this.content = content; } public String getContent() { return content; } public String getContentWithoutPrefix() { switch (getPrefixType()) { case 1: if (end == strLenght) return content.substring(1, strLenght); return content.substring(1, content.length() - 1); case 2: return content.substring(1, content.length() - 1); case 3: return content; default: return content; } } /** * 1 @ 人物 2 # 话题 3 http://t.cn/ 短链 4 [ 表情 * * @return */ public int getPrefixType() { if (content.startsWith("@")) return 1; if (content.startsWith("#")) return 2; if (content.startsWith("http://")) return 3; if (content.startsWith("[")) return 4; return -1; } } public static ArrayList<String> getImages(Context mContext) { // 反射获取所有的图片 ArrayList<String> images = new ArrayList<String>(); Class<drawable> drawables = R.drawable.class; Field[] fields = drawables.getFields(); if (fields != null) { for (Field field : fields) { images.add("[" + field.getName() + "]"); } } return images; } public static class LocalLinkMovementMethod extends LinkMovementMethod { static LocalLinkMovementMethod sInstance; public static LocalLinkMovementMethod getInstance() { if (sInstance == null) sInstance = new LocalLinkMovementMethod(); return sInstance; } @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])); } if (widget instanceof WeiboText) { ((WeiboText) widget).linkHit = true; 、、 } return true; } else { Selection.removeSelection(buffer); Touch.onTouchEvent(widget, buffer, event); return false; } } return Touch.onTouchEvent(widget, buffer, event); } } public static List<PositionItem> paresString(String content) { String regex = "@[^\\s::《]+([\\s::《]|$)|#(.+?)#|http://t\\.cn/\\w+|\\[(.*?)\\]"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); boolean b = m.find(); List<PositionItem> list = new ArrayList<PositionItem>(); while (b) { int start = m.start(); int end = m.end(); String str = m.group(); list.add(new PositionItem(start, end, str, content.length())); b = m.find(m.end() - 1); } return list; } }
package com.maizi.weight; import android.content.Context; import android.text.Html; import android.text.SpannableStringBuilder; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.TextView; public class WeiboText extends TextView { boolean dontConsumeNonUrlClicks = true; public boolean linkHit; public WeiboText(Context context) { super(context); } public WeiboText(Context context, AttributeSet attrs) { super(context, attrs); } public WeiboText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { linkHit = false; boolean res = super.onTouchEvent(event); if (dontConsumeNonUrlClicks) return linkHit; return res; } public void setTextViewHTML(String html) { CharSequence sequence = Html.fromHtml(html); SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence); setText(strBuilder); } }
package com.maizi.adapter.test; import java.util.List; import android.content.Context; import android.view.View; import android.view.ViewGroup; import com.maizi.activity.R; import com.maizi.adapter.BaseAdapterHelper; import com.maizi.adapter.test.TestAdapter.Item; import com.maizi.util.WeiboUtils; import com.maizi.weight.WeiboText; public class WeiboAdapter<Weibo> extends BaseAdapterHelper<Weibo>{ public WeiboAdapter(Context context, List<Weibo> list) { super(context, list); } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = flater.inflate(R.layout.weibo_item, null); WeiboText weiboText = (WeiboText) convertView.findViewById(R.id.tv_name); com.maizi.vo.test.Weibo Weibo = (com.maizi.vo.test.Weibo) list.get(position); weiboText.setText(Weibo.getContent()); }
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" > <translate android:duration="3000" android:fromYDelta="-100%p" android:interpolator="@android:anim/accelerate_interpolator" android:toYDelta="0%p" > </translate> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" > <translate android:duration="3000" android:fromYDelta="0%p" android:interpolator="@android:anim/accelerate_interpolator" android:toYDelta="-100%p" > </translate> </set>
相关文章推荐
- 鼠标点击不同位置触发的事件
- 实现类似微博@..的点击文字跳转事件 iOS
- 点击一个按钮触发不同的事件
- Android Studio中设置一个按钮的不同点击触发事件
- 新闻客户端首页图片无限循环滚动展示(可点击触发不同事件)初步封装IOS
- Android富文本实现不同的文字添加点击事件
- 新闻客户端首页图片无限循环滚动展示(可点击触发不同事件)初步封装IOS
- Android同一个TevtView显示不同颜色的文字,添加不同的点击事件。
- Unity_DOTween动画的学习(十一)_DOTweenPath路径编辑器的使用补充_结合按钮触发不同点击事件控制播放状态_Waypoints
- c# tabcontrol 点击不同的tabpage 触发不同的事件
- 页面选中文字弹出层,点击层中文字或者图片触发事件
- label 显示不同颜色 不同文字点击事件
- texeview设置不同文字的点击事件
- Android 按钮点击两次触发不同的事件
- c# tabcontrol 点击不同的tabpage 触发不同的事件
- 一个按钮点击两次触发不同事件
- jquery实现点击触发执行不同的事件
- 同一个TextView不同文字的点击事件
- android 按钮点击1次,点击3次和点击6次触发不同的事件
- JS自定义事件绑定--通过URL触发不同的点击事件