代码之家  ›  专栏  ›  技术社区  ›  Will

阻止文本在Web地址的句点上拆分为多行

  •  9
  • Will  · 技术社区  · 14 年前

    我有一个android文本视图显示一些文本,它是多行的。但是,在文本中,我有时会有域名;如何阻止textView在其句点上拆分行?

    例如,是否有Unicode非中断期间?


    要查看包装电子邮件地址时的实际问题,请运行
    android create project--target 16--path demo--package com.example.demo--activity mainactivity
    并将 res/layout/main.xml中的文本更改为“ hello world,myactivity filler text+email foo@foo.com ”。在Galaxy S3(API级别16)上生成此输出:

    (根据需要调整文本,以查看其他屏幕尺寸的设备上的换行。值得注意的是,包装是在Intellij的布局预览中正确完成的,它只在设备上出现故障。)

    例如,是否有Unicode非中断期间?


    要查看包装电子邮件地址时的实际问题,请运行
    android create project --target 16 --path demo --package com.example.demo --activity MainActivity
    并在中更改文本 res/layout/main.xml Hello World, MyActivity filler text + email foo@foo.com “。在Galaxy S3(API级别16)上生成此输出:

    Email wrapping

    (根据需要调整文本,以查看其他屏幕尺寸的设备上的换行。值得注意的是,包装是在Intellij的布局预览中正确完成的,只有在设备上才有问题。)

    4 回复  |  直到 9 年前
        1
  •  7
  •   Community Dan Abramov    7 年前

    Word wrap comparison on Android 4.1.2 vs Android 4.2.2

    package com.example.nobr;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
    import android.widget.TextView.BufferType;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TextView helloWorld = (TextView) findViewById(R.id.hello_world);
            helloWorld.setText(R.string.hello_world, BufferType.EDITABLE);
    
            TextView longText = (TextView) findViewById(R.id.long_text);
            longText.setText(R.string.long_text_with_url, BufferType.EDITABLE);
        }
    }
    

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp" >
    
        <com.example.nobr.NonBreakingPeriodTextView
            android:id="@+id/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <com.example.nobr.NonBreakingPeriodTextView
            android:id="@+id/long_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/hello_world"
            android:layout_below="@+id/hello_world"
            android:layout_marginTop="20dp" />
    
    </RelativeLayout>
    

    package com.example.nobr;
    
    import android.content.Context;
    import android.graphics.Paint;
    import android.text.Editable;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.TextView;
    
    public class NonBreakingPeriodTextView extends TextView {
        private static final String TAG = "NonBreakingPeriodTextView";
    
        public NonBreakingPeriodTextView(Context context) {
            super(context);
        }
    
        public NonBreakingPeriodTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            Editable editable = getEditableText();
            if (editable == null) {
                Log.d(TAG, "non-editable text");
                return;
            }
            int width = getWidth() - getPaddingLeft() - getPaddingRight();
            if (width == 0) {
                Log.d(TAG, "zero-length text");
                return;
            }
    
            Paint p = getPaint();
            float[] widths = new float[editable.length()];
            p.getTextWidths(editable.toString(), widths);
            float curWidth = 0.0f;
            int lastWSPos = -1;
            int strPos = 0;
            final char newLine = '\n';
            final String newLineStr = "\n";
            boolean reset = false;
            int insertCount = 0;
    
            /*
             * Traverse the string from the start position, adding each character's width to the total
             * until: 1) A whitespace character is found. In this case, mark the whitespace position. If
             * the width goes over the max, this is where the newline will be inserted. 2) A newline
             * character is found. This resets the curWidth counter. curWidth > width. Replace the
             * whitespace with a newline and reset the counter.
             */
    
            while (strPos < editable.length()) {
                curWidth += widths[strPos];
    
                char curChar = editable.charAt(strPos);
    
                if (curChar == newLine) {
                    reset = true;
                } else if (Character.isWhitespace(curChar)) {
                    lastWSPos = strPos;
                } else if (curWidth > width && lastWSPos >= 0) {
                    editable.replace(lastWSPos, lastWSPos + 1, newLineStr);
                    insertCount++;
                    strPos = lastWSPos;
                    lastWSPos = -1;
                    reset = true;
                }
    
                if (reset) {
                    curWidth = 0.0f;
                    reset = false;
                }
    
                strPos++;
            }
    
            if (insertCount != 0) {
                setText(editable);
            }
        }
    }
    

    Word wrap on Android 4.1.2 with the fix

    enter image description here

        2
  •  1
  •   Siddharth Lele    14 年前

    android:autoLink="web"
    

        3
  •  1
  •   user1868091    11 年前

        4
  •  0
  •   Peter    9 年前

    else if(Character.isWhitespace(curChar))
    

    } else if (curChar == '\u00A0') {