android textview计算字体大小以适合给定的边界

时间:2013-11-02 14:00:02

标签: android graphics fonts textview size

如何计算TextView的字体大小以适应我使用多行文字定义的界限

TextView内有RelativeLayout。在运行时将基于此知道App的屏幕大小。

    Rect boundsTv = TextPositions.getTextViewBounds(1, mainActivity.mWidthPx, mainActivity.mHeightPx);
    Log.e("SlideLoader", "paint.boundsTv() left, right, top, bottom :"+boundsTv.flattenToString());//paint.boundsTv() left, right, top, bottom :163 363 1767 749

    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) tvText.getLayoutParams();
    params.width = boundsTv.width();// right - left;
    params.height = boundsTv.height();// bottom - top;
    params.leftMargin = boundsTv.left; // Your X coordinate
    params.topMargin = boundsTv.top; // Your Y coordinate
    tvText.setLayoutParams(params);
    tvText.invalidate();

这就是问题所在。在某些设备上,字体很小,填充的文本比其他设备上的TextView的一半要小,甚至不适合一半。

输出代码来自设备,其中字体大小到目前为止很大。 我检查了几种方法,可能会建议这两种方法,都失败了:

    // left, top - right, bottom        
    TextPaint paint = tvText.getPaint();        
    paint.getTextBounds(text, 0, text.length()-1, boundsTv);        
    Log.e("SlideLoader", "paint.getTextBounds() left, right, top, bottom :"+boundsTv.flattenToString());//paint.getTextBounds() left, right, top, bottom :2 -33 16049 9, how to interpret this values?!

    float width = paint.measureText(text);// for single line

2 个答案:

答案 0 :(得分:1)

如果您不介意根据屏幕大小使用foldernames定义文本大小,例如:

RES /值-sw600dp / dimens.xml

dimens.xml的内容

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="text_size">20sp</dimen>
</resources>

RES /值-w1024dp

dimens.xml的内容

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="text_size">35sp</dimen>
</resources>

现在,您可以直接在布局中使用特定于屏幕尺寸的文字尺寸:

我选择为文本res / values / styles.xml

定义样式
<style name="Text">
    <item name="android:padding">5dp</item>
    <item name="android:paddingLeft">10dp</item>
    <item name="android:paddingRight">10dp</item>
    <item name="android:shadowColor">@color/Grey</item>
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item>
    <item name="android:shadowRadius">1</item>
    <item name="android:textColor">@color/Black</item>
    <!-- Here the dimen/text_size is used -->
    <item name="android:textSize">@dimen/text_size</item>
    <item name="android:textStyle">bold</item>
    <item name="android:typeface">monospace</item>
    <item name="android:ellipsize">none</item>
    <item name="android:gravity">left</item>
    <item name="android:maxLines">1</item>
    <item name="android:background">@color/Transparent</item>
</style>

因为我动态地将TextView添加到我的布局中,所以我定义了一个简单的entry.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="false" />

多数民众赞成。当我扩展entry.xml布局时,文本大小将反映显示的大小。

您可以在此处详细了解该技术:http://wptrafficanalyzer.in/blog/different-layouts-for-different-screen-sizes-in-android/

答案 1 :(得分:0)

Here 我已发布解决方案。我希望有人能给出比这更好的答案。

也可以是以下结果:1行半......

enter image description here

一些测试设备数据:我很高兴看到我有2个设备具有相同的屏幕尺寸或屏幕尺寸比例或Android版本或什么? :)

// Lenovo phone: DisplayMetrics{density=1.5, width=800, height=480, scaledDensity=1.6500001, xdpi=240.0, ydpi=240.0}        width/height: 1.666
// Lenovo tablet: DisplayMetrics{density=1.0, width=1024, height=552, scaledDensity=1.0, xdpi=160.0, ydpi=160.0}            width/height: 1.85
// Samsung tablet: DisplayMetrics{density=1.0, width=1280, height=752, scaledDensity=1.0, xdpi=149.82489, ydpi=150.51852}   width/height: 1.7
// THL phone:  DisplayMetrics{density=3.0, width=1920, height=1080, scaledDensity=3.3000002, xdpi=480.0, ydpi=480.0}        width/height: 1.77

哦,由于宽度/高度比不同,文字不会以同一个词结尾。 它可能恰好只有1行,而在其他设备需要2行......

        // get the text size
        int textSize = 50;
        int maxHeight = boundsTv.height();
        while (getHeightOfMultiLineText(text, textSize, params.width) > maxHeight) {
            textSize--;
        }
        float scaleFactor = mainActivity.getResources().getDisplayMetrics().density;
        float fuckingMagic = 1.8f; // large screens need a lower number, smaller screens a higher number.
        // Samsung tablet 1.4
        // THL phone 1.6
        // Lenovo phone: 2.2
        // Lenovo table 1.8

        float size = textSize / (fuckingMagic * scaleFactor);