9

我有一个字符串格式的大故事。我想在画廊中显示文字。我想要做的是对所有文本进行切片,使我在画廊中的所有视图都显示适合屏幕的文本。

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

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

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

解决方案

非常感谢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>
4

3 回答 3

7

You check the TextView source code and see how they decide where to ellipsize the string.

The code for TextView is here.

Alternatively, you can use TextUtils class's public static CharSequence ellipsize(CharSequence text, TextPaint p, float avail, TruncateAt where) method.

TextPaint p should be the TextView's paint object.

Update:

Another alternative is to use 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 is the number of characters that fit in the TextView.
availableWidth is the width of the TextView in pixels.

This code is approximate and contains syntax errors. You will have to do some minor changes to get it working.

Update 2:

Another alternative would be to use

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

I think this is the best solution for you. Check its documentation here.

Update:

Sample code using paint.breakText method.

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;
}
于 2012-05-05T18:27:56.313 回答
0

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

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

于 2012-05-05T17:01:12.337 回答
0

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

于 2012-05-05T17:05:42.067 回答