如何获得可以适合具有特定大小的Screen / TextView的N文本?

时间:2012-05-03 13:01:54

标签: android layout fonts

我有一个String格式的大故事。我想在画廊中显示文字。我想要做的是以这样的方式切片所有文本,使我在画廊中的所有视图显示适合屏幕的文本。

这样我就可以将我的字符串部分制作出来,每个部分都将显示在屏幕上,每个部分都将覆盖整个屏幕。

需要注意的一点是,用户可以更改文本大小,大小,因此屏幕上的文本也会随着大小的变化而变化。

我想知道是否有办法做到这一点。

解决方案

非常感谢userSeven7s帮助我。根据您的示例,我可以举个例子。这是:

package com.gsoft.measure.text;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainScreen extends Activity {

    private final String TAG = "MainScreen";
    private String textToBeShown = "These are the text";
    private String sampleText = "Here are more text";
    private TextView mTextView = null;

    Handler handler = new Handler() {

        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                updateUI();
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTextView = (TextView) findViewById(R.id.ui_main_textView);
        mTextView.setTextSize(20f);
        for (int i = 0; i < 100; i++) {
            textToBeShown = textToBeShown + " =" + i + "= " + sampleText;
        }

        // I am using timer as the in UI is not created and
        // we can't get the width.
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                // So that UI thread can handle UI work
                handler.sendEmptyMessage(1);
            }
        };
        Timer timer = new Timer();
        timer.schedule(task, 1000 * 1);
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    private void updateUI() {

        // Set text
        mTextView.setText(textToBeShown);
        // Check the width
        Log.e(TAG, "Width = " + mTextView.getWidth());

        // Check height of one line
        Log.e(TAG, "Line height= " + mTextView.getLineHeight());

        // Check total height for TextView
        Log.e(TAG, "Text height= " + mTextView.getHeight());

        // No of line we can show in textview
        int totalLine = mTextView.getHeight() / mTextView.getLineHeight();
        Log.e(TAG, "Total Lines are height= " + totalLine);


        for (int i = 0; i < totalLine; i++) {
            // Get No of characters fit in that textView
            int number = mTextView.getPaint().breakText(textToBeShown, 0, textToBeShown.length(), true,
                    mTextView.getWidth(), null);
            Log.e(TAG, "Number of chracters = " + number);

            // Show the text that fit into line
            Log.e(TAG, textToBeShown.substring(0, number));
            // Update the text to show next
            textToBeShown = textToBeShown.substring(number, textToBeShown.length());
        }
    }
}

这是我的XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_id_for_value"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/black"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/ui_main_textView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/twitter"
        android:textColor="@color/white" />

</LinearLayout>

3 个答案:

答案 0 :(得分:7)

您检查TextView源代码,看看他们如何决定将字符串椭圆化的位置。

TextView的代码为here

或者,您可以使用TextUtils班级的public static CharSequence ellipsize(CharSequence text, TextPaint p, float avail, TruncateAt where)方法。

TextPaint p应该是TextView的绘图对象。

更新

另一种方法是使用Paint.getTextWidths(char[] text, int index, int count, float[] widths)

textpaint.getTextWidths(char[] text, int index, int count, float[] widths);

int i = 0;
int prev_i = 0;
while (i < count) {
    textWidth = 0;
    for (int i = prev_i; (i < count) || (textWidth < availableWidth); i++) {
        textWidth += widths[i];
    }
    String textThatFits = mOriginalText.subString(prev_i, i);
    mTextview.setText(textThatFits);
    prev_i = i;
}

i是适合TextView的字符数 availableWidthTextView的宽度,以像素为单位。

此代码为近似值,包含语法错误。你必须做一些小改动才能让它发挥作用。

更新2:

另一种选择是使用

int breakText (CharSequence text,      
                int start, int end,   
                boolean measureForwards,   
                float maxWidth, float[] measuredWidth). 

我认为这是最适合您的解决方案。检查其documentation here.

更新

使用paint。breakText方法的示例代码。

paint.setSubpixelText(true);
int prevPos = 0;
while (nextPos  < chars.length) {
    int nextPos = paint.breakText(chars, prevPos, chars.length, maxWidth, null);
    tvStr = str.substring(prevPos, nextPos);
    prevPos = nextPos+1;
}

答案 1 :(得分:0)

如果每个部分具有不同数量的字符,则它们还需要具有不同大小的字体。不仅如此,太小的设备也会有太小的字体大小,因为文本需要适合更小的空间。 我建议为所有部件使用相同的字体大小,同时允许在没有足够空间的情况下向下滚动。

为此,您可以在每个页面上使用带有滚动视图的viewpager,每个都包含一个textview。

答案 2 :(得分:0)

Graphics.getFontMetricsFontMetrics.stringWidth可帮助您确定屏幕上文字的实际大小。根据此计算,您可以确定显示的子字符串应该有多长。