Change Clickable Textview's Color on Focus and Click

Change clickable TextView's color on focus and click?

If you want to set stateful color from code, you need to pass in ColorStateList as an argument to setTextColor passing an int to the method results in setting the color to all the states. It also looks like your xml is not totally correct. Example from ColorStateList docs looks like(should be located like this: res/color/selector_txt.xml):

 <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:color="@color/testcolor1"/>
<item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" />
<item android:state_enabled="false" android:color="@color/testcolor3" />
<item android:color="@color/testcolor5"/>
</selector>

UPD on how to set a ColorStateList to text color:

ColorStateList cl = null;
try {
XmlResourceParser xpp = getResources().getXml(R.color.selector_txt);
cl = ColorStateList.createFromXml(getResources(), xpp);
} catch (Exception e) {}

Note: The method createFromXml(Resources, XmlPullParser parser) was deprecated in API level 23.
Use createFromXml(Resources, XmlPullParser parser, Theme)

With XML its as easy as:

android:textColor="@color/selector_txt"

How to change the TextView Color on click of a layout in android?

You should add this definitely working.I am also check it out...

flightRelative.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
TextView flight = (TextView)findViewById(R.id.flight_content);
flight.setTextColor(Color.parseColor("#FFFFFF"));

}
});

Changing background color of a TextView when clicked

I think this part of the code creates this effect:

https://github.com/nickbutcher/plaid/blob/61d59644d5ae9e373f93cef10e0438c50e2eea6d/app/src/main/java/io/plaidapp/util/LinkTouchMovementMethod.java

It's actually based on this question:

Change the text color of a single ClickableSpan when pressed without affecting other ClickableSpans in the same TextView

public class LinkTouchMovementMethod extends LinkMovementMethod {

private static LinkTouchMovementMethod instance;
private TouchableUrlSpan pressedSpan;

public static MovementMethod getInstance() {
if (instance == null)
instance = new LinkTouchMovementMethod();

return instance;
}

@Override
public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
boolean handled = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressedSpan = getPressedSpan(textView, spannable, event);
if (pressedSpan != null) {
pressedSpan.setPressed(true);
Selection.setSelection(spannable, spannable.getSpanStart(pressedSpan),
spannable.getSpanEnd(pressedSpan));
handled = true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
TouchableUrlSpan touchedSpan = getPressedSpan(textView, spannable, event);
if (pressedSpan != null && touchedSpan != pressedSpan) {
pressedSpan.setPressed(false);
pressedSpan = null;
Selection.removeSelection(spannable);
}
} else {
if (pressedSpan != null) {
pressedSpan.setPressed(false);
super.onTouchEvent(textView, spannable, event);
handled = true;
}
pressedSpan = null;
Selection.removeSelection(spannable);
}
return handled;
}

private TouchableUrlSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent
event) {

int x = (int) event.getX();
int y = (int) event.getY();

x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();

x += textView.getScrollX();
y += textView.getScrollY();

Layout layout = textView.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);

TouchableUrlSpan[] link = spannable.getSpans(off, off, TouchableUrlSpan.class);
TouchableUrlSpan touchedSpan = null;
if (link.length > 0) {
touchedSpan = link[0];
}
return touchedSpan;
}

}

Change the text color of a single ClickableSpan when pressed without affecting other ClickableSpans in the same TextView

I finally found a solution that does everything I wanted. It is based on this answer.

This is my modified LinkMovementMethod that marks a span as pressed on the start of a touch event (MotionEvent.ACTION_DOWN) and unmarks it when the touch ends or when the touch location moves out of the span.

public class LinkTouchMovementMethod extends LinkMovementMethod {
private TouchableSpan mPressedSpan;

@Override
public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mPressedSpan = getPressedSpan(textView, spannable, event);
if (mPressedSpan != null) {
mPressedSpan.setPressed(true);
Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan),
spannable.getSpanEnd(mPressedSpan));
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event);
if (mPressedSpan != null && touchedSpan != mPressedSpan) {
mPressedSpan.setPressed(false);
mPressedSpan = null;
Selection.removeSelection(spannable);
}
} else {
if (mPressedSpan != null) {
mPressedSpan.setPressed(false);
super.onTouchEvent(textView, spannable, event);
}
mPressedSpan = null;
Selection.removeSelection(spannable);
}
return true;
}

private TouchableSpan getPressedSpan(
TextView textView,
Spannable spannable,
MotionEvent event) {

int x = (int) event.getX() - textView.getTotalPaddingLeft() + textView.getScrollX();
int y = (int) event.getY() - textView.getTotalPaddingTop() + textView.getScrollY();

Layout layout = textView.getLayout();
int position = layout.getOffsetForHorizontal(layout.getLineForVertical(y), x);

TouchableSpan[] link = spannable.getSpans(position, position, TouchableSpan.class);
TouchableSpan touchedSpan = null;
if (link.length > 0 && positionWithinTag(position, spannable, link[0])) {
touchedSpan = link[0];
}

return touchedSpan;
}

private boolean positionWithinTag(int position, Spannable spannable, Object tag) {
return position >= spannable.getSpanStart(tag) && position <= spannable.getSpanEnd(tag);
}
}

This needs to be applied to the TextView like so:

    yourTextView.setMovementMethod(new LinkTouchMovementMethod());

And this is the modified ClickableSpan that edits the draw state based on the pressed state set by the LinkTouchMovementMethod: (it also removes the underline from the links)

public abstract class TouchableSpan extends ClickableSpan {
private boolean mIsPressed;
private int mPressedBackgroundColor;
private int mNormalTextColor;
private int mPressedTextColor;

public TouchableSpan(int normalTextColor, int pressedTextColor, int pressedBackgroundColor) {
mNormalTextColor = normalTextColor;
mPressedTextColor = pressedTextColor;
mPressedBackgroundColor = pressedBackgroundColor;
}

public void setPressed(boolean isSelected) {
mIsPressed = isSelected;
}

@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
ds.bgColor = mIsPressed ? mPressedBackgroundColor : 0xffeeeeee;
ds.setUnderlineText(false);
}
}

Set textview focus color programmatically / change focus color in themes

You can use ColorStateList, to specify the state color programmatically.

    int[][] states = new int[][] {
new int[] { android.R.attr.state_pressed}, // pressed
new int[] { android.R.attr.state_focused}, // focused
new int[] { android.R.attr.state_enabled} // enabled
};

int[] colors = new int[] {
Color.parseColor("#008000"), // green
Color.parseColor("#0000FF"), // blue
Color.parseColor("#FF0000") // red
};

ColorStateList list = new ColorStateList(states, colors);
textView.setTextColor(list);
textView.setClickable(true);
textView.setFocusableInTouchMode(true);

I want to change the color text using styles,

You can make use of Enum class to easily define the colors wanted, and this way, you'll be able to increase the amount of supported colors without too much changes in your code.

Enum class

public enum ColorFactory {

BLACK(R.id.textView1, R.color.black),
WHITE(R.id.textView2, R.color.white),
BLUE(R.id.textView2, R.color.blue),
RED(R.id.textView2, R.color.red),
CYAN(R.id.textView2, R.color.cyan),
GREEN(R.id.textView2, R.color.green),
GREY(R.id.textView2, R.color.grey),
YELLOW(R.id.textView2, R.color.yellow),
PINK(R.id.textView2, R.color.pink),
PURPLE(R.id.textView2, R.color.purple),
BROWN(R.id.textView2, R.color.brown),
CUSTOM(R.id.textView2, R.color.custom);

int id;
int color;

ColorFactory(int id, int color) {
this.id = id;
this.color = color;
}

public int getId() {
return id;
}

public int getColor() {
return color;
}

public static int getColorById(int id) {
for (ColorFactory currentEnumElement : values()) {
if (currentEnumElement.getId() == id) {
return currentEnumElement.getColor();
}
}
return -1;
}
}

And you'll have to have those colors defined in your colors.xml file as following

Colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<color name="blue">#0000ff</color>
<color name="red">#ff0000</color>
<color name="cyan">#00f2ff</color>
<color name="green">#00ff00</color>
<color name="grey">#8b8378</color>
<color name="yellow">#ffd700</color>
<color name="pink">#e8a4a3</color>
<color name="purple">#b72bef</color>
<color name="brown">#a7823e</color>
<color name="custom">#990000</color>
</resources>

And to the final, the code to use it...(simplified)

Code

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

TextView textView1;
TextView textView2;
.
.
.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

textView1 = (TextView) findViewById(R.id.textView1);
textView2 = . . . .
.
.
.
.

}

@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.textView1:
textView1.setTextColor(ColorFactory.getColorById(view.getId()));
break;
case R.id.textView2:
.
.
.
}
}
}

It should allow you to set the colors as a result of a click.
NOTE: you can also use ButterKnife to bind the views to improve the readability of your code and so on..
Hope it helps.

Changing TextView background color on click android

If the textview is clicked the background changes to yellow and remains yellow until it is click again. Then it returns to its default background.

It's a matter of logic as you need to keep in your click listener the current click state.(blind coding):

textView.setOnClickClickListener(new View.OnClickListener() {
private boolean stateChanged;
public void onClick(View view) {
if(stateChanged) {
// reset background to default;
textView.setBackgroundDrawable(circleOffDrawable);
} else {
textView.setBackgroundDrawable(circleOnDrawable);
}
stateChanged = !stateChanged;
}
});

To improve the answer, you should keep stateChanged flag in the activity and retain its value across activity recreations - if the user rotates the activity. (Store the flag in onSaveInstanceState and restore in onCreate if its parameter is not null.)



Related Topics



Leave a reply



Submit