【问题标题】:How to calculate line height containing TextView with specific height in Android?如何在Android中计算包含具有特定高度的TextView的行高?
【发布时间】:2013-12-13 09:35:16
【问题描述】:

我想计算 (或布局)高度(在 DP 中),它仅包含 TextView 作为使用默认行间距时 TextView text size 的结果?
IE。对于这个布局:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/minRow1col1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:textIsSelectable="false"
        android:textSize="11dp" />  

</LinearLayout>

布局/行高是多少? (任何公式?我不需要运行时的值)

谢谢!

【问题讨论】:

    标签: android android-layout textview height


    【解决方案1】:

    我不知道这是否对你们有帮助,但我的解决方案是让行的高度独立于布局的高度,只需采用如下字体指标:

    myTextView.getPaint().getFontMetrics().bottom - myTextView.getPaint().getFontMetrics().top)
    

    有了这个你会得到行高,对我来说,它适用于所有单词(有一些像“g”或“j”这样的字符占用一些底部空间,所谓的“descender”等等)。

    【讨论】:

    • 我记得是 px。
    • 在处理 Paint 和大多数 Android API 时,它始终是 px。
    • 答案产生了正确的值,但应该注意的是,fontMetrics.top 和 fontMetrics.bottom 实际上并不代表您可能认为它们代表的内容。顶部:在给定文本大小下,字体中最高字形的基线上方的最大距离。底部:在给定文本大小下,字体中最低字形的基线下方的最大距离。 bottom - top 导致正确值的唯一原因是因为 top 是负数:请记住,Y 值向下增加,因此这些值将是正的,而测量距离的值将是负数。
    【解决方案2】:

    尝试使用TextViewTextPaint 对象。

    TextView tv = useTextView;
    String text = tv.getText().toString();
    Paint textPaint = tv.getPaint();
    
    Rect textRect = new Rect();
    textPaint.getTextBounds(text, 0, text.length(), textRext);
    
    int textHeight = textRect.height();
    

    根据Paint#getTextBound 的文档:

    返回边界(由调用者分配)的最小矩形 包含所有字符,隐含的原点位于 (0,0)。

    使用TextView 使用的Paint 对象将确保它具有用于绘制文本的相同参数集。

    【讨论】:

    • 跨区文本会发生什么。每条线可能有不同的高度。如果您执行 toString(),所有跨越的信息都将丢失。遇到这种情况怎么处理?
    • @Ashwin TextView 在内部使用 Spanned 来处理可编辑的文本。每次文本更改时都必须调用它,但应该得到当前文本的最短高度。
    【解决方案3】:

    您必须创建自定义Textview 并使用getActualHeight() 方法。 公式在哪里:actualHeight=(int) ((getLineCount()-1)*getTextSize());

    public class TextViewHeightPlus extends TextView {
        private static final String TAG = "TextView";
        private int actualHeight=0;
    
    
        public int getActualHeight() {
            return actualHeight;
        }
    
        public TextViewHeightPlus(Context context) {
            super(context);
        }
    
        public TextViewHeightPlus(Context context, AttributeSet attrs) {
            super(context, attrs);
            setCustomFont(context, attrs);
        }
    
        public TextViewHeightPlus(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
    
        }
    
       @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            actualHeight=0;
    
            actualHeight=(int) ((getLineCount()-1)*getTextSize());
    
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      你可以试试Paint.getTextBounds():

      String finalVal ="Hello";
      
      Paint paint = new Paint();
      paint.setTextSize(18);  
      paint.setTypeface(Typeface.SANS_SERIF);
      paint.setColor(Color.BLACK);
      paint.setStyle(Paint.Style.FILL);
      
      Rect result = new Rect();
      // Measure the text rectangle to get the height
      paint.getTextBounds(finalVal, 0, finalVal.length(), result);
      
      Log.d("WIDTH        :", String.valueOf(result.width()));
      Log.d("HEIGHT       :", String.valueOf(result.height()));
      

      Source.

      【讨论】:

      • 我只需要知道formula 而不是运行时的大小。
      • 我得到的数字代表什么? DP? PX?因为我测量了我的打印屏幕并得到了不同的值。另外,我得到的值比 9 大 8。
      • 由于getTextBounds函数正在绘制一个矩形,我会说在DP中所以取决于像素的屏幕密度,但我不能确定
      • @Pull:只有在 getResources() 的上下文中交谈时才会得到 DP。任何边界/位置始终是原始转换后的像素值。
      【解决方案5】:

      对于我的用例,我首先假设行高是一个取决于文本大小的线性函数,例如:

      line_height = text_size*some_constant
      

      现在 some_constant 可能也是一个函数,这取决于您使用的字体。但由于在我的要求中字体是静态的,所以我能够计算 some_constant 并以安全的方式重复使用。

      为了让您更了解我的用例,我正在缩放一段多行文本,以便将其放入一个高度可变的框中。

      在我的用例中,我想更进一步,包括空间乘数。这很简单,因为它只是等式中的另一个因素:

      line_height = text_size*some_constant*spacing_multiplier
      

      总而言之,如果您坚持使用相同的字体并计算一次 some_constant 的值,您可以(可能)获得您的功能。

      免责声明:我说了很多“可能”,因为我没有测试很多我的假设,但就像我说的,它适用于相当复杂的用例。

      【讨论】:

        猜你喜欢
        • 2017-11-03
        • 1970-01-01
        • 2013-07-22
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多