Вопрос по java, android – Android - Как сделать все строки в тексте редактирования подчеркнутыми?

3

Из учебника я создал макет:

  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 < 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): at android.text.PackedIntVector.getValue(PackedIntVector.java:70) 04-28 08:29:05.093: E/AndroidRuntime(14398): at android.text.DynamicLayout.getLineTop(DynamicLayout.java:367) 04-28 08:29:05.093: E/AndroidRuntime(14398): at android.text.Layout.getLineBottom(Layout.java:831) 04-28 08:29:05.093: E/AndroidRuntime(14398): at android.text.Layout.getLineBounds(Layout.java:437) 04-28 08:29:05.093: E/AndroidRuntime(14398): at android.widget.TextView.getLineBounds(TextView.java:4122) 04-28 08:29:05.093: E/AndroidRuntime(14398): at com.bbbfr.mynotepad.NotepadText$LinedEditText.onDraw(NotepadText.java:56)

к этой строке:int baseline = getLineBounds(i, r);

Я также установилandroid:lines="5" в представлении.

Ваш Ответ

3   ответа
0

что вы можете вызвать setText только с разделителями строк в конструкторе, например & Quot; \ N \ N \ N & Quot; (Вы можете динамически построить его, основываясь на том, сколько строк вам нужно), тогда ваш текущий LinedEditText будет иметь подчеркивания, как вы хотите.

0

Как видно из вашего кода, вы рисуетеunderline дляedit text для строк из0 to count в вашем для цикла иcount установлен вint count = getLineCount();, Таким образом, только существующее количество строк в EditText будет увеличено! Изменяя количество, вы можете нарисовать столько подчеркиваний, сколько захотите!

Я тоже думал об этом! Но когда я изменяю это, например, 5 Я получаю сообщение об ошибке, смотрите обновленный пост erdomester
r в getlinebounds возвращает 0, так как в этой строке нет текста и, следовательно, нет границ. Вы должны попытаться определить его в пределах вашего текста редактирования.
Я это сделал. Я убедился, что у меня есть строки = & quot; 5 & quot; а также 5 в цикле. erdomester
это потому, что, возможно, ваш текст не имеет 5 строк. вам нужно установить android: lines = & quot; 5 & quot; чтобы иметь 5 строк в вашем тексте редактирования, на которых вы можете рисовать подчеркивания.
10

If you don't mind the underline having the same colour as the text in the EditText, you should really just use the built-in UnderlineSpanлибо создавая его самостоятельно, либо косвенно черезHtml.fromHtml(...).

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

The main difference with your current approach is that this will only underline the actual text, and not the whole text line. For example, if you run my code snippet, you will find that the underline does not extend to the end of the line when it's broken off by the \n or <br/>. However, depending on the behaviour your after, this may not be what you're looking for.


Edit: Так что, если я вас правильно понимаю, вы в основном хотите продолжать рисовать горизонтальные линии в своемEditTextНеважно, есть ли текст или нет? «Подчеркивание» участие в вашем вопросе было своего рода вводящим в заблуждение, поскольку, как выясняется, это не имеет к этому никакого отношения (в традиционном значении этого слова :)).

В любом случае, вы не можете использоватьgetLineCount() так как это всегда будет возвращать количество строк, которые содержат фактический текст. Это означало бы, что вам придется «заполнить»; любое оставшееся пространство с символами новой строки, чтобы получить желаемый эффект, который звучит как-то противно ... Лучшей альтернативой, вероятно, является основание рисования горизонтальных линий на общей высотеEditText, Быстрый пример, который вы, очевидно, можете настроить по своему вкусу:

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

Результат выглядит так:

LinedEditText

Это отличный подход! Определение класса должно быть статическим, иначе я получаю сообщение об ошибке setContentView (R.layout.notepadtext); line.T большое спасибо! erdomester
@erdomester: извините, я получил неправильное указание на 'подчеркивание' часть в вашем вопросе. Пожалуйста, посмотрите на изменение в моем ответе, которое, мы надеемся, решит больше проблем, с которыми вы сталкиваетесь.
Сладкий как. :) Вы должны были объявить класс статическим, потому что вы, вероятно, реализуете его как вложенный класс, как показано в приведенном xml:com.bbbfr.mynotepad.NotepadText$LinedEditText, Если бы вы реорганизовали его в отдельный файл, вы можете удалитьstatic и ссылаться на него напрямую - хотя на самом деле никакой разницы нет.

Похожие вопросы