从分裂停止文本多行的网页地址的时期 [英] Stopping text from splitting to multiple lines on the periods in web addresses

查看:105
本文介绍了从分裂停止文本多行的网页地址的时期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android的TextView显示一些文本,这是多行。然而,在文中,我有时域名;我怎么可以停止的TextView从分裂排队的时间在其中?

I have an Android TextView displaying some text, and it's multi-line. However, in the text, I sometimes have domain names; how can I stop the TextView from splitting the lines up on the periods in them?

有没有单code非磨合期,例如?

Is there a unicode non-breaking-period, for example?

要看到问题的行动包装的电子邮件地址,运行
的Andr​​oid创建项目--target 16 --path演示--package com.example.demo --activity MainActivity
并修改 RES /布局/ main.xml中为文本的Hello World,MyActivity填充文字+电子邮件foo@foo.com 。产生于银河S3(API级别16)的输出:

To see the issue in action in wrapping an email address, run
android create project --target 16 --path demo --package com.example.demo --activity MainActivity
and change the text in res/layout/main.xml to "Hello World, MyActivity filler text + email foo@foo.com". That produces this output on a Galaxy S3 (API level 16):

(调整文本适合看包装上与其它屏幕尺寸的设备。值得注意的是,包裹在的IntelliJ的布局preVIEW做正确,这只是在设备上,这是错误的。)

(Adjust text as appropriate to see wrapping on devices with other screen sizes. Notably, the wrapping is done correctly in Intellij's layout preview, it's only on the device that it's faulty.)

推荐答案

TLDR;

@马特麦克明已经显示出了这个问题解决这里,去抓住它。我只是重新迭代的解决方案在这里。

@Matt McMinn has already shown a solution for this problem here, go grab it. I am only re-iterating that solution here.

需要注意的是,这个问题已经被固定在的Andr​​oid 4.2.2平台级。请参阅下面的屏幕截图为同一code的基础,但在Galaxy Nexus的不同平台版本的自动换行比较。

Note that, this issue has already been fixed at platform level in Android 4.2.2. See the below screenshots for word wrap comparison for the same code base but different platform versions on Galaxy Nexus.

因此​​,如果你不针对旧版本的Andr​​oid系统,你可能不希望使用此修复程序在所有。

Hence, if you are not targeting older versions of Android, you may not wish to use this fix at all.

MainActivity.java

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);
    }
}

activity_main.xml

<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>

NonBreakingPeriodTextView.java

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);
        }
    }
}

结果

在Android 4.1.2(Galaxy Nexus的)

在Android 2.3.3(AVD,Nexus One的克隆)

希望这有助于。

这篇关于从分裂停止文本多行的网页地址的时期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆