13

ここ数日間、これを理解しようとしてきましたが、成功していません...

私は現在アンドロイドを学んでおり、現在、学習プロジェクトとして歴史のある電卓を作成しています。すべての履歴を表示する TextView があります...電卓のフォントのように見えるデジタル フォントを使用していますが、これは数字と小数とコンマにのみ適しています。すべての演算子を強調表示し、別のフォント (現時点では Arial Narrow) で表示したい。カスタム フォントを適用する CustomTypeFaceSpan クラスを使用するフォントだけでなく、フォントの色を指定するスパン可能な文字列を使用して、これを美しく機能させることができました。

問題...書体を混在させると、行の高さに問題があるように見えるので、別のカスタム定義クラスを使用して、スパン可能なテキストの追加された各行に行の高さを適用する方法を示すこの投稿を見つけました。

public class CustomLineHeightSpan implements LineHeightSpan{
    private final int height;

    public CustomLineHeightSpan(int height){
        this.height = height;
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, FontMetricsInt fm) {
        fm.bottom += height;
        fm.descent += height;
    }

}

これはうまくいかないようで、その理由がわかりません。異なる書体を適用しない場合、最初の行の上にスペースがなく、行間に約 5 ピクセルのスペースがあり、期待どおりに表示されます。代替書体を適用すると、テキストの最初の行の上に約 10 ~ 15 ピクセルのスペースがあり、行間隔はほぼ同じ 10 ~ 15 ピクセルです。

書体のみでフォントサイズに違いはありません。何が欠けていますか。LineHeightSpan を実装し、chooseHeight メソッドをオーバーライドする CustomLineHeightSpan を実装しました。私はそれを次のように呼びます:

WordtoSpan.setSpan(新しい CustomLineHeightSpan(10), operatorPositions.get(ii), operatorPositions.get(ii) + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

CustomLineHeightSpan への呼び出しに何を入れても問題ないようです。何も変わらない...

私が何を見逃しているのか、誰にもわかりません...「見逃したなんて信じられない」という答えだと思いますが、現時点では理解できないようです。

助けてくれてありがとう:-)

4

1 に答える 1

22

私は最終的に LineHeightSpan の使用のより詳細な例を見つけました...実際には LineHeightSpan.WithDensity がより正確です... 以下は、私の問題を解決するのに役立った抜粋です:

private static class Height implements LineHeightSpan.WithDensity {
    private int mSize;
    private static float sProportion = 0;

    public Height(int size) {
        mSize = size;
    }

    public void chooseHeight(CharSequence text, int start, int end,
                             int spanstartv, int v,
                             Paint.FontMetricsInt fm) {
        // Should not get called, at least not by StaticLayout.
        chooseHeight(text, start, end, spanstartv, v, fm, null);
    }

    public void chooseHeight(CharSequence text, int start, int end,
                             int spanstartv, int v,
                             Paint.FontMetricsInt fm, TextPaint paint) {
        int size = mSize;
        if (paint != null) {
            size *= paint.density;
        }

        if (fm.bottom - fm.top < size) {
            fm.top = fm.bottom - size;
            fm.ascent = fm.ascent - size;
        } else {
            if (sProportion == 0) {
                /*
                 * Calculate what fraction of the nominal ascent
                 * the height of a capital letter actually is,
                 * so that we won't reduce the ascent to less than
                 * that unless we absolutely have to.
                 */

                Paint p = new Paint();
                p.setTextSize(100);
                Rect r = new Rect();
                p.getTextBounds("ABCDEFG", 0, 7, r);

                sProportion = (r.top) / p.ascent();
            }

            int need = (int) Math.ceil(-fm.top * sProportion);

            if (size - fm.descent >= need) {
                /*
                 * It is safe to shrink the ascent this much.
                 */

                fm.top = fm.bottom - size;
                fm.ascent = fm.descent - size;
            } else if (size >= need) {
                /*
                 * We can't show all the descent, but we can at least
                 * show all the ascent.
                 */

                fm.top = fm.ascent = -need;
                fm.bottom = fm.descent = fm.top + size;
            } else {
                /*
                 * Show as much of the ascent as we can, and no descent.
                 */

                fm.top = fm.ascent = -size;
                fm.bottom = fm.descent = 0;
            }
        }
    }
}

これは、この例から取られました。

それが何をするかは、以下に引用されているとおりです。

テキスト行を指定された高さに強制し、可能な場合はアセントを縮小/ストレッチします。アセントをさらに縮小するとテキストが読めなくなる場合は下降します。

これが次の人に役立つことを願っています:-)

于 2012-10-17T01:08:16.610 に答える