开发者

detect clipping in android TextView

开发者 https://www.devze.com 2022-12-09 00:13 出处:网络
I have a TextView in my android application that has a set width on it.It\'s currently got a gravity of \"center_horitonzal\" and a set textSize (9sp).I pull values to put on this label from a sqlite

I have a TextView in my android application that has a set width on it. It's currently got a gravity of "center_horitonzal" and a set textSize (9sp). I pull values to put on this label from a sqlite database, and some of the values are too large to fit in the TextView at the current textSize.

Is there a way to detect that the text inside a TextView is going to be clipped? I'd like to detect this, and lower the font until it fits. There is a nice property in the iPhone UILabel that handles this called "adjustToFit" (which also has a minimum font size), and I'm basically trying to emulat开发者_StackOverflowe that.

Here's an example of the TextView that I'm working with:

<TextView android:id="@+id/label5" android:layout_width="62px"
            android:layout_height="wrap_content" android:layout_x="257px"
            android:layout_y="169px" android:textSize="9sp" 
            android:textColor="#000"
            android:typeface="sans" android:textStyle="bold"
            android:gravity="center_horizontal" android:lines="1" />


I found a way to measure the width of text using the TextView's Paint object, and lower it until it fit in the size I needed. Here's some sample code:

    float size = label.getPaint().measureText(item.getTitle());
    while (size > 62) {
        float newSize = label.getTextSize() - 0.5f;
        label.setTextSize(newSize);
        size = label.getPaint().measureText(item.getTitle());
    }


Another way to do this (which might be equivalent) is something like this:

        TextView title = new TextView(context) {
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int textsize = 30;
                setTextSize(textsize);
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                while (getMeasuredHeight() > MeasureSpec.getSize(heightMeasureSpec)) {
                    textsize--;
                    setTextSize(textsize);
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                }
            }
        };

Just a warning that this seems to work, but I just threw it together - might be some edge cases in ways the TextView can be measured.


I wrote this function to trim off letters from the end of the text until it meets a certain width requirement.

The 0.38 function is setting the proportion of the screen I want to fill with this text, in this case, it was 38% since I wanted it to cover ~40% including padding. Worked for the cases I've tested it with.

Using this code to call the function below

DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

double maxWidth = (double)metrics.widthPixels*0.38 - 1;
TextPaint painter = station.getPaint();

String left = item.getLocationName();
left = trimToLength(painter, left, maxWidth);


textView.setText(left);

This is the function

public String trimToLength(TextPaint painter, String initialText, double width)
{
    String message = initialText;
    String output = initialText;

    float currentWidth = painter.measureText(output);
    while (currentWidth > width)
    {
        message = message.substring(0, message.length()-1);

        output = message + "...";

        currentWidth = painter.measureText(output);
    }

    return output;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消