アイデア
コードU + 20BDの1つのルーブル記号で構成されるヘッドセットを作成し、ルーブル記号のテキストをレンダリングするときにこのヘッドセットを使用します。
スパンについて少し
Androidには、TextViewテキストのレンダリングに影響する特別なオブジェクトで文字列をマークするメカニズムがあります。 たとえば、 塗りつぶし / 背景の色 、 スタイル、またはすべてを一度にオーバーライドするオブジェクトがあります(Androidに組み込まれたマーカーの完全なリスト )。 このメカニズムについては、すでにこことここで habrについて書いています 。
適切なヘッドセットを作成する
将来のヘッドセットの基礎として、私はArtemy Lebedevから既製のソリューションを取りました。これは、少し前にHabréで書かれました。 このヘッドセットは、ラテンアルファベット文字(小文字aからs )に割り当てられたさまざまなスタイルのルーブル記号で構成されています。
文字i(に割り当てられているグリフを選択しました( ) Robotoヘッドセットでの使用に最も適しているように思えます。
ヘッドセットを編集するには、すばらしいGlyphsアプリケーションを使用しました。 ヘッドセットからすべてのグリフを削除し、選択したもののみを残しました。 私は彼にコードU + 20BDを割り当てました。 次のステップは、ttfにエクスポートすることです。
最終的には、 このようになりました 。
もちろん、ワンドを完成させることで首都Pのグリフを編集することは可能ですが、この問題には自信がありません。 それは多くのニュアンスを傷つけます。 誰もがこれを行うことができる場合、私はあなたのプルリクエストを喜んで受け入れます。
実装
まず、テンプレートからプロジェクトを作成します。 Android StudioスイートのBlank Activityのテンプレート、MainActivityと呼ばれるアクティビティを使用しました。
MainActivityのマークアップは次のようになります。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <EditText android:id="@+id/main_price_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" tools:hint="@string/main_price_hint" /> </LinearLayout>
ここではすべてが簡単です。EditTextの子孫を1つ持つLinearLayoutを作成します。 EditTextのhintプロパティを名前空間
tools
で設定して、ツールチップがプレビューでのみ表示されるようにします。 プログラムでは、プロンプトをプログラムで設定します。
MainActivity#onCreate
では、すべてのルーブル記号にTypefaceSpanというラベルが付けられたスパンドストリングを作成する必要があります。これにより、ヘッドセットを変更して特定の文字を描画できます。 ここで少し問題があります:TypefaceSpanはfont-family-システムセットからのフォントの名前でのみ作成できます。 幸いなことに、 TypefaceSpanソースコードから判断すると、このアプローチは、テキストレンダリングシステムの技術的な能力によるものではありません。
package me.pepyakin.roublesign; import android.graphics.Paint; import android.graphics.Typeface; import android.text.TextPaint; import android.text.style.MetricAffectingSpan; public class TypefaceSpan2 extends MetricAffectingSpan { private final Typeface mTypeface; public TypefaceSpan2(Typeface typeface) { mTypeface = typeface; } @Override public void updateDrawState(TextPaint ds) { apply(ds, mTypeface); } @Override public void updateMeasureState(TextPaint paint) { apply(paint, mTypeface); } private static void apply(Paint paint, Typeface tf) { int oldStyle; Typeface old = paint.getTypeface(); if (old == null) { oldStyle = 0; } else { oldStyle = old.getStyle(); } int fake = oldStyle & ~tf.getStyle(); if ((fake & Typeface.BOLD) != 0) { paint.setFakeBoldText(true); } if ((fake & Typeface.ITALIC) != 0) { paint.setTextSkewX(-0.25f); } paint.setTypeface(tf); } }
上記のTypefaceSpan2を使用して、必要なヘッドセットを使用してテキストをマークするだけです。
String priceHint = getString(R.string.main_price_hint); final Typeface roubleSupportedTypeface = Typeface.createFromAsset(getAssets(), "fonts/rouble2.ttf"); SpannableStringBuilder resultSpan = new SpannableStringBuilder(priceHint); for (int i = 0; i < resultSpan.length(); i++) { if (resultSpan.charAt(i) == '\u20BD') { TypefaceSpan2 roubleTypefaceSpan = new TypefaceSpan2(roubleSupportedTypeface); resultSpan.setSpan(roubleTypefaceSpan, i, i + 1, 0); } }
ここでは、ルーブルシンボルとルーブルグリフ付きヘッドセットを含むラインのテンプレートをロードします。
次に、テンプレートに基づいてSpannableStringBuilderを作成し、 setSpanを使用してヘッドセットを変更するためのマーカーを設定します。
ヒントを割り当て、
priceInput.setHint(resultSpan);
そして完了!
ソースへのリンク