ホームページ  >  記事  >  バックエンド開発  >  Android 文字列フォーマットのオープンソース ライブラリの紹介_PHP チュートリアル

Android 文字列フォーマットのオープンソース ライブラリの紹介_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:18:151045ブラウズ

Android 文字列フォーマット用のオープンソース ライブラリであるフレーズの紹介

前回のブログでは、Android は String.format を通じて文字列リソースの表示内容をフォーマット (動的に変更) し、String.format を使用して string.xml ファイル内の文字列をフォーマットする方法を紹介しました。オープン ソース ライブラリのフレーズは、String.format と比較して、フレーズを使用して文字列コードをフォーマットする方が読みやすくなっています。


1. フレーズプロジェクトの紹介:

1. ソース コード: フレーズ プロジェクトのソース コードは非常に単純です: Phrase.java コードは次のとおりです。

リーリー *

    *
  • キーを中括弧で囲みます。 2 つの {{ を使用して脱出します。
  • *
  • キーは小文字で始まり、その後に小文字とアンダースコアが続きます。
  • *
  • strings.xml にある単純な HTML タグなどのスパンは保持されます。
  • *
  • キーが一致しない場合はすぐに失敗します。
  • *
* コンストラクターは元のパターンを解析して、{@link Token} の二重リンク リストを作成します。 * これらのトークンは元のパターンを変更しないため、スパンは維持されます。 *

* {@link #format()} メソッドはトークンを反復処理し、反復中にテキストを置き換えます。の * 二重リンクリストでは、各トークンがその先行トークンに拡張された長さを問い合わせることができます。 */ public 最終クラス フレーズ { /**修正されていないオリジナルのパターン。*/ プライベート最終 CharSequence パターン。 /**すべてのキーは中括弧を除いて元のパターンから解析されます。*/ プライベート最終 Set キー = new HashSet(); private Final Map keyToValues = new HashMap(); /**すべてのキーを対応する値に置き換えた後にキャッシュされた結果。*/ プライベート CharSequence 形式。 /**コンストラクターは、元のパターンを解析して、この二重リンクされたトークンのリストを作成します。*/ プライベートトークンヘッド。 /**解析すると、これが現在の文字になります。*/ プライベート文字 curChar; プライベート int curCharIndex; /**解析が完了したことを示します。*/ プライベート静的最終整数 EOF = 0; /*** この API へのエントリ ポイント。 * * @throws パターンに構文エラーが含まれる場合は IllegalArgumentException。*/ public static Phrase from(Fragment f, int patternResourceId) { return from(f.getResources(), patternResourceId); } /*** この API へのエントリ ポイント。 * * @throws パターンに構文エラーが含まれる場合は IllegalArgumentException。*/ public static Phrase from(View v, int patternResourceId) { return from(v.getResources(), patternResourceId); } /*** この API へのエントリ ポイント。 * * @throws パターンに構文エラーが含まれる場合は IllegalArgumentException。*/ public static Phrase from(Context c, int patternResourceId) { return from(c.getResources(), patternResourceId); } /*** この API へのエントリ ポイント。 * * @throws パターンに構文エラーが含まれる場合は IllegalArgumentException。*/ public static Phrase from(Resources r, int patternResourceId) { return from(r.getText(patternResourceId)); } /*** この API へのエントリ ポイント。パターンは null 以外である必要があります。 * * @throws パターンに構文エラーが含まれる場合は IllegalArgumentException。*/ public static Phrase from(CharSequence pattern) { 新しいフレーズ(パターン)を返します。 } /*** 指定されたキーを null 以外の値に置き換えます。 Phrase インスタンスを再利用して置き換えることができます。 * 新しい値を持つキー。 * * キーがパターンにない場合は @throws IllegalArgumentException。*/ public Phrase put(String key, CharSequence value) { if (!keys.contains(key)) { throw new IllegalArgumentException("無効なキー: " + key); } if (値 == null) { throw new IllegalArgumentException("Null value for '" + key + "'"); } keyToValues.put(キー, 値); // キャッシュされた書式設定されたテキストを無効にします。 フォーマット済み = null; これを返します。 } /**@#put(String, CharSequence)を参照してください。*/ public Phrase put(String key, int value) { if (!keys.contains(key)) { throw new IllegalArgumentException("無効なキー: " + key); } keyToValues.put(key, Integer.toString(value)); // キャッシュされた書式設定されたテキストを無効にします。 フォーマット済み = null; これを返します。 } /*** キーがパターンに含まれていない場合は、黙って無視されます。 * * @ #put(String, CharSequence) を参照*/ public Phrase putOptional(String key, CharSequence value) { キーを返します。含まれる(キー) ? put(キー, 値) : これ; } /**@#put(String, CharSequence)を参照してください。*/ public Phrase putOptional(String key, int value) { キーを返します。含まれる(キー) ? put(キー, 値) : これ; } /*** すべてのキーを値に置き換えた後のテキストを返します。 * * キーが置換されていない場合は @throws IllegalArgumentException。*/ public CharSequence format() { if (formatted == null) { if (!keysToValues.keySet().containsAll(keys)) { Set missingKeys = 新しい HashSet(keys); missingKeys.removeAll(keysToValues.keySet()); throw new IllegalArgumentException("欠落しているキー: " + missingKeys); } // 元のパターンをコピーして、太字、斜体などのすべてのスパンを保持します。 SpannableStringBuilder sb = 新しい SpannableStringBuilder(パターン); for (トークン t = head; t != null; t = t.next) { t.expand(sb, keyToValues); } フォーマット済み = sb; } フォーマットされた状態で戻ります。 } /*** キーを展開せずに生のパターンを返します。デバッグにのみ役立ちます。通らない * {@link #format()} まで。そうするとすべてのスパンが削除されるためです。*/ @Override public String toString() { パターンを返します。toString(); }プライベート フレーズ(CharSequence パターン) { curChar = (pattern.length() > 0) ? pattern.charAt(0) : EOF; this.pattern = パターン; // 「Building Recognizers By Hand」のイディオムに基づいて手作業でコーディングされたレクサー。 // http://www.antlr2.org/book/byhand.pdf。 前のトークン = null; 次のトークン。 while ((next = token(prev)) != null) { // head で始まるトークンの二重リンクリストを作成します。 if (head == null) head = next; 前 = 次; } } /**入力パターンから次のトークンを返すか、解析が終了したら null を返します。*/ プライベートトークン token(前のトークン) { if (curChar == EOF) { null を返します。 } if (curChar == '{') { char nextChar = lookahead(); if (nextChar == '{') { leftCurlyBracket(前)を返します; else if (nextChar >= 'a' && nextChar = 'a' && curChar data); /**展開後の文字数を返します。*/ abstract int getFormattedLength(); /**展開後の文字インデックスを返します。*/ Final int getFormattedStart() { if (prev == null) { // 最初のトークン。 0を返します。 } それ以外 { // 先行ノードに開始インデックスを再帰的に問い合わせます。 戻り prev.getFormattedStart() + prev.getFormattedLength(); } } } /**トークン間の通常のテキスト。*/ プライベート静的クラス TextToken extends Token { プライベートfinal int textLength; TextToken(前のトークン, int textLength) { スーパー(前); this.textLength = textLength; } @Override void Expand(SpannableStringBuilder target, Map data) { // ターゲット内のスパンを変更しないでください。 } @Override int getFormattedLength() { textLength を返します。 } } /**2 つの中括弧のシーケンス。*/ プライベート静的クラス LeftCurlyBracketToken extends Token { LeftCurlyBracketToken(前のトークン) { スーパー(前); } @Override void Expand(SpannableStringBuilder target, Map data) { int start = getFormattedStart(); target.replace(start, start + 2, "{"); } @Override int getFormattedLength() { // と置換する {。 1を返します。 } } プライベート静的クラス KeyToken extends Token { /**{ と } のないキー。*/ プライベート最終文字列キー。 プライベート CharSequence 値。 KeyToken(前のトークン, 文字列キー) { スーパー(前); this.key = キー; } @Override void expand(SpannableStringBuilder target, Map data) { value = data.get(key); int replaceFrom = getFormattedStart(); // Add 2 to account for the opening and closing brackets. int replaceTo = replaceFrom + key.length() + 2; target.replace(replaceFrom, replaceTo, value); } @Override int getFormattedLength() { // Note that value is only present after expand. Don't error check because this is all // private code. return value.length(); } } }


2、字符串格式化原理:

通过阅读Phrase.java的代码可知,它用"{"和"}"将需要格式化的内容包起来,然后用键值对给需要改变的内容传值,包起来的内容为键,值为动态设置的内容,比如:

"Hi {first_name}, you are {age} years old."
我们要最终的显示内容为:“Hi UperOne, you are 26 years old.”这里的first_name和age是键,值为UperOne和26。


二、使用方法:

Phrase.java的类名上面的注释已经告诉了我们具体的使用方法:

/**
 * A fluent API for formatting Strings. Canonical usage:
 * 
 *   CharSequence formatted = Phrase.from("Hi {first_name}, you are {age} years old.")
 *       .put("first_name", firstName)
 *       .put("age", age)
 *       .format();
 * 
*
    *
  • Surround keys with curly braces; use two {{ to escape.
  • *
  • Keys start with lowercase letters followed by lowercase letters and underscores.
  • *
  • Spans are preserved, such as simple HTML tags found in strings.xml.
  • *
  • Fails fast on any mismatched keys.
  • *
* The constructor parses the original pattern into a doubly-linked list of {@link Token}s. * These tokens do not modify the original pattern, thus preserving any spans. *

* The {@link #format()} method iterates over the tokens, replacing text as it iterates. The * doubly-linked list allows each token to ask its predecessor for the expanded length. */ public final class Phrase
比如:

CharSequence parseStr = Phrase.from("Hi {first_name}, you are {age} years old.")
				 .put("first_name", "UperOne")
				 .put("age", "26")
				 .format();
		
mParseTxt.setText( parseStr );
用起来非常简单。



www.bkjia.comtruehttp://www.bkjia.com/PHPjc/885681.htmlTechArticleAndroid字符串格式化开源库phrase介绍 在上一篇博客Android通过String.format式化(动态改变)字符串资源的显示内容中介绍了通过String.format来式...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。