How to add custom HTML tags for TextView in Android

Source: Internet
Author: User

TextView in Android supports some Html format tags. This includes common font size and color settings and text links. It is easy to use. You only need to use Html class conversion.For example:

TextView. setText (Html. fromHtml (str ));

However, in one case, the labels supported by default may not be enough. For example, we need to click a link in textView to return to an interface in the application, not just a network connection. How can we achieve this?

After several hours of research on the Html class source code in android, we found a solution and passed the test.

First, the source code of the Html class contains the following paragraph:

Copy codeThe Code is as follows :/**
* Is notified when HTML tags are encountered that the parser does
* Not know how to interpret.
*/
Public static interface TagHandler {
/**
* This method will be called whenn the HTML parser encounters
* A tag that it does not know how to interpret.
*/
Public void handleTag (boolean opening, String tag,
Editable output, XMLReader xmlReader );

An interface is defined here. What is the interface used?

Continue to read the code and see the code for parsing the Html tag:

Copy codeThe Code is as follows: private void handleStartTag (String tag, Attributes attributes ){
If (tag. inclusignorecase ("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. inclusignorecase ("p ")){
HandleP (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("div ")){
HandleP (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("em ")){
Start (mSpannableStringBuilder, new Bold ());
} Else if (tag. inclusignorecase ("B ")){
Start (mSpannableStringBuilder, new Bold ());
} Else if (tag. inclusignorecase ("strong ")){
Start (mSpannableStringBuilder, new Italic ());
} Else if (tag. canonical signorecase ("cite ")){
Start (mSpannableStringBuilder, new Italic ());
} Else if (tag. inclusignorecase ("dfn ")){
Start (mSpannableStringBuilder, new Italic ());
} Else if (tag. inclusignorecase ("I ")){
Start (mSpannableStringBuilder, new Italic ());
} Else if (tag. inclusignorecase ("big ")){
Start (mSpannableStringBuilder, new Big ());
} Else if (tag. inclusignorecase ("small ")){
Start (mSpannableStringBuilder, new Small ());
} Else if (tag. inclusignorecase ("font ")){
StartFont (mSpannableStringBuilder, attributes );
} Else if (tag. inclusignorecase ("blockquote ")){
HandleP (mSpannableStringBuilder );
Start (mSpannableStringBuilder, new Blockquote ());
} Else if (tag. inclusignorecase ("tt ")){
Start (mSpannableStringBuilder, new Monospace ());
} Else if (tag. inclusignorecase ("")){
StartA (mSpannableStringBuilder, attributes );
} Else if (tag. inclusignorecase ("u ")){
Start (mSpannableStringBuilder, new Underline ());
} Else if (tag. inclusignorecase ("sup ")){
Start (mSpannableStringBuilder, new Super ());
} Else if (tag. inclusignorecase ("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. inclusignorecase ("img ")){
StartImg (mSpannableStringBuilder, attributes, mImageGetter );
} Else if (mTagHandler! = Null ){
MTagHandler. handleTag (true, tag, mSpannableStringBuilder, mReader );
}
}

Private void handleEndTag (String tag ){
If (tag. inclusignorecase ("br ")){
HandleBr (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("p ")){
HandleP (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("div ")){
HandleP (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("em ")){
End (mSpannableStringBuilder, Bold. class, new StyleSpan (Typeface. BOLD ));
} Else if (tag. inclusignorecase ("B ")){
End (mSpannableStringBuilder, Bold. class, new StyleSpan (Typeface. BOLD ));
} Else if (tag. inclusignorecase ("strong ")){
End (mSpannableStringBuilder, Italic. class, new StyleSpan (Typeface. ITALIC ));
} Else if (tag. canonical signorecase ("cite ")){
End (mSpannableStringBuilder, Italic. class, new StyleSpan (Typeface. ITALIC ));
} Else if (tag. inclusignorecase ("dfn ")){
End (mSpannableStringBuilder, Italic. class, new StyleSpan (Typeface. ITALIC ));
} Else if (tag. inclusignorecase ("I ")){
End (mSpannableStringBuilder, Italic. class, new StyleSpan (Typeface. ITALIC ));
} Else if (tag. inclusignorecase ("big ")){
End (mSpannableStringBuilder, Big. class, new RelativeSizeSpan (1.25f ));
} Else if (tag. inclusignorecase ("small ")){
End (mSpannableStringBuilder, Small. class, new RelativeSizeSpan (0.8f ));
} Else if (tag. inclusignorecase ("font ")){
EndFont (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("blockquote ")){
HandleP (mSpannableStringBuilder );
End (mSpannableStringBuilder, Blockquote. class, new QuoteSpan ());
} Else if (tag. inclusignorecase ("tt ")){
End (mSpannableStringBuilder, Monospace. class,
New TypefaceSpan ("monospace "));
} Else if (tag. inclusignorecase ("")){
EndA (mSpannableStringBuilder );
} Else if (tag. inclusignorecase ("u ")){
End (mSpannableStringBuilder, Underline. class, new UnderlineSpan ());
} Else if (tag. inclusignorecase ("sup ")){
End (mSpannableStringBuilder, Super. class, new SuperscriptSpan ());
} Else if (tag. inclusignorecase ("sub ")){
End (mSpannableStringBuilder, Sub. class, new SubscriptSpan ());
} Else if (tag. length () = 2 &&
Character. toLowerCase (tag. charAt (0) = 'H '&&
Tag. charAt (1)> = '1' & tag. charAt (1) <= '6 '){
HandleP (mSpannableStringBuilder );
EndHeader (mSpannableStringBuilder );
} Else if (mTagHandler! = Null ){
MTagHandler. handleTag (false, tag, mSpannableStringBuilder, mReader );
}
}

We can see that if it is not the default tag, the handleTag method of mTagHandler is called. Therefore, we can implement this interface to parse the custom tag type.

Let's look at the sample code that I implemented to parse the <game> tag:

Copy codeThe Code is as follows: public class GameTagHandler implements TagHandler {
Private int startIndex = 0;
Private int stopIndex = 0;
@ Override
Public void handleTag (boolean opening, String tag, Editable output,
XMLReader xmlReader ){
If (tag. toLowerCase (). equals ("game ")){
If (opening ){
StartGame (tag, output, xmlReader );
} Else {
EndGame (tag, output, xmlReader );
}
}

}
Public void startGame (String tag, Editable output, XMLReader xmlReader ){
StartIndex = output. length ();
}

Public void endGame (String tag, Editable output, XMLReader xmlReader ){
StopIndex = output. length ();
Output. setSpan (new GameSpan (), startIndex, stopIndex,
Spanned. SPAN_EXCLUSIVE_EXCLUSIVE );
}

Private class GameSpan extends ClickableSpan implements OnClickListener {

@ Override
Public void onClick (View v ){
// Jump to a page
}
}

The above code is for <game>... </Game>.

Specific call method:

TextView. setText (Html. fromHtml ("Click <game> here </game> to jump to the game ",

Null, new GameTagHandler ()));

TextView. setClickable (true );

TextView. setMovementMethod (LinkMovementMethod. getInstance ());

After running, you can see that the string "here" contains a hyperlink. After you click the link, The onClick () method of the GameSpan class is called. You can jump in this method.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.