Android中TextView的详细使用解析(一) 超链接的处理



TextView中 对于特殊字符的自动处理


例如  自动识别 网址 电话号码  邮箱等


 <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:autoLink="all"
        android:text="@string/hello_world" />

上面的这个textView就会自动地去识别其中的特殊字符,识别后,如果可以自动的调用系统的默认的浏览器,拨号器等进行处理

这里面配制了属性autoLink

该属性可设置的属性值如下:

none:不匹配任何链接(默认)               

web:匹配Web网址                   

email:匹配E-mail地址

phone:匹配电话号码                           

map:匹配映射地址                    

all:匹配所有的链接

这里配制的是all,也就是可以支持自动识别所有的链接

例如:

         TextView textView = (TextView) findViewById(R.id.textview);

		
	 textView.setText("我的博客:http://blog.csdn.net/zl18603543572 \n\n 我的电话 186******* \n\n 我的邮箱  [email protected]");
	

在显示出来的页面中 点击相应的条目,就会打开系统默认的 浏览器 或者是系统默认的拨号器或者是发送邮件的应用



Android中TextView的详细使用解析(一) 超链接的处理_第1张图片

拦截打开系统默认的这些应用

也就是说在点击链接的时候,指定打开的浏览器,或者是在自己的应用中打开相应的页面



// 实现超文本链接的点击 拦截
	private void SetLinkClickIntercept(TextView textView) {
		
		textView.setMovementMethod(LinkMovementMethod.getInstance());
		CharSequence text = textView.getText();
		if (text instanceof Spannable) {
			int end = text.length();
			Spannable sp = (Spannable) textView.getText();
			URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
			if (urls.length == 0) {
				return;
			}

			SpannableStringBuilder spannable = new SpannableStringBuilder(text);
			// 只拦截 http:// URI
			LinkedList<String> myurls = new LinkedList<String>();
			for (URLSpan uri : urls) {
				String uriString = uri.getURL();
				if (uriString.indexOf("http://") == 0 || uriString.indexOf("https://") == 0) {
					myurls.add(uriString);
				}
			}
			// 循环把链接发过去
			for (URLSpan uri : urls) {
				String uriString = uri.getURL();
				if (uriString.indexOf("http://") == 0 || uriString.indexOf("https://") == 0) {
					MyURLSpan myURLSpan = new MyURLSpan(uriString, myurls);
					spannable.setSpan(myURLSpan, sp.getSpanStart(uri), sp.getSpanEnd(uri),
							Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
				}
			}
			textView.setText(spannable);
		}
	}

	/**
	 * 处理TextView中的链接点击事件 链接的类型包括:url,号码,email,地图 这里只拦截url,即 http:// 开头的URI  处 https://开头的URI
	 */
	private class MyURLSpan extends ClickableSpan {
		private String mUrl; // 当前点击的实际链接
		private LinkedList<String> mUrls; // 根据需求,一个TextView中存在多个link的话,
						// 无论点击哪个都必须知道该TextView中的所有link,因此添加改变量

		MyURLSpan(String url, LinkedList<String> urls) {
			mUrl = url;
			mUrls = urls;
		}

             @Override
	      public void updateDrawState(TextPaint ds) {
		  ds.setColor(ds.linkColor);
		  ds.setUnderlineText(false); // 去掉下划线
	          ds.setColor(Color.parseColor("#034198"));	//设置超链接颜色

           }



		@Override
		public void onClick(View widget) {
			
// 这里你可以做任何你想要的处理
// 比如在你自己的应用中用webview打开,而不是打开系统的浏览器
			
                       String info = new String();
			
                        if (mUrls.size() == 1) {
// 只有一个url,根据策略弹出提示对话框
                         info = mUrls.get(0);
			
                      } else {
// 多个url,弹出选择对话框,意思一下
		         info = mUrls.get(0) + "\n" + mUrls.get(1);
			}
			
			// Uri uri = Uri.parse(mUrl);
			// Intent intent = new Intent(Intent.ACTION_VIEW, uri);
			// context.startActivity(intent);
			这里可以设置你要进行的操作
		}
	}}

 在使用的时候可以直接将上面的拦截操作的代码复制就行 
 

当然也可以解析相应的html文件

        String htmlString ="<font color ='red'>i love you </font><br>";
        htmlString+="<big><a href='https://baidu.com'>我的百度</a></big>";


        CharSequence sequence = Html.fromHtml(htmlString);
        //设置要显示的文本
        mTextView.setText(sequence);
        //必须进行下面的设置,否则点击链接无法进行浏览器的中转浏览
        mTextView.setMovementMethod(LinkMovementMethod.getInstance());


如果不进行setMovementMethod方法设置,是可以正常显示链接的


关于解析html的源码分析

这里用到的Html.fromHtml()方法,在源码中

    public static Spanned fromHtml(String source) {
        return fromHtml(source, null, null);
    }

    public static Spanned fromHtml(String source, ImageGetter imageGetter,
                                   TagHandler tagHandler) {
        Parser parser = new Parser();
        try {
            parser.setProperty(Parser.schemaProperty, HtmlParser.schema);
        } catch (org.xml.sax.SAXNotRecognizedException e) {
            // Should not happen.
            throw new RuntimeException(e);
        } catch (org.xml.sax.SAXNotSupportedException e) {
            // Should not happen.
            throw new RuntimeException(e);
        }

        HtmlToSpannedConverter converter =
                new HtmlToSpannedConverter(source, imageGetter, tagHandler,
                        parser);
        return converter.convert();
    }
可以看到这里有两个重载的方法 ,不过最终都是调用到了多参数的那个方法 

其中涉及到的第一个参数source就是带标签的html文字, formHtml方法中 使用到HtmlToSpannedConverter这个类,这个类是用来转换html文本的,这个类就 定义在Html.java中,

在HtmlToSpannedConverter类中,我们很容易的找到两个方法 

private void handleStartTag(String tag, Attributes attributes) {
 if (tag.equalsIgnoreCase("br")) {
            // We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>
            // so we can safely emite the linebreaks when we handle the close tag.
        } else if (tag.equalsIgnoreCase("p")) {
            handleP(mSpannableStringBuilder);
        } else if (tag.equalsIgnoreCase("div")) {
            handleP(mSpannableStringBuilder);
        } else if (tag.equalsIgnoreCase("strong")) {
            start(mSpannableStringBuilder, new Bold());
        } else if (tag.equalsIgnoreCase("b")) {
            start(mSpannableStringBuilder, new Bold());
        } else if (tag.equalsIgnoreCase("em")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("cite")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("dfn")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("i")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("big")) {
            start(mSpannableStringBuilder, new Big());
        } else if (tag.equalsIgnoreCase("small")) {
            start(mSpannableStringBuilder, new Small());
        } else if (tag.equalsIgnoreCase("font")) {
            startFont(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("blockquote")) {
            handleP(mSpannableStringBuilder);
            start(mSpannableStringBuilder, new Blockquote());
        } else if (tag.equalsIgnoreCase("tt")) {
            start(mSpannableStringBuilder, new Monospace());
        } else if (tag.equalsIgnoreCase("a")) {
            startA(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("u")) {
            start(mSpannableStringBuilder, new Underline());
        } else if (tag.equalsIgnoreCase("sup")) {
            start(mSpannableStringBuilder, new Super());
        } else if (tag.equalsIgnoreCase("sub")) {
            start(mSpannableStringBuilder, new Sub());
        } else if (tag.length() == 2 &&
                   Character.toLowerCase(tag.charAt(0)) == 'h' &&
                   tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
            handleP(mSpannableStringBuilder);
            start(mSpannableStringBuilder, new Header(tag.charAt(1) - '1'));
        } else if (tag.equalsIgnoreCase("img")) {
            startImg(mSpannableStringBuilder, attributes, mImageGetter);
        } else if (mTagHandler != null) {
            mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
        }
}
 private void handleEndTag(String tag) {
...
}


可以看到这两个方法就是用于分析html文本的开头与结尾




设置固定文字的背景颜色


<pre name="code" class="java"> private void setTextViewBackground(){
        
        String test = "设置固定部分的字符串的背景颜色....";
       
 //将字符串转换成SpannableString对象
        SpannableString  spannableString = new SpannableString(test);
        //确定要设置的子字符串的开始位置和结束位置
        int start = 2;
        int end = 6;
        //创建BackgroundColorSpan对象
        BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.BLUE);
       
 //使用setSpan方法 将指定的子字符串转换成BackgroundColorSpan对象
        spannableString.setSpan(backgroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

       
 //设置显示到textView上
        mTextView2.setText(spannableString);
    }


 
 

设置固定文字的背景色 与 显示 颜色

 private void setTextViewBackGroudnAndTextColor(){
        
        String test = "设置固定部分的字符串的背景颜色以及字体的颜色....";
        
        //将字符串转换成SpannableString对象
        SpannableString  spannableString = new SpannableString(test);
        
        //确定要设置的子字符串的开始位置和结束位置
        int start = 2;
        int end = 6;
        
        //创建BackgroundColorSpan对象
        ColorSpan backgroundColorSpan = new ColorSpan(Color.BLUE,Color.YELLOW);
        
        //使用setSpan方法 将指定的子字符串转换成BackgroundColorSpan对象
        spannableString.setSpan(backgroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        //设置显示到textView上
        mTextView3.setText(spannableString);
    }

class ColorSpan extends CharacterStyle{

        private int mTextColor;
        private int mBackgroundColor;
        public ColorSpan(int textColor,int backgroundColor){
            ColorSpan.this.mBackgroundColor = backgroundColor;
            ColorSpan.this.mTextColor = textColor;
        }
        @Override
        public void updateDrawState(TextPaint tp) {

            //设置背景颜色
            tp.bgColor = mBackgroundColor;
            //设置显示字体的颜色
            tp.setColor(mTextColor);
        }
    }

updateDrawState(TextPaint tp)
会在系统设置指定文字样式之前调用,以修改绘制文字的属性


Android中TextView的详细使用解析(一) 超链接的处理_第2张图片




TextView中设置文字的行间距



在布局文件中使用android:lineSpacingExtra

android:lineSpacingExtra="20dp"

第一行文本与第二文本之间的行间距是20dp


在布局文件中使用android:lineSpancingMultiplier属性

android:lineSpancingMltiplier = “1.8”
第一行文本与第二行文本之间的行间距是默认的行间距的1.8倍


使用用style

<style name="line-space">
       <item name="android:lineSpacingMultiplier">1.5</item>
</style>


使用setLineSpancing方法设置 

textView.setLineSpacing(50,1.2f);

这里面有两个参数,第一个相当于android:lineSpacingExtra属性,第二个参数相当于android:lineSpancingMultiplier属性,系统会采用表示行间距大的那个值




在TextView中设置省略号


当文字过多的时候 ,我们可以在文字的最后 或者是最前面或者 是中间添加省略号

使用的时候就是在TextView中设置属性ellipsize


在开头设置省略号

android:ellipsize="middle"

在中间设置省略号

android:ellipsize="start"


在结尾设置省略号

android:ellipsize="end"


不显示省略号 

android:ellipsize="none"<pre name="code" class="java">

 这是在布局文件中进行设置 
 

在代码中进行设置

<pre name="code" class="java">textView.setEllipsize(TextUtils.TruncateAt.END);


 
 

TextView设置走马灯的效果 

                       http://blog.csdn.net/zl18603543572/article/details/49980623

TextView设置滚动效果

<TextView
        android:id="@+id/txtview4"


        android:scrollbars="vertical"
        android:scrollbarStyle="insideOverlay"
        android:scrollbarFadeDuration="5000"
        

        android:maxLines="4"
        android:padding="10dp"
        android:textSize="20sp"
        android:layout_marginTop="10dp"
        android:singleLine="false"
        android:text="@string/textstring_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


其中:

scorllbarFadeDuration 设置的是滚动条从出现到消失的时间 ,单位是毫秒;




在布局文件中设置后,在代码中还必须设置 

 mTextView4.setMovementMethod(ScrollingMovementMethod.getInstance());



EditText中输入表情



public void addFaceEmotionClick(View view){
        //随机产生1到44的整数

        int randomId = 1+new Random().nextInt(44);

        try {
            //根据随机产生的整数从R.drawable类中获得相应资源ID的Field对象
            Field field = R.drawable.class.getDeclaredField("ee_" + randomId);
            //获得资源ID的值
            int resurceId = Integer.parseInt(field.get(null).toString());
            //根据资源ID获得资源图像的Bitmap对象
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),resurceId);
            //根据bitmap对象创建imagespan对象
            ImageSpan imageSpan = new ImageSpan(this,bitmap);
            //创建spannableString对象,插入用Imagespan对象封装的图像
            SpannableString spannableString = new SpannableString("ee_");
            //用imageSpan对象替换ee_
            spannableString.setSpan(imageSpan,0,3,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            //将随机获得的图像追加到EditText控件的最后
            mEditText.append(spannableString);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }



这里面使用到的"ee_" 是文件中的表情的名称


使用field.get方法来获取值的时候,如果获取的是静态变量,field.get方法的值设为Null即可,如果不是静态变量,需要指定一个变量所在的对象为值


EditTex中不能直接插入span对象,因此需要先使用SpannableString对象封装span对象,然后再将SpannableString对象插入到EditText控件中


设置下面的这个方法,弹出的系统软件盘不会遮挡文字的输入框


getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);


效果图

Android中TextView的详细使用解析(一) 超链接的处理_第3张图片




源码:









你可能感兴趣的:(Android中TextView的详细使用解析(一) 超链接的处理)