Q:

Android Studio / ¿Como cambiar el color de selección de un texto clickeable con ClickableSpan?

ClickableSpan permite hacer clickeables distintas partes de un mismo texto, las cuales al ser clickeadas cambian su background al color que le especifiquemos con el siguiente código:
txt.setHighlightColor(Color.LTGRAY);

El problema es que el color de fondo (background) de la parte clickeable del texto no vuelve a su color original. Me explico: Se selecciona la palabra "Click" del texto "Haz Click aquí" y la palabra "Click" adquiere el fondo "LTGRAY" permanentemente. 
Me gustaría lograr un efecto de selección en donde al tocar "Click" se coloree el fondo con "LTGRAY" pero que al soltar el click, esta palabra vuelva a no tener fondo (o tener uno determinado).
Adjunto el código que hace clickeable mi texto
TextView txt = findViewById(R.id.txt);
SpannableString ss = null;
ClickableSpan metodo_clickable = new ClickableSpan() {
    @Override
    public void onClick(@NonNull View widget) {
    Toast.makeText(context, "Hiciste click", Toast.LENGTH_SHORT).show();}

ss.setSpan(metodo_clickable, 1, 9,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
txt.setText(ss);              
txt.setMovementMethod(LinkMovementMethod.getInstance());
txt.setHighlightColor(Color.LTGRAY);

Adjunto foto de como se ve el fondo del texto clickeado el cual permanece así hasta que se cierre la aplicación

Agradezco mucho su lectura

A:

Es muy fácil hacer lo que quieres. 
En Android, hay muchos tipos de Spans para darle estilo a los textos.
Pero vamos a enfocarnos en uno principal que resolverían tu problema:

BackgroundColorSpan: Cambia el color de fondo del texto al que se adjunta el span.

Una solución, es implementar View.OnTouchListener desde la clase control que creas para manejar tu ClickableSpan y jugar con los eventos MotionEvent.ACTION_DOWN el cual se activa al mantener presionada la vista y MotionEvent.ACTION_UP que se dispara al levantarla. Dichos eventos se disparan solo una vez por cada accion correspondiente.
En dichos eventos, debes setear el Span para que pueda crear el efecto que quieras.

OJO: cada vez que asignas un Span a un Spannable, estos permanecen. Si quieres deshacer un Span, debes eliminarlo
  manualmente según la clase que implementaste para el Span. Por
  ejemplo, tu Spannable puede tener muchos Spans diferentes a la vez;
  ForegroundColorSpan, BackgroundColorSpan, ClickableSpan, esto
  hace que no puedas implementar dos Spans de un mismo tipo a la vez,
  porque solo tomara como prioridad el primero que afecte una propiedad,
  es por ello que cada vez que quieras setear un mismo span dentro de un
  rango en el Spannable debes eliminarlo manualmente.

Tanto onClick como onTouch, son dos eventos que intercaran con tus acciones en la pantalla, pero onTouch es mas general porque es el padre que detona esos eventos. Estos no se implementan a la vez y es por eso que debes hacer unos ajustes en onTouch para poder disparar tu evento Click. Se retorna true para indicarle que dicho evento es quien tomo la acción y cuando haces el ACTION_UP disparas el evento click. Ten en cuenta que no estas tomando las demás acciones como ACTION_MOVE, es por ello que donde sea que levantes el dedo luego de hacerle el evento ACTION_DOWN a la vista, se disparara Click.
Te dejo un código rápido de ejemplo para lograr lo que quieres:
Clickable.java
public class Clickable extends ClickableSpan implements View.OnTouchListener{
        private TextView mTarget;
        private int mDefaultColor;
        private int mPressedColor;

        public void wrap(@NonNull TextView view){
            this.mTarget = view;
        }

        public void enableHighlightMode(@ColorInt int defaultColor, @ColorInt int pressedColor){
            this.mDefaultColor = defaultColor;
            this.mPressedColor = pressedColor;
            this.mTarget.setOnTouchListener(this);
            setDefaultTextColor();
        }

        private void setDefaultTextColor(){

            if(mTarget.getText() instanceof  Spannable) {
                Spannable editable = (Spannable) mTarget.getText();
                editable.setSpan(new BackgroundColorSpan(mDefaultColor), 0, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        private void setPressedTextColor(){
            if(mTarget.getText() instanceof  Spannable) {

                Spannable editable = (Spannable) mTarget.getText();
                BackgroundColorSpan[] spans = null;

                spans = editable.getSpans(0, editable.length(), BackgroundColorSpan.class);

                for (int i = 0; i < spans.length; i++)
                    editable.removeSpan(spans[i]);

                editable.setSpan(new BackgroundColorSpan(mPressedColor), 0, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        @Override
        public void onClick(@NonNull View widget) { /* No default implementation */ }

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    setPressedTextColor();
                    break;
                case MotionEvent.ACTION_UP:
                    setDefaultTextColor();
                    onClick(mTarget);
                    break;
            }

            return true;
        }
    }

Y para configurar tu ClickableSpan:
TextView textView = findViewById(R.id.textView);
SpannableString spannableString = new SpannableString("Hello World");
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance());

Clickable clickable = new Clickable() {
    @Override
    public void onClick(@NonNull View widget) {
        Toast.makeText(MainActivity.this, "Hiciste click", Toast.LENGTH_SHORT).show();
    }
};
clickable.wrap(textView);
clickable.enableHighlightMode(Color.TRANSPARENT, Color.BLUE);
spannableString.setSpan(clickable, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

Puedes modificar el código, hacer validaciones como quieras y jugar con los Spans. Happy coding. Saludos.
Edit: si quieres aplicar un Span a un texto en específico, debes indicarle las posiciones en el método setSpan. 
Una forma es, crear un método en tu control dónde le pases un String para pintarlo.
Ejemplo:
private int spanStart = -1;
private int spanEnd = -1;

public void applySpanOn(String text){
           if(mTarget == null || text == null) return;

           String spanned = mTarget.getText();
           spanStart = spanned.indexOf(text);

           // Return if not found
           if(spanStart == -1) return;

           spanEnd = spanStart + text.length();
}

Y en los métodos setPressedTextColor() y setDefaultTextColor():
Al código de editable.setSpan debes indicarle spanStart en vez de 0 y spanEnd en vez de editable.length(). Debes tener en cuenta que debes hacer las validaciones correspondientes con tu lógica.
Siguiendo el ejemplo, para aplicar el cambio debes hacer.
clickable.applySpanOn("world");
Nota: te invito a que busques y estudies la documentación de casa cosa que implementas en la internet. Normalmente es una guía de soluciones, no soluciones definitivas. Así podrás implementar códigos entendibles y salir a camino solo cuando no entiendes algo. Saludos.

