6

I have a TextView to be used as a bluetooth connection console. When I send a command, I want it to be written in a color (for example cyan), and the answers received in a different color (for example red).

Is it possible to do that, and if so, how?

I read it may be possible to do using HTML, but i'm not quite sure it is the best approach, or even how to do it.

Michal Kottman
  • 16,375
  • 3
  • 47
  • 62
Roman Rdgz
  • 12,836
  • 41
  • 131
  • 207
  • Look at http://stackoverflow.com/questions/22939862/textview-with-background-color-and-line-spacing/30096905#30096905 – qw1nz Sep 25 '15 at 13:38

5 Answers5

18

Here's a little helper function based on C0deAttack's answer, that simplifies things

public static void appendColoredText(TextView tv, String text, int color) {
    int start = tv.getText().length();
    tv.append(text);
    int end = tv.getText().length();

    Spannable spannableText = (Spannable) tv.getText();
    spannableText.setSpan(new ForegroundColorSpan(color), start, end, 0);
}

Just replace any calls to

textView.append("Text")

with

appendColoredText(textView, "Text", Color.RED);
benjymous
  • 2,102
  • 1
  • 14
  • 21
  • Could you please explain me why this solution no longer works if a prebuild ForegroundColorSpan object is passed instead of the color parameter? Thanks – MadBlack May 16 '13 at 16:14
8

Do you really need it to be a TextView or can you use a ListView instead and add a new row in the list for each command/answer?

If you really want to use a TextView you can do something like this (This is a working example you can just copy and paste to your app to try out):

package com.c0deattack;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.style.ForegroundColorSpan;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MultipleColoursInOneTextViewActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView tv = new TextView(this);

        String command = "This is a command";
        String response = "\nThis is a response";

        tv.append(command + response);
        Spannable spannableText = (Spannable) tv.getText();
        spannableText.setSpan(new ForegroundColorSpan(Color.GREEN), 0, command.length(), 0);
        spannableText.setSpan(new ForegroundColorSpan(Color.RED), command.length(), command.length() + response.length(), 0);

        LinearLayout layout = new LinearLayout(this);
        layout.addView(tv);
        setContentView(layout);
    }
}

So that shows that it can be done, but you'll obviously notice you'll have to set the line breaks yourself and workout where each command/answer starts and ends so you can apply the correct colour to it. It's not that hard but to me, feels clunky.

C0deAttack
  • 24,419
  • 18
  • 73
  • 81
  • I wanted to use a TextView because it looks like a console terminal. A ListView has horizontal lines between each 2 lines, so it wouldn't look like that. If you know how to avoid those lines, it could work for me. Please explain how if you know how to. – Roman Rdgz Nov 12 '11 at 16:17
0

It's easyer if you use:

textView.append(Html.fromHtml("<font color='#FFFFFF'</font>"));
larsaars
  • 2,065
  • 3
  • 21
  • 32
0
public static void appendColoredText(TextView tv, String text, int color) {
    SpannableStringBuilder ssb = new SpannableStringBuilder();
    ssb.append(text);
    ssb.setSpan(new ForegroundColorSpan(color), 0, text.length(), 0);
    tv.append(ssb);
}

optimizing @benjymous answer

we can create a SpannableStringBuilder object to hold the text and the color span, and use its append() and setSpan() methods to add the text and the color span.

This will be more efficient, as it avoids creating a new Spannable object every time the method is called.

Rinav
  • 2,527
  • 8
  • 33
  • 55
-3

check for every state textView.setTextColor(Color.RED);

mohammed momn
  • 3,230
  • 1
  • 20
  • 16