Home  >  Q&A  >  body text

android - 对于一个单行TextView,当字符串超出一行时,如何获取未显示的部分字符串?

PHP中文网PHP中文网2766 days ago409

reply all(1)I'll reply

  • 大家讲道理

    大家讲道理2017-04-17 14:36:53

    Assume that the width of TextView is a specific value set in xml, such as 300dp,
    (The purpose is to simplify this problem. If it is set to match_parent or wrap_content, its width needs to be calculated when the program is running, and the total getWidth value must be calculated directly. It returns 0, which is more troublesome)

    For example, it is configured like this:

        <TextView
            android:id="@+id/textView"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:singleLine="true" />

    is then filled with an extra long string, like this:

    String str = "If you really want to hear about it, the first thing you'll probably want to know";

    This will result in incomplete display, like this:
    If you really want to hear about it, the first thin...

    So, if you want to get the number of displayed characters or the number of undisplayed characters, then the key is how to calculate the width of each character .
    Then iterate through this string. When the sum of the widths of the current n characters exceeds the width of the TextView, the number of displayed characters is obtained.

    String str = "If you really want to hear about it, the first thing you'll probably want to know";
    mTextView = (TextView) findViewById(R.id.textView);
    
    // 计算TextView宽度:xml中定义的宽度300dp,转换成px
    float textViewWidth = convertDpToPixel(300);
    float dotWidth = getCharWidth(mTextView, '.');
    Log.d(TAG, "TextView width " + textViewWidth);
    
    int sumWidth = 0;
    for (int index=0; index<str.length(); index++) {
        // 计算每一个字符的宽度
        char c = str.charAt(index);
        float charWidth = getCharWidth(mTextView, c);
        sumWidth += charWidth;
        Log.d(TAG, "#" + index + ": " + c + ", width=" + charWidth + ", sum=" + sumWidth);
        
        if (sumWidth + dotWidth*3 >= textViewWidth) {
            Log.d(TAG, "TextView shows #" + index + " char: " + str.substring(0, index));
            break;
        }
    }
    
    // Dp转Px
    private float convertDpToPixel(float dp){
        Resources resources = getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * (metrics.densityDpi / 160f);
        return px;
    }
    
    // 计算每一个字符的宽度
    public float getCharWidth(TextView textView, char c) {
        textView.setText(String.valueOf(c));
        textView.measure(0, 0);
        return textView.getMeasuredWidth();
    }  

    The results are as follows, passed the test on Honor 3C and LG G3 (G3 displays one more character than the calculated result) :

    10-22 01:17:42.046: D/Text(21495): TextView width 600.0
    10-22 01:17:42.048: D/Text(21495): #0: I, width=8.0, sum=8
    10-22 01:17:42.049: D/Text(21495): #1: f, width=9.0, sum=17
    10-22 01:17:42.049: D/Text(21495): #2:  , width=7.0, sum=24
    10-22 01:17:42.049: D/Text(21495): #3: y, width=14.0, sum=38
    ......
    10-22 01:17:42.053: D/Text(21495): #17: t, width=9.0, sum=213
    10-22 01:17:42.053: D/Text(21495): #18:  , width=7.0, sum=220
    10-22 01:17:42.053: D/Text(21495): #19: t, width=9.0, sum=229
    ......
    
    10-22 01:17:42.061: D/Text(21495): #50: n, width=16.0, sum=575
    10-22 01:17:42.061: D/Text(21495): #51: g, width=16.0, sum=591
    10-22 01:17:42.061: D/Text(21495): TextView shows #51 char: If you really want to hear about it, the first thin

    That’s it.

    reply
    0
  • Cancelreply