【问题标题】:How to set font width in an Android textview?如何在 Android 文本视图中设置字体宽度?
【发布时间】:2011-08-30 00:13:17
【问题描述】:

我正在开发一个应用程序来显示信息,例如对字体宽度非常敏感的 ascii 艺术。我一直在使用等宽字体,但效果不佳,因为信息中有宽字符(例如中文和日文字符),并且 textview 不会使宽字符恰好是常规字符的两倍。因此我想看看是否可以改变文本视图中字体的宽度,或者是否有更好的方法来解决这个问题?在我的应用程序中安装另一种等宽字体是个好主意吗?非常感谢任何输入。谢谢。

凯文

【问题讨论】:

    标签: android fonts width textview


    【解决方案1】:

    你可以试试

    textView.setTextScaleX(1.5f);
    
    textView.setTextSize(20);
    
    textView.setTypeface(Typeface.MONOSPACE);    //all characters the same width
    

    希望通过这三种方法,您可以将字体设置为理想的外观。

    【讨论】:

    • 感谢您的回复。似乎 setTextScaleX 根据其原始宽度调整字体宽度。因此宽度与原始宽度成正比,而不是使所有字体的宽度相同。有没有办法解决这个问题?谢谢。
    • 等宽​​字体用于使常规字符等宽。似乎它不适用于宽字符。为了正确显示 ascii 艺术,宽字符需要是常规字符的两倍。例如,aaaaaaa aaaa 这两个字符串在终端上看起来应该具有相同的长度。维基百科说等宽字体不支持中文和日文等宽字符语言。 en.wikipedia.org/wiki/Droid_(font) 因此它无法正确渲染宽字符的宽度,所以我希望找到一种方法来设置宽字符的宽度。谢谢。
    • 作为样式项:等宽
    • 请注意,如果您设置 fontFamily,它可能无法正常工作。有问题的值的示例是“sans-serif-light”
    【解决方案2】:

    对于那些想要使用 xml 设置等宽字体的人,请尝试添加 'android:typeface = "monospace"'

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

    在添加等宽之前

    添加等宽后

    【讨论】:

      【解决方案3】:

      这个问题太老了,但我遇到了类似的问题,我最终找到了一个好的解决方案。

      我有字体,它没有等宽变体。我需要在TextView 内的几行中显示一些十六进制值,但我不想使用任何其他字体。

      Android documentation 说:

      跨度是功能强大的标记对象,可用于在字符或段落级别设置文本样式。通过将跨度附加到文本对象,您可以通过多种方式更改文本,包括添加颜色、使文本可单击、缩放文本大小以及以自定义方式绘制文本。 Span 还可以更改 TextPaint 属性、在 Canvas 上绘图,甚至更改文本布局。

      因此,我创建了源自 ReplacementSpan 的自定义 MonospaceSpan 实现。此跨度检测给定文本的最宽字符并绘制具有相同宽度的其他字符。

      结果如下:

      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);
                  }
              }
          }
      

      使用示例:

      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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-23
        • 1970-01-01
        相关资源
        最近更新 更多