欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android仿新浪微博、QQ空間等帖子顯示(2)

 更新時間:2016年09月30日 16:46:48   作者:FlowLeaf  
這篇文章主要為大家詳細介紹了Android仿新浪微博、QQ空間等帖子顯示,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、介紹

這是新浪微博的一個帖子,剛好包括了話題、表情、@好友三種顯示。顯示方法上篇已經(jīng)闡述了,就是使用SpannableString。這篇主要介紹顯示這種帖子的解析工具類。

二、實現(xiàn)

1.字符串表示和對應(yīng)正則表達式

話題用##號括起來
表情用[]表示
@好友昵稱
借助正則匹配來解析帖子信息。

話題 -> #[^#]+#
表情 -> [[^]]+]
@好友 -> @好友昵稱

2.寫一個通用方法,對spanableString進行正則判斷,如果符合要求,則將內(nèi)容變色

private static void dealPattern(int color, SpannableString spannableString, Pattern patten, int start) throws Exception {
  Matcher matcher = patten.matcher(spannableString);
  while (matcher.find()) {
   String key = matcher.group();
   // 返回第一個字符的索引的文本匹配整個正則表達式,ture 則繼續(xù)遞歸
   if (matcher.start() < start) {
    continue;
   }
   // 計算該內(nèi)容的長度,也就是要替換的字符串的長度
   int end = matcher.start() + key.length();
   //設(shè)置前景色span
   spannableString.setSpan(new ForegroundColorSpan(color), matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
   if (end < spannableString.length()) {
    // 如果整個字符串還未驗證完,則繼續(xù)。。
    dealPattern(color, spannableString, patten, end);
   }
   break;
  }
 }

3.應(yīng)為有些是可點擊的,所以需要一個方法來處理可點擊的內(nèi)容

①先定義一個接口,通過接口的方式將點擊事件交給調(diào)用者

 public interface SpanClickListener<T>{
  void onSpanClick(T t);
 }

②寫一個通用方法,對spanableString進行正則判斷,如果符合要求,將內(nèi)容設(shè)置可點擊

private static void dealClick(SpannableString spannableString, Pattern patten, int start, final SpanClickListener spanClickListener, final Object bean){
  Matcher matcher = patten.matcher(spannableString);
  while (matcher.find()) {
   String key = matcher.group();
   // 返回第一個字符的索引的文本匹配整個正則表達式,ture 則繼續(xù)遞歸
   if (matcher.start() < start) {
    continue;
   }
   // 計算該內(nèi)容的長度,也就是要替換的字符串的長度
   int end = matcher.start() + key.length();
   spannableString.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
     spanClickListener.onSpanClick(bean);
    }
    @Override
    public void updateDrawState(TextPaint ds) {
     super.updateDrawState(ds);
     //設(shè)置畫筆屬性
     ds.setUnderlineText(false);//默認有下劃線
    }
   }, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
   if (end < spannableString.length()) {
    // 如果整個字符串還未驗證完,則繼續(xù)。。
    dealClick(spannableString, patten, end, spanClickListener, bean);
   }
   break;
  }
 }

4.表情解析方法(后面會寫一篇關(guān)于表情的處理)

private void dealExpression(Context context,
   SpannableString spannableString, Pattern patten, int start)
   throws Exception {
  Matcher matcher = patten.matcher(spannableString);
  while (matcher.find()) {

   String key = matcher.group();
   if (matcher.start() < start) {
    continue;
   }
   String value = emojiMap.get(key);
   if (TextUtils.isEmpty(value)) {
    continue;
   }
   // 通過上面匹配得到的字符串來生成圖片資源id
   int resId = context.getResources().getIdentifier(value, "drawable",
     context.getPackageName());
   if (resId != 0) {
    Drawable emoji = context.getResources().getDrawable(resId);
    int w = (int) (emoji.getIntrinsicWidth() * 0.40);
    int h = (int) (emoji.getIntrinsicHeight() * 0.40);
    emoji.setBounds(0, 0, w, h);
    // 通過圖片資源id來得到bitmap,用一個ImageSpan來包裝
    ImageSpan imageSpan = new ImageSpan(emoji);
    // 計算該圖片名字的長度,也就是要替換的字符串的長度
    int end = matcher.start() + key.length();
    // 將該圖片替換字符串中規(guī)定的位置中
    spannableString.setSpan(imageSpan, matcher.start(), end,
      Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    if (end < spannableString.length()) {
     dealExpression(context, spannableString, patten, end);
    }
    break;
   }
  }
 }

5.關(guān)鍵詞變色處理方法,這個實際中的使用場景比如地圖關(guān)鍵字搜索,匹配到關(guān)鍵字的地址中關(guān)鍵字顯示特別顏色

public static SpannableString getKeyWordSpan(int color, String str, String patterStr) throws Exception {
  SpannableString spannableString = new SpannableString(str);
  Pattern patten = Pattern.compile(patterStr, Pattern.CASE_INSENSITIVE);
  dealPattern(color, spannableString, patten, 0);
  return spannableString;
 }

6.話題處理,參數(shù)中需要傳入話題對象。這里只處理了一個帖子中只有一個話題的情況

 public static SpannableString getTopicSpan(int color, String str, boolean clickable,SpanClickListener spanClickListener, Topic topic) throws Exception {
  SpannableString spannableString = new SpannableString(str);
  Pattern patten = Pattern.compile(PatternString.TOPIC_PATTERN, Pattern.CASE_INSENSITIVE);
  if(clickable){
   dealClick(spannableString, patten, 0, spanClickListener, topic);
  }
  dealPattern(color, spannableString, patten, 0);
  return spannableString;
 }

7.@好友處理,參數(shù)中需要傳入@的好友列表

public static SpannableString getAtUserSpan(int color, String str, boolean clickable, SpanClickListener spanClickListener, List<User> atUsers) throws Exception {
  SpannableString spannableString = new SpannableString(str);
  Pattern patten;
  for (User u : atUsers) {
   patten = Pattern.compile("@" + u.getName(), Pattern.CASE_INSENSITIVE);
   if(clickable){
    dealClick(spannableString, patten, 0, spanClickListener, u);
   }
   dealPattern(color, spannableString, patten, 0);
  }
  return spannableString;
 }

8.表情處理,就這么簡潔

 public static SpannableString getExpressionSpan(Context context, String str) throws Exception {
  return ExpressionConvertUtil.getInstace().getExpressionString(context, str);
 }

三、使用

1.關(guān)鍵字變色

private void testColoredKeywd() {
  String string = "Android一詞的本義指“機器人”,同時也是Google于2007年11月5日,Android logo相關(guān)圖片,Android logo相關(guān)圖片(36張)\n";
  SpannableString cardText = null;
  try {
   cardText = SpanUtils.getKeyWordSpan(getResources().getColor(R.color.md_green_600), string, "Android");
  } catch (Exception e) {
   e.printStackTrace();
  }
  tvColoredKeywd.setText(cardText);
 }

2.話題測試,需要注意的是,讓部分內(nèi)容可點擊需要設(shè)置tvTopic.setMovementMethod(LinkMovementMethod.getInstance());,否則點擊無效果

private void testTopic() {
  String topic = "#舌尖上的大連#四種金牌烤芝士吃法愛吃芝士的盆友不要錯過了~L秒拍視頻\n";
  SpannableString topicText = null;
  try {
   topicText = SpanUtils.getTopicSpan(Color.BLUE, topic, true, new SpanUtils.SpanClickListener<Topic>() {
    @Override
    public void onSpanClick(Topic t) {
     Toast.makeText(MainActivity.this, "點擊話題:" + t.toString() , Toast.LENGTH_SHORT).show();
    }
   }, new Topic(1, "舌尖上的大連"));
  } catch (Exception e) {
   e.printStackTrace();
  }
  tvTopic.setText(topicText);
  //如果想實現(xiàn)點擊,必須要設(shè)置這個
  tvTopic.setMovementMethod(LinkMovementMethod.getInstance());
 }

3.@好友測試

private void textAtUsers(){
  List<User> users = new ArrayList<>();
  users.add(new User(1, "好友1"));
  users.add(new User(2, "好友2"));
  StringBuilder sb = new StringBuilder("快來看看啊");
  for (User u : users) {
   sb.append("@").append(u.getName());
  }
  sb.append("\n");
  try {
   SpannableString atSpan = SpanUtils.getAtUserSpan(Color.BLUE, sb.toString(), true, new SpanUtils.SpanClickListener<User>() {
    @Override
    public void onSpanClick(User user) {
     Toast.makeText(MainActivity.this, "@好友:" + user.toString(), Toast.LENGTH_SHORT).show();
    }
   }, users);

   tvTestAt.setText(atSpan);
   tvTestAt.setMovementMethod(LinkMovementMethod.getInstance());
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

4.表情測試

 private void textExpression(){
  String exStr = "今天天氣很好啊[呲牙],是不是應(yīng)該做點什么[色]";
  SpannableString span = null;
  try {
   span = SpanUtils.getExpressionSpan(this, exStr);
  } catch (Exception e) {
   e.printStackTrace();
  }
  tvExpression.setText(span);
 }

效果圖

下載:https://github.com/LineChen/SpannableStringDemo

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論