How to set font width in an Android textview?

雨燕双飞 提交于 2019-12-20 17:36:26

问题


I am developing an app that displays information such as ascii arts which are very sensitive to font width. I've been using monospace font, but it does not work well because there are wide chars (such as Chinese and Japanese characters) in the information and the textview does not make the wide chars exactly twice wide as regular chars. Therefore I am trying to see if it's possible to alter the width of fonts in a textview, or if there's better way to solve this problem? Is Installing another monospace font to my app a good idea? Any input is greatly appreciated. Thank you.

Kevin


回答1:


You can try

textView.setTextScaleX(1.5f);

textView.setTextSize(20);

textView.setTypeface(Typeface.MONOSPACE);    //all characters the same width

With these three methods I hope you can set the font to a desirable appearance.




回答2:


for those who wants to set monospace using xml, try adding 'android:typeface = "monospace"'

        <TextView
            android:id="@+id/tv_output"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"  
            android:typeface="monospace" />

before adding monospace

after adding monospace




回答3:


This question is too old, but I got similar issue and I eventually found a good solution.

I have font, which has no monospace variant. I need to display some hexadecimal value in few lines within TextView, but I don't want to use any other font.

Android documentation says:

Spans are powerful markup objects that you can use to style text at a character or paragraph level. By attaching spans to text objects, you can change text in a variety of ways, including adding color, making the text clickable, scaling the text size, and drawing text in a customized way. Spans can also change TextPaint properties, draw on a Canvas, and even change text layout.

So, I create custom MonospaceSpan implementation which derives from ReplacementSpan. This span detects the widest char of given text and draws others with the same width.

Here's result:

GitHub

MonospaceSpan.java

    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.text.style.ReplacementSpan;

    public class MonospaceSpan extends ReplacementSpan {
        private boolean ignoreFullText;

        public void setIgnoreFullText(boolean ignoreFullText) {
            this.ignoreFullText = ignoreFullText;
        }

        private int getMaxCharWidth(@NonNull Paint paint, @NonNull CharSequence text, int start, int end, float[] widths) {
            if (widths == null) {
                widths = new float[end - start];
            }

            paint.getTextWidths(text, start, end, widths);

            float max = 0;

            for (float w : widths) {
                if (max < w) {
                    max = w;
                }
            }

            return Math.round(max);
        }

        @Override
        public int getSize(@NonNull Paint paint, @NonNull CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
            if (fm != null) {
                paint.getFontMetricsInt(fm);
            }

            int count = end - start;

            if (text.charAt(start) == '\n') {
                count -= 1;
            }

            if (text.charAt(end - 1) == '\n') {
                count -= 1;
            }

            if (count < 0) {
                count = 0;
            }

            if (ignoreFullText) {
                return getMaxCharWidth(paint, text, start, end, null) * count;
            } else {
                return getMaxCharWidth(paint, text, 0, text.length(), null) * count;
            }
        }

        @Override
        public void draw(@NonNull Canvas canvas, @NonNull CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
            float[] widths = new float[end - start];
            int max = getMaxCharWidth(paint, text, start, end, widths);

            if (!ignoreFullText) {
                max = getMaxCharWidth(paint, text, 0, text.length(), null);
            }

            for (int i = 0, n = end - start; i < n; ++i) {
                float p = (max - widths[i]) / 2;
                canvas.drawText(text, start + i, start + i + 1, x + max * i + p, y, paint);
            }
        }
    }

Example of usage:

MainActivity.java

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.text.SpannableString;
    import android.widget.TextView;

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            String text = "Lorem ipsum\ndolor sit amet\n0123456789";
            SpannableString textMono = new SpannableString(text);
            textMono.setSpan(new MonospaceSpan(), 0, textMono.length(), 0);

            TextView textView1 = findViewById(android.R.id.text1);
            TextView textView2 = findViewById(android.R.id.text2);

            textView1.setText(text);
            textView2.setText(textMono);
        }
    }

res/layout/activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@android:id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="4dp"
            android:background="#fa0"
            android:fontFamily="@font/fredoka_one" />

        <TextView
            android:id="@android:id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="4dp"
            android:background="#0af"
            android:fontFamily="@font/fredoka_one" />
    </LinearLayout>


来源:https://stackoverflow.com/questions/6078194/how-to-set-font-width-in-an-android-textview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!