【问题标题】:Android - How to make all lines in an edittext underlined?Android - 如何使edittext中的所有行都加下划线?
【发布时间】:2012-05-08 20:35:58
【问题描述】:

从教程中我创建了布局:

  public static class LinedEditText extends EditText {
        private Rect mRect;
        private Paint mPaint;

        // we need this constructor for LayoutInflater
        public LinedEditText(Context context, AttributeSet attrs) {
            super(context, attrs);

            mRect = new Rect();
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(0x80000000);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            int count = getLineCount();
            Rect r = mRect;
            Paint paint = mPaint;

            for (int i = 0; i < count; i++) {
                int baseline = getLineBounds(i, r);
                canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
            }

            super.onDraw(canvas);
        }
    }

<view xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.bbbfr.mynotepad.NotepadText$LinedEditText"
    android:id="@+id/note"
    android:background="#ffd6e5"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp"
    android:scrollbars="vertical"
    android:fadingEdge="vertical"
    android:gravity="top"
    android:textSize="22sp"
    android:textColor="#000000"
    android:inputType="textMultiLine"
    android:capitalize="sentences"
/>

这只会使第一行加下划线。即使编辑文本中只有一行,是否可以将所有行都加下划线?

我尝试改变循环,例如for (int i = 0; i &lt; 5; i++) 但随后我收到此错误:

04-28 08:29:05.093: E/AndroidRuntime(14398): java.lang.IndexOutOfBoundsException: 2, 1 04-28 08:29:05.093: E/AndroidRuntime(14398):在 android.text.PackedIntVector.getValue(PackedIntVector.java:70) 04-28 08:29:05.093: E/AndroidRuntime(14398): 在 android.text.DynamicLayout.getLineTop(DynamicLayout.java:367) 04-28 08:29:05.093: E/AndroidRuntime(14398): 在 android.text.Layout.getLineBottom(Layout.java:831) 04-28 08:29:05.093: E/AndroidRuntime(14398):在 android.text.Layout.getLineBounds(Layout.java:437) 04-28 08:29:05.093: E/AndroidRuntime(14398):在 android.widget.TextView.getLineBounds(TextView.java:4122) 04-28 08:29:05.093: E/AndroidRuntime(14398): 在 com.bbbfr.mynotepad.NotepadText$LinedEditText.onDraw(NotepadText.java:56)

到这一行:int baseline = getLineBounds(i, r);

我还在视图中设置了android:lines="5"

【问题讨论】:

    标签: java android android-edittext


    【解决方案1】:

    从您的代码中可以看出,您正在为 for 循环中的 0 to count 中的行绘制 underlineedit text,并且 count 设置为 int count = getLineCount();。所以只会增加 EditText 中现有的行数!通过更改计数的数量,您可以绘制任意数量的下划线!

    【讨论】:

    • 我也想过这个!但是当我将其更改为例如5 我收到一个错误,请参阅更新后的帖子
    • 那是因为您的文本可能没有 5 行。你需要设置 android:lines="5" 在你的编辑文本中有 5 行你可以画下划线。
    • 我做到了。我确保我有 lines="5" 和 5 在循环中。
    • r in getlinebounds 返回 0,因为该行中没有文本,因此没有边界。您应该尝试将其定义为您的编辑文本的范围。
    【解决方案2】:

    如果您不介意与EditText 中的文本颜色相同的下划线,您应该只使用内置的UnderlineSpan,可以自己创建,也可以通过@987654325 间接创建@.

    private void createUnderlinedText() {
        String text = "I am underlined text\nLine #2\nLine #3\nLine #4\nLine #5";
    
        EditText underlineSpanEditText = (EditText) findViewById(R.id.underlinespan_edittext);
        SpannableStringBuilder sb = new SpannableStringBuilder(text);
        sb.setSpan(new UnderlineSpan(), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        underlineSpanEditText.setText(sb);
    
        EditText htmlUnderlineEditText = (EditText) findViewById(R.id.html_underline_edittext);
        String html = "<u>I am underlined text</br>Line #2</br>Line #3</br>Line #4</br>Line #5</u>";
        htmlUnderlineEditText.setText(Html.fromHtml(html));
    }
    

    与您当前方法的主要区别在于,这只会在实际文本下划线,而不是整个文本行。例如,如果你运行我的代码sn -p,你会发现下划线在被\n&lt;br/&gt; 打断时并没有延伸到行尾。但是,根据您之后的行为,这可能不是您想要的。


    编辑:所以如果我理解正确的话,你基本上想在EditText 中继续画水平线,不管有没有文字?您问题中的“下划线”部分有点误导,因为事实证明,这与它几乎没有关系(在这个词的传统含义中:))。

    无论如何,您不能使用getLineCount(),因为它总是会返回包含实际文本的行数。这意味着您必须用换行符“填充”任何剩余空间才能获得所需的效果,这听起来有点恶心......更好的选择可能是将水平线的绘制基于@的总高度987654331@。一个简单的示例,您显然可以根据自己的喜好对其进行调整:

    public class LinedEditText extends EditText {
        private Paint mPaint = new Paint();
    
        public LinedEditText(Context context) {
            super(context);
            initPaint();
        }
    
        public LinedEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            initPaint();
        }
    
        public LinedEditText(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initPaint();
        }
    
        private void initPaint() {
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(0x80000000);
        }
    
        @Override protected void onDraw(Canvas canvas) {
            int left = getLeft();
            int right = getRight();
            int paddingTop = getPaddingTop();
            int paddingBottom = getPaddingBottom();
            int paddingLeft = getPaddingLeft();
            int paddingRight = getPaddingRight();
            int height = getHeight();
            int lineHeight = getLineHeight();
            int count = (height-paddingTop-paddingBottom) / lineHeight;
    
            for (int i = 0; i < count; i++) {
                int baseline = lineHeight * (i+1) + paddingTop;
                canvas.drawLine(left+paddingLeft, baseline, right-paddingRight, baseline, mPaint);
            }
    
            super.onDraw(canvas);
        }
    }
    

    结果如下:

    【讨论】:

    • @erdomester:对不起,我被你问题中的“下划线”部分弄错了。请查看我的答案中的编辑,希望它能解决您正在解决的更多问题。
    • 这是一个很棒的方法!类定义必须是静态的,否则我会收到 setContentView(R.layout.notepadtext); 错误line.T 非常感谢!
    • 甜蜜如。 :) 您必须将类声明为静态,因为您可能将其实现为嵌套类,请参见给出的 xml:com.bbbfr.mynotepad.NotepadText$LinedEditText。如果您将其重构为一个单独的文件,您可以删除 static 并直接引用它 - 不过实际上并没有任何区别。
    【解决方案3】:

    最简单的解决方法是您可以在构造函数中仅使用行分隔符调用 setText,例如"\n\n\n" (你可以根据你需要的行数动态构建它),那么你当前的 LinedEditText 就会有你想要的下划线。

    【讨论】:

      猜你喜欢
      • 2013-03-31
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2011-07-27
      相关资源
      最近更新 更多