Android字符串进阶之一(特殊字符的输入)

本文按照遇到问题的思路展开:
(一) 在Res下String.xml向字符串中插入“&”符号报错
如下图所示:

Paste_Image.png

翻译:在对实体的引用中,实体名必须紧跟在“&”后。
查找知道:这设计到HTML语言的字符集知识:
在网页中除了可显示常见的ASCII字符和汉字外,HTML还有许多特殊字符,它们一起构成了HTML字符集。有2种情况需要使用特殊字符,一是网页中有其特殊意义的字符,二是键盘上没有的字符。 字符集HTML字符可以用一些代码来表示,代码可以有2种表示方式。即字符代码(命名实体)和数字代码(编号实体)。字符代码以&符开始,以分号结束,其间是字符名;数字代码也以&符开始,以分号结束,其间是#号加编号。示例见下图,完整的html字符集在文后Excel附件中,并非全部,仅常用。

Paste_Image.png

(二) 这涉及到了Android对此有专门的处理
文档中有专门说明,如下图所示:

Paste_Image.png

字符串可以包含风格标签(styling tag),需要注意的是:你必须转码(escaping)缩写号( apostrophe即’)和引用号(quotation mark 即”或’)。你可风格化(style)和格式化(format)字符串。
1, 对缩写号和引号的处理
文档示例如下:

Paste_Image.png

正确的转码是:
A:用双引号将字符串全部圈住
B:使用转义符号“*”*
错误做法:
A:不处理
错误如下图所示:

Paste_Image.png

正确方法见上正确转码
B:使用html的字符代码代替缩写号
错误如下图所示:

Paste_Image.png

对以上错误的修正:

Paste_Image.png

Note:因为xml并不是完全实时编译,所以可以错误的xml语句并不当时报错,但当项目启动时,会报错。
2, 格式化字符串(format string)
即字符串中保留参数位作为模板,可以传入变量,转换。eg,SimpleDateFormat
模板为:yyyy-MM-dd,传入Date,得到1999-10-10
String.xml文件中代码如下:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

Java中代码如下:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

有必要说明的是:
%:产生字面值,貌似是这个意思。
1$:代表第一个参数
2$:代表第二个参数
s:参数类型是字符串
d:参数类型是数字
More:http://dlc.sun.com.edgesuite.net/jdk/jdk-api-localizations/jdk-api-zh-cn/builds/latest/html/zh_CN/api/java/util/Formatter.html#syntax
Java代码如下:
3, 在字符串中使用****Html****标记风格符号(Html makeup)
即Html的字符代码。一步一步,终于排除到问题的可能解答处。

  1. Android支持的Html元素,如下图所示:
Paste_Image.png

这三个字体标签,能够直接使用,称之为“styled text”。<b>内即为黑体字例如:
<string name="welcome">Welcome to <b>Android</b>!</string>

但是如果将以上的“<”分解,使用Html字符代码的话,用法将有所不同,这两个字符代码:
l “<”对应的字符代码为:<
l “>”对应的字符代码为:>
如下:
<string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string>

称之为“HTML-escaped”text,因为最终文本的显示要为styled text,所以需要将Html-styled text转为 styled text,调用fromHtml()方法。代码如下:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);

因为fromHtml()方法转换的对象是html-styled,所以调用此方法之前,必须使用文本格式化(formated text)和TextUtil.htmlEncode()方法,确保所有的可能html字符已经被转码(escape)。如果代码中含有特殊字符“&”“<”等,必须调用以上方法。代码如下:
String escapedUsername = TextUtil.htmlEncode(username);

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount);
CharSequence styledText = Html.fromHtml(text);

测试:如果name中含有html character,不转为html-styled,会有什么情况发生。
xml中字符串format如下:
<string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string>

测试代码如下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

    Resources rs = getResources(); 
    mTextView1 = (TextView) findViewById(R.id.textView1); 
    mTextvView2 = (TextView) findViewById(R.id.textView2); 
     
    String name = new  String("<Mike>"); 
    int count = 12345; 

    //未转为html-styled 
    format1 = String.format(rs.getString(R.string.welcome_messages), name,count); 
    CharSequence styledText1 = Html.fromHtml(format1); 
    mTextView1.setText(styledText1); 
     
    //转为html-styled 
    format2 = String.format(rs.getString(R.string.welcome_messages), TextUtils.htmlEncode(name),count); 
    CharSequence styledText2 = Html.fromHtml(format2); 
    mTextvView2.setText(styledText2); 
         
} 

模拟器显示如下:

Paste_Image.png
  1. 进入TextUtil类中,htmlEncode()方法做格式化字符代码的转换。且Android中,只接受以上五种特殊字符。代码如下:
    /**
    • Html-encode the string.
    • @param s the string to be encoded
    • @return the encoded string
      */
      public static String htmlEncode(String s) {
      StringBuilder sb = new StringBuilder();
      char c;
      for (int i = 0; i < s.length(); i++) {
      c = s.charAt(i);
      switch (c) {
      case '<':
      sb.append("<"); //$NON-NLS-1$
      break;
      case '>':
      sb.append(">"); //$NON-NLS-1$
      break;
      case '&':
      sb.append("&"); //$NON-NLS-1$
      break;
      case ''':
      sb.append("'"); //$NON-NLS-1$
      break;
      case '"':
      sb.append("""); //$NON-NLS-1$
      break;
      default:
      sb.append(c);
      }
      }
      return sb.toString();
      }

(三) ****源码中
有三处出现htmlEncode()方法。
如下图所示:

Paste_Image.png

第一处:即上文提到的TextUtils类
第二处: TextUtils的测试类,暂时不知道有什么用处
第三处:XmlParser类
定位到代码,如下:

Paste_Image.png

向上查看代码块描述:

Paste_Image.png

显然和之上的分析吻合。这些方法是对xml的输出,输出需要标准化,即 被未来的styled text(或者是其他)准确转换convert。
(四) 流程图

Paste_Image.png

**(五) ****单复数的处理(string format ****引入的问题)


文档中说明如下:

Paste_Image.png

测试各个关键字的效果如何。
Xml中定义plurals,如下:
<plurals name="numberOfSongsAvailable">
<item quantity="zero">Zero song found.</item>
<item quantity="one">One song found.</item>
<item quantity="two">Two song found.</item>
<item quantity="few">Few song found.</item>
<item quantity="other">Other song found.</item>
<item quantity="many">Many song found.</item>
</plurals>

代码中如下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

   int count1 = 0; 
   Resources res = getResources(); 
   String songsFound1 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count1, count1); 
   TextView textView1 = (TextView) findViewById(R.id.textView1); 
   textView1.setText(songsFound1); 
    
   int count2 = 1; 
   String songsFound2 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count2, count2); 
   TextView textView2 = (TextView) findViewById(R.id.textView2); 
   textView2.setText(songsFound2); 
    
   int count3 = 2; 
   String songsFound3 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count3, count3); 
   TextView textView3 = (TextView) findViewById(R.id.textView3); 
   textView3.setText(songsFound3); 
    
   int count4 = 3; 
   String songsFound4 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count4, count4); 
   TextView textView4 = (TextView) findViewById(R.id.textView4); 
   textView4.setText(songsFound4); 
    
   int count5 = 4; 
   String songsFound5 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count5, count5); 
   TextView textView5 = (TextView) findViewById(R.id.textView5); 
   textView5.setText(songsFound5); 
    
   int count6 = 1000; 
   String songsFound6 = res.getQuantityString(R.plurals.numberOfSongsAvailable, count6, count6); 
   TextView textView6 = (TextView) findViewById(R.id.textView6); 
   textView6.setText(songsFound6); 

}

模拟器显示如下:

Paste_Image.png

即在中文状态下,只支持one和other两个关键字。

The End!
本文出自 “小新专栏” 博客,请务必保留此出处http://mikewang.blog.51cto.com/3826268/862643

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容