Изменить цвет раздела текста в TextView в зависимости от его состояния - PullRequest
0 голосов
/ 26 января 2012

У меня есть куча текста, который может быть слишком длинным, чтобы уместиться на экране пользователя.Таким образом, вместо того, чтобы тратить место, я хочу показать только короткий отрывок и позволить пользователю расширить его.Дизайн этой функции требует короткого фрагмента цветного текста в конце этого фрагмента («Показать больше ...»).

Мне интересно, как я могу:

  • Цвет этого бита текста отличается от цвета остального текста.
  • Измените цвет этого бита в зависимости от состояния TextTiew.Синий, если пользователь не взаимодействует с ним, и красный, когда пользователь нажимает на него.

Возможно ли это и как мне это сделать?

Примечание: я будув некотором смысле подключите все TextView как кнопку.

Ответы [ 3 ]

2 голосов
/ 26 января 2012

Вы можете расширить TextView с помощью переопределенного поведения с многоточием, как я сделал (на основе кода из этого вопроса: многострочный текстовый просмотр для Android с многоточием )

import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.text.StaticLayout;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class EllipsizingTextView extends TextView {
    private static final char ELLIPSIS = '…';

    public interface EllipsizeListener {
        void ellipsizeStateChanged(boolean ellipsized);
    }

    private final List<EllipsizeListener> ellipsizeListeners = new ArrayList<EllipsizeListener>();
    private volatile boolean isEllipsized;
    private volatile boolean isStale;
    private volatile boolean programmaticChange;
    private CharSequence fullCharSequence;
    private int maxLines = -1;
    private float lineSpacingMultiplier = 1.0f;
    private float lineAdditionalVerticalPadding = 0.0f;

    public EllipsizingTextView(Context context) {
        super(context);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttributes(context, attrs);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initAttributes(context, attrs);
    }

    private void initAttributes(Context context, AttributeSet attrs) {
        maxLines = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "maxLines", -1);
        if (maxLines != -1) {
            isStale = true;
        }
    }

    public void addEllipsizeListener(EllipsizeListener listener) {
        if (listener == null) {
            throw new NullPointerException();
        }
        ellipsizeListeners.add(listener);
    }

    public void removeEllipsizeListener(EllipsizeListener listener) {
        ellipsizeListeners.remove(listener);
    }

    public boolean isEllipsized() {
        return isEllipsized;
    }

    public void setMaxLines(int maxLines) {
        if (getMaxLines() != maxLines) {
            super.setMaxLines(maxLines);
            this.maxLines = maxLines;
            isStale = true;
        }
    }

    public int getMaxLines() {
        return maxLines;
    }

    public void setLineSpacing(float add, float mult) {
        this.lineAdditionalVerticalPadding = add;
        this.lineSpacingMultiplier = mult;
        super.setLineSpacing(add, mult);
    }

    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);
        if (!programmaticChange) {
            fullCharSequence = text;
            isStale = true;
        }
    }

    protected void onDraw(Canvas canvas) {
        if (isStale) {
            super.setEllipsize(null);
            resetText();
        }
        super.onDraw(canvas);
    }

    private void resetText() {
        int maxLines = getMaxLines();
        boolean ellipsized = false;
        SpannableStringBuilder builder = SpannableStringBuilder.valueOf(fullCharSequence);

        if (maxLines != -1) {
            Layout layout = createWorkingLayout(builder);
            if (layout.getLineCount() > maxLines) {
                int end = layout.getLineEnd(maxLines - 1);
                int nextSpace = builder.toString().indexOf(' ', end);
                if (nextSpace != -1) {
                    builder.delete(end, builder.length());
                }
                builder.append(ELLIPSIS);
                while (createWorkingLayout(builder).getLineCount() > maxLines) {
                    int pos = builder.toString().lastIndexOf(' ');
                    builder.delete(pos, builder.length());
                    builder.append(ELLIPSIS);
                }
                ellipsized = true;
            }
        }

        if (!TextUtils.equals(builder, getText())) {
            programmaticChange = true;
            try {
                setText(builder);
            } finally {
                programmaticChange = false;
            }
        }
        isStale = false;
        if (ellipsized != isEllipsized) {
            isEllipsized = ellipsized;
            for (EllipsizeListener listener : ellipsizeListeners) {
                listener.ellipsizeStateChanged(ellipsized);
            }
        }
    }

    private Layout createWorkingLayout(CharSequence workingText) {
        return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),
                Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false);
    }

    public void setEllipsize(TruncateAt where) {
        // Ellipsize settings are not respected
    }

    public int getLineCount() {
        return Math.min(super.getLineCount(), getMaxLines());
    }

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (changed) {
            isStale = true;
        }
        super.onLayout(changed, left, top, right, bottom);
    }
}

Вы можете заменить ELLIPSIS своимстроку (например, «Показать больше») и добавьте ForegroundColorSpan или BackgroundColorSpan для этой части текста.Будьте осторожны с пробелами в этом случае (это может привести вас к бесконечному циклу).

2 голосов
/ 26 января 2012

Вы ищете SpannableString

специально ForegroundColorSpan

0 голосов
/ 26 января 2012

разноцветный текст в одном текстовом представлении может быть получен с помощью метода HTML.и обратная связь с пользователем для состояния касания может быть достигнута настройкой onTouchListener для просмотра текста.но в onTouchListener вам понадобится код, который меняет цвет текста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...