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:
- Android TextView no muestra Grabación de sonido Copyright símbolo "℗"
- Android: html en textview con el enlace clickable
- Android Fuente personalizada Spannable Tipo de letra
- Disposición de Android: Alinear un TextView y un Spinner
- Resaltar Textview con EditText
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
- Selecciona el texto de la vista de texto con un solo clic en android
- Conversión de TextView a String (tipo de) Android
- TextView de anchura fija con compuesto estirable
- Pruebas de Android. Café exprés. Cambiar texto en un TextView
- Cómo cambiar TextView texto en DataChange sin llamada atrás TextWatcher Listener
- Escala de texto en una vista para que se ajuste?
- Android BroadcastReceiver onReceive Actualizar TextView en MainActivity
- Android Html.fromHtml función automática convierte texto no deseado en hipervínculos
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
- ¿Cómo hacer que el agente api.ai aprenda algo dinámicamente?
- Cómo encontrar la ubicación del GPS en Android de forma periódica