Android:TextView中的文本链接之--点击链接跳转总结(2种方法+2个实例应用)

       最近做了一些东西,涉及到比较重要些的技术点有:TextView正则匹配、文本链接、点击链接页面跳转,外加一个链接文本去掉默认的下划线。其实大部分都是从技术文档上学到的,应用了一下。便于以后查看,特别总结一下。如有更好的方法意见,望指点。


一、重写ClickableSpan类,点击跳转,并去掉默认的下划线

If an object of this type is attached to the text of a TextView with a movement method of LinkMovementMethod, the affected spans of text can be selected. If clicked, theonClick(View) method will be called.

默认超链接都带下划线的,重写ClickableSpan 去掉下划线:

private class MyClickSpan extends ClickableSpan { 
String text;
public NoLineClickSpan(String text) {
super();
this.text = text;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(ds.linkColor); //设置链接的文本颜色
ds.setUnderlineText(false); //去掉下划线
}
@Override
public void onClick(View widget) {

processHyperLinkClick(text); //点击超链接时调用
}
}

把超链接文本封装为MyClickSpan 对象,并添加到TextView中;

TextView tv = findViewById(R.id.tv_click);
SpannableString spStr = new SpannableString("试试看http://2711822222.163.com");
MyClickSpan clickSpan = new MyClickSpan (); //设置超链接
spStr.setSpan(clickSpan, 0, str.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tv.append(spStr);
tv.setMovementMethod(LinkMovementMethod.getInstance());//设置超链接为可点击状态


参考:http://orgcent.com/android-textview-no-underline-hyperlink/


二、微博中匹配@ 和#xxx#为文本链接,点击链接至此人页面。

android:TextView中的文本链接之--点击链接跳转总结(2种方法+2个实例应用) - 2711082222 - 蓉蓉来啦的博客 文本页面
android:TextView中的文本链接之--点击链接跳转总结(2种方法+2个实例应用) - 2711082222 - 蓉蓉来啦的博客 点击@科幻世界,传递了文本链接的文字内容
android:TextView中的文本链接之--点击链接跳转总结(2种方法+2个实例应用) - 2711082222 - 蓉蓉来啦的博客 点击#介已一,传递了文本链接的文字内容
 

显示文本的activity:

TextView txt = (TextView) findViewById(R.id.txt);
extractMention2Link(txt);

public static void extractMention2Link(TextView v) {
        v.setAutoLinkMask(0);
        Pattern pattern = Pattern.compile("@(\\w+?)(?=\\W|$)");  
        String scheme = String.format("%s/?%s=", Defs.SCHEMA, Defs.PARAM_UID);
        Linkify.addLinks(v, pattern, scheme, null, new TransformFilter() {
      @Override
      public String transformUrl(Matcher match, String url) {
       Log.d(TAG, match.group(1));
       return match.group(1); // 要传到到此人页面的东西
      }
     });        
        Pattern pattern1 = Pattern.compile("#(\\w+?)#");
        String scheme1 = String.format("%s/?%s=", Defs.SCHEMA1, Defs.PARAM_UID);
        Linkify.addLinks(v, pattern1, scheme1, null, new TransformFilter() {
      @Override
      public String transformUrl(Matcher match, String url) {
       Log.d(TAG, match.group(1));
       return match.group(1); // 要传到到此人页面的东西
      }
     });        
 }

Manifest.xml中,设置要跳转到的Activity

<activity android:name=".Profile" >
          <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="devdiv" android:host="sina_profile"/>
   </intent-filter>
        </activity>
        <activity android:name=".Profile1" >
   <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="devdiv" android:host="sina_profile1"/>
   </intent-filter>
        </activity>

Defs.java

 public class Defs {
 public static final String SCHEMA = "devdiv://sina_profile";
 public static final String SCHEMA1 = "devdiv://sina_profile1";
 public static final String PARAM_UID = "uid";
}

Profile.java

public class Profile extends Activity {
 private static final String TAG = "Profile";
 private static final Uri PROFILE_URI = Uri.parse(Defs.SCHEMA); 
 private String uid; 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);  
  extractUidFromUri();
  setTitle("Profile:Hello, " + uid);
 } 
 private void extractUidFromUri() {
  Uri uri = getIntent().getData();
        if (uri != null && PROFILE_URI.getScheme().equals(uri.getScheme())) {
          uid = uri.getQueryParameter(Defs.PARAM_UID);
             Log.d(TAG, "uid from url: " + uid);
        }
 }
}

Profile1.java

public class Profile1 extends Activity {
 private static final String TAG = "Profile";
 private static final Uri PROFILE_URI = Uri.parse(Defs.SCHEMA); 
 private String uid; 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);  
  extractUidFromUri();
  setTitle("Profile1:Hello, " + uid);
 } 
 private void extractUidFromUri() {
  Uri uri = getIntent().getData();
        if (uri != null && PROFILE_URI.getScheme().equals(uri.getScheme())) {
          uid = uri.getQueryParameter(Defs.PARAM_UID);
             Log.d(TAG, "uid from url: " + uid);
        }
 }
}

参考自:http://www.devdiv.com/forum.php?mod=viewthread&tid=35696&extra=&ordertype=2&page=1


实例一

Textview里匹配的文字有不同的颜色显示,可点击链接

SpannableString checkInSpanStr = new SpannableString("xxxxxxxxxx")
hilightAtUserName(checkInSpanStr);
tvContent.setText(checkInSpanStr);

tv.setMovementMethod(LinkMovementMethod.getInstance());//设置超链接为可点击状态

 private void hilightAtUserName(SpannableString spannableStr) {
       Pattern pattern = Pattern.compile(ConstantsConfig.AT_USER_NAME_REG_EXP);//正则匹配
       Matcher matcher = pattern.matcher(spannableStr);
       int start, end;
       while (matcher.find()) {
              start = matcher.start();
              end = matcher.end();
              spannableStr.setSpan(new ForegroundColorSpan(0xFF0099FA), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
       }
   }


实例二:

 已知String参数为 :before<at username="aaa" name="a" id="25"> :第一个 </at>after<at username="bbb" name="b" id="26">: </at>over

最后显示:before @aaa 第一个 after @bbb over

点击 aaa 传递25 点击bbb传递26 到个人页

调用:

    String strA=RevoPubAccess.getUsefulText(commentContent);
    String strDisplay =RevoPubAccess.getDisplayText(strA);    
    SpannableString checkInSpanStr = new SpannableString(strDisplay); 
    RevoPubAccess.setTextLink(context, strA, checkInSpanStr);
    listItemView.mCommenttext.setText(checkInSpanStr); 
    listItemView.mCommenttext.setMovementMethod(LinkMovementMethod.getInstance());

/**
  * change <at </at> text to @ username id text 
  * @param ori   before<at   username="aaa"   name="a"  id="25"> :第一个 </at>after<at   username="bbb"   name="b" id="25">: </at>over
  * @return   before@aaa:25 第一个 after@bbb:25  over
  */
  public static final String getUsefulText(String ori) {
   StringBuilder rs = new StringBuilder();
   int index = 0;
   Pattern pattern = Pattern.compile("<at.+?</at>");
   Matcher matcher = pattern.matcher(ori);
   while (matcher.find()) {
       rs.append(ori.substring(index, matcher.start()));      
       Pattern pattern1 = Pattern.compile("username=\".+?\"");
       Matcher matcher1 = pattern1.matcher(matcher.group());
       if (matcher1.find()) {
            rs.append("@"+matcher1.group().replaceAll("username\\s*=\\s*", "").replaceAll("\"", ""));
       } else {
         //  rs.append("没有username属性");
       }          
       Pattern pattern2 = Pattern.compile("id=\".+?\"");
       Matcher matcher2 = pattern2.matcher(matcher.group());
       if (matcher2.find()) {
           rs.append(":"+matcher2.group().replaceAll("id\\s*=\\s*", "").replaceAll("\"", "")+" ");
       } else {
          // rs.append("没有id属性");
       }
       Pattern pattern3 = Pattern.compile(":.*\\s");
       Matcher matcher3 = pattern3.matcher(matcher.group());
       if (matcher3.find()) {
//        Log.e("3", matcher3.group());
           rs.append(matcher3.group().replaceAll(":", ""));
       } else {
          // rs.append("没有texttent属性");
       }
       index = matcher.end();
   }
   rs.append(ori.substring(index, ori.length()));   
   Log.e("-----",  ori);
   Log.e("-----",  rs.toString());  
   return rs.toString();
 }
 
  /**
   * get the @username text for display
   * @param usefulText  before@aaa:25 第一个 after@bbb:25  over
   * @return
   */
  public static final String getDisplayText(String usefulText) {
   StringBuilder rs = new StringBuilder();
   int index = 0;
   Pattern pattern = Pattern.compile("@.+?\\s");
   Matcher matcher = pattern.matcher(usefulText);
   while (matcher.find()) {
       rs.append(usefulText.substring(index, matcher.start()));      
       Pattern pattern1 = Pattern.compile("username=\".+?\"");
       Matcher matcher1 = pattern1.matcher(matcher.group());
//       if (matcher1.find()) {
//            rs.append("@"+matcher1.group().replaceAll("username\\s*=\\s*", "").replaceAll("\"", ""));
//       } else {
//         //  rs.append("没有username属性");
//       }  
       String[]aa=matcher.group().split(":");
       rs.append(aa[0]+" ");
       index = matcher.end();
   }
   rs.append(usefulText.substring(index, usefulText.length()));   
   return rs.toString();  
 }

 

public  static final void setTextLink(Context con, String userfulText, SpannableString checkInSpanStr) 
 {  
   Log.e("checkInSpanStr", checkInSpanStr.toString());
   Pattern pattern = Pattern.compile("@.+?\\s");     
      Matcher matcher = pattern.matcher(checkInSpanStr); 
      while (matcher.find()) {
       String id = "" ;
//       Log.e("3", matcher.group());

       Pattern pattern1 = Pattern.compile(matcher.group().replaceAll("\\s", "")+":.+?\\s"); 
       Matcher matcher1 = pattern1.matcher(userfulText);
       if(matcher1.find())
       {
         id=matcher1.group().replaceAll("@.+?:", "");
         Log.e("revoId", id);
       }
       final String revoId=id;            
       checkInSpanStr.setSpan(new RevoClickSpan(con, revoId) , matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//       
      }       
  }


/**
 * remove underline and jump to mypage
 * @author Lyra
 * 2012.4.20
 */
public class RevoClickSpan extends ClickableSpan {
 Context mContext;
 String mId;
 @Override
 public void onClick(View widget) {
  Log.e("click", mId);
        Intent i= new Intent (mContext,MyPage.class);  
        i.putExtra(Base.WHOSEID, mId);
  mContext.startActivity(i);
 }
 
    public RevoClickSpan(Context con,  String id) {
         super();
         this.mContext = con;
         this.mId = id;
     }
 
    @Override
     public void updateDrawState(TextPaint ds) {
         ds.setColor(Color.RED);//设置连接的文本颜色
         ds.setUnderlineText(false); //去掉下划线
     } 
} 

另外:以下的博文很不错,可以参考:

http://www.2cto.com/kf/201109/106431.html

http://zhangning290.iteye.com/blog/1134286

http://www.cnblogs.com/ryan1012/archive/2011/07/12/2104087.html

http://blog.csdn.net/tianqixin/article/details/6785457

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现英文两端对齐,可以使用Android的JustifiedTextView控件。JustifiedTextView是一个自定义TextView,它可以将文本对齐到视图的左右边缘。这个控件使用了一个开源的库android-textview-align库,你可以在项目引入该库,也可以将其源代码拷贝到你的项目。 下面是使用JustifiedTextView控件实现英文两端对齐的步骤: 1. 在项目添加android-textview-align库。 2. 在布局文件使用JustifiedTextView控件。 3. 在代码设置文本和对齐方式。 示例代码如下: ```xml <com.codesgood.views.JustifiedTextView android:id="@+id/justified_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello world, this is a sample text to demonstrate the usage of JustifiedTextView." /> ``` ```java JustifiedTextView justifiedText = (JustifiedTextView) findViewById(R.id.justified_text); justifiedText.setText("Hello world, this is a sample text to demonstrate the usage of JustifiedTextView."); justifiedText.setAlignment(Paint.Align.LEFT); ``` 在上面的代码,我们将对齐方式设置为左对齐,这将使文本左右两端对齐。你也可以将对齐方式设置为央对齐、右对齐等。 需要注意的是,JustifiedTextView控件不支持在文本使用HTML标记,如果你需要在文本使用HTML标记,可以使用Android的Html.fromHtml()方法来解析HTML标记,然后将解析后的文本设置到JustifiedTextView控件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值