Nuevo Texto Seleccionable en el componente android 3 (API <= 11)

Después de una búsqueda larga y demorada, no puedo encontrar un componente que pueda seleccionar texto en textview para nivel de API de android <= 11. He escrito este componente que puede ser de ayuda para usted:

public class SelectableTextView extends TextView { public static int _SelectedBackgroundColor = 0xffA6D4E1; public static int _SelectedTextColor = 0xff000000; private OnTouchListener lastOnTouch; protected int textOffsetStart; protected int textOffsetEnd; private OnLongClickListener lastOnLongClick; protected boolean longCliked; protected boolean isDowned; protected int textSelectedEnd; protected int textSelectedStart; private static SelectableTextView lastInstance; public SelectableTextView(Context context) { super(context); } public void setTextIsSelectable(boolean selectable) { // TODO:ANDROID3 // if:androidversion>=3 // super.setTextIsSelectable(selectable); // else super.setLongClickable(true); super.setOnLongClickListener(getSelectableLongClick()); super.setOnTouchListener(getSelectableOnTouch()); } private OnLongClickListener getSelectableLongClick() { return new OnLongClickListener() { @Override public boolean onLongClick(View v) { longCliked = true; if (lastOnLongClick != null) { lastOnLongClick.onLongClick(v); } return true; } }; } @Override public void setOnTouchListener(OnTouchListener l) { super.setOnTouchListener(l); this.lastOnTouch = l; } @Override public void setOnLongClickListener(OnLongClickListener l) { super.setOnLongClickListener(l); this.lastOnLongClick = l; } private OnTouchListener getSelectableOnTouch() { return new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { if (lastInstance == null) lastInstance = SelectableTextView.this; if (lastInstance != null && lastInstance != SelectableTextView.this) { lastInstance.clean(); lastInstance = SelectableTextView.this; } int offset = getOffset(event); if ((offset < textOffsetEnd && offset > textOffsetStart) || (offset > textOffsetEnd && offset < textOffsetStart)) { if (textOffsetEnd - offset > offset - textOffsetStart) textOffsetStart = textOffsetEnd; } else { clean(); textOffsetStart = offset; } isDowned = true; } else if (isDowned && longCliked && action == MotionEvent.ACTION_MOVE) { selectTextOnMove(event); } else if (action == MotionEvent.ACTION_UP) { isDowned = false; longCliked = false; } if (lastOnTouch != null) lastOnTouch.onTouch(v, event); return false; } }; } private void selectTextOnMove(MotionEvent event) { int offset = getOffset(event); if (offset != Integer.MIN_VALUE) { String text = getText().toString(); SpannableStringBuilder sb = new SpannableStringBuilder(text); BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor); ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor); int start = textOffsetStart; textOffsetEnd = offset; int end = offset; if (start > end) { int temp = start; start = end; end = temp; } int[] curectStartEnd = curectStartEnd(text, start, end); start = curectStartEnd[0]; end = curectStartEnd[1]; SelectableTextView.this.textSelectedStart = start; SelectableTextView.this.textSelectedEnd = end; sb.setSpan(bgc, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE); setText(sb); } } private int[] curectStartEnd(String text, int start, int end) { int length = text.length(); while (start < length && start > 0 && text.charAt(start) != ' ') { start--; } while (end < length && text.charAt(end) != ' ') { end++; } return new int[] { start, end }; } private int getOffset(MotionEvent event) { Layout layout = getLayout(); if (layout == null) return Integer.MIN_VALUE; float x = event.getX() + getScrollX(); float y = event.getY() + getScrollY(); int line = layout.getLineForVertical((int) y); int offset = layout.getOffsetForHorizontal(line, x); return offset; } protected void clean() { if (this.getText() != null) { this.setText(this.getText().toString()); textSelectedStart = 0; textSelectedEnd = 0; } } @Override public int getSelectionStart() { return textSelectedStart; } @Override public int getSelectionEnd() { return textSelectedEnd; } } 

getOffset obtiene el desplazamiento seleccionado del texto que el usuario Tocado para usar este componente establece estos atributos:

  SelectableTextView textView1 = new SelectableTextView(context); textView1.setClickable(false); textView1.setCursorVisible(false); textView1.setOnTouchListener(getOnTextTouch());//new after text select touch textView1.setEnabled(this.selectable); textView1.setTextIsSelectable(this.selectable); 

¿Puede alguien actualizar este componente?

Este es el código en git hub

También agregue los dos constructores siguientes debido a esto

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

También he añadido lo siguiente al código:

  @SuppressLint("NewApi") public void setTextIsSelectable(boolean selectable) { if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) super.setTextIsSelectable(true); else { super.setLongClickable(true); super.setOnLongClickListener(getSelectableLongClick()); super.setOnTouchListener(getSelectableOnTouch()); } } 

Lo usé así, sin un OnTouchListener:

 txt_copyFrom.setClickable(false); txt_copyFrom.setCursorVisible(false); txt_copyFrom.setEnabled(true); txt_copyFrom.setTextIsSelectable(true); txt_copyFrom.setOnLongClickListener(new OnLongClickListener(){ @Override public boolean onLongClick(View v) { int start=txt_copyFrom.getSelectionStart(); int end=txt_copyFrom.getSelectionEnd(); mSelectedText=txt_copyFrom.getText().toString().substring(start, end); Log.d(TAG, "Selected text: "+mSelectedText); return true; } }); 

Con el XML:

 <com.example.clipboardtest.SelectableTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Old Buccaneer1The Old Sea-dog at the Admiral BenbowSquire Trelawney, Dr. Livesey, and the rest of these gentlemen having asked me to write down the whole particulars about Treasure Island, from the beginning to the end, keeping nothing back but the bearings of the island, and that only because there is still treasure not yet lifted, I take up my pen in the year of grace 17--and go back to the time when my father kept the Admiral Benbow inn and the brown old seaman with the sabre cut first took up his lodging under our roof." android:id="@+id/txt_copyfrom" /> 

Supongo que tengo que establecer un OnTouchListener dentro de OnLongClickListener para el TextView en la actividad en sí.

Probado poner Logs todo el lugar en SelectableTextView, no parece estar trabajando … Me parece que el LongClickListener se llama, pero el TouchListener ni siquiera se llama …

Establecer OnTouchListener dentro de OnLongClickListener hizo esto

  • Mostrar todos los caracteres Unicode en TextView
  • Actividad requiere FLAG_ACTIVITY_NEW_TASK Indicador
  • Cómo obtener el texto ellipsizado en un TextView
  • Android: No se puede utilizar android.R.drawable como imagen de fondo para textview
  • Measure () no funciona correctamente con diseños dinámicos y textView - Android
  • Android (cambio de cadena en código java)
  • Cómo influenciar linebreak en Android Textview
  • Android- Ajusta el ancho de un TextView a la izquierda de cualquier botón-1 o botón-2
  • ¿Cómo modificar la propiedad MaxLines de TextView con animación?
  • Verticalmente Centro TextView en RelativeLayout
  • ListView con TextView autoLink no recibe OnItemClickListener
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.