2012-07-13 10 views
7

Quiero permitir que el usuario edite solo una parte de una línea de texto en mi aplicación de Android. Veo una clase llamada EasyEditSpan pero cuando la meto en un TextView no sucede nada. Traté de editar TextView, pero aún no tiene ningún efecto. Si cambia a EditText, toda la línea de texto se puede editar, lo que también es incorrecto. Aquí está mi código:¿Cómo se usa EasyEditSpan en Android para permitir la edición parcial de texto?

@Override 
public void onCreate(Bundle savedInstanceState) { 
    TextView testView = (TextView)findViewById(R.id.text_view); 
    testView.setText(buildMiddleEditSpannable("Please enter your ", "Name", " here.")); 
} 

public static Spannable buildMiddleEditSpannable(CharSequence beginning, CharSequence middle, CharSequence end) { 
    int spanMidStart = beginning.length(); 
    int spanMidEnd = spanMidStart + middle.length(); 

    SpannableString span = new SpannableString(new StringBuilder(middle).insert(0, beginning).append(end)); 
    span.setSpan(new EasyEditSpan(), spanMidStart, spanMidEnd, 0); 
    return span; 
} 
+0

¿Cuál es la versión para Android de su aplicación de destino para ejecutar? Tenga en cuenta que [EasyEditSpan] (http://developer.android.com/reference/android/text/style/EasyEditSpan.html) es realmente nuevo desde API Nivel 14. Puede romperse en el viejo sistema de Android, aunque debería obtener alguna excepción de error en Logcat. – yorkw

+0

Estoy corriendo y probando en Ice Cream Sandwich o superior solamente. – satur9nine

Respuesta

5

Después de mirar el código de la arquitectura en referencia a EasyEditSpan (EasyEditSpan, TextView y TextUtils), que llega a ser evidente que a pesar de que dice en su descripción:

proporciona un fácil forma de editar una porción de texto.

La funcionalidad disponible actualmente se limita sólo a la segunda parte de la descripción de la siguiente manera:

La TextView utiliza este lapso para permitir al usuario borrar un mandril de texto en un solo clic. el texto. TextView elimina este lapso apenas se edita el texto o se mueve el cursor.

He aquí algunos ejemplos de código rápida que demuestra su uso:

public class EasyEditSpanActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     final EditText editText = new EditText(this); 
     setContentView(editText); 

     showToast("Longclick to set EasyEditSpan for the line on cursor"); 

     editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); 
     editText.setSingleLine(false); 
     editText.setText("####\n#######\n###\n######\n####".replace("#", "text ")); 
     editText.setOnLongClickListener(new OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View v) { 
       final Layout layout = editText.getLayout(); 
       final int line = layout.getLineForOffset(editText.getSelectionStart()); 
       final int start = layout.getLineStart(line); 
       final int end = layout.getLineEnd(line); 
       editText.getEditableText().setSpan(new EasyEditSpan(), start, end, 
         Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
       showToast("Edit line to show EasyEdit window"); 
       return true; 
      } 
     }); 
    } 

    private void showToast(String message) { 
     Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); 
    } 

} 

Así que, lamentablemente, si usted necesita una manera de permitir al usuario editar sólo una parte de una línea de texto en su aplicación, EasyEditSpan no lo hace parece ayudar mucho. Es probable que necesite implementar algún código utilizando ClickableSpan y probablemente un cuadro de diálogo personalizado.

+0

Al mirar el código en TextView, no pude ver cómo EasyEditSpan hizo algo fácil de editar. Incluso el Javadoc dice que solo permite la eliminación de texto. – sww314

3

Puede ser mejor que use ClickableSpan y aparezca un cuadro de diálogo para editar el contenido. Sin embargo, traté de implementar una vista de texto parcialmente editable. Esto no es completo y puede tener algunos bordes ásperos. Utiliza tres intervalos y sustituciones en los métodos SelectChanged (int selStart, int selEnd) y onKeyDown (int keyCode, KeyEvent event) para deshabilitar las modificaciones mientras el destino sea part1 o part3. Espero eso ayude.

//activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <com.sensei.partialedit.EditTextSelectable 
     android:id="@+id/text_view" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="@dimen/padding_medium" 
     android:text="@string/hello_world" 
     android:background="#00000000" 
     tools:context=".MainActivity" /> 
</RelativeLayout> 

//MainActivity.java

package com.sensei.partialedit; 

import android.app.Activity; 
import android.os.Bundle; 

public class MainActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     EditTextSelectable testView = (EditTextSelectable) findViewById(R.id.text_view); 
     testView.setText("Please enter your ", " Name ", " here."); 
    } 
} 

//EditTextSelectable.java

package com.sensei.partialedit; 

import android.content.Context; 
import android.graphics.Color; 
import android.text.Spannable; 
import android.text.SpannableStringBuilder; 
import android.text.method.KeyListener; 
import android.text.style.CharacterStyle; 
import android.text.style.ForegroundColorSpan; 
import android.text.style.UnderlineSpan; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.widget.EditText; 

public class EditTextSelectable extends EditText { 

    private String part1; 
    private String part2; 
    private String part3; 
    private ForegroundColorSpan span1; 
    private CharacterStyle span2; 
    private ForegroundColorSpan span3; 

    public EditTextSelectable(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     setTag(getKeyListener()); 
    } 

    public EditTextSelectable(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setTag(getKeyListener()); 
    } 

    public EditTextSelectable(Context context) { 
     super(context); 
     setTag(getKeyListener()); 
    } 

    public void setText(String part1, String part2, String part3) { 
     setText(buildMiddleEditSpannable(part1, part2, part3)); 
     setSelection(part1.length() + part2.length() - 1); 
    } 

    private Spannable buildMiddleEditSpannable(String part1, String part2, 
      String part3) { 
     this.part1 = part1; 
     this.part2 = part2; 
     this.part3 = part3; 
     SpannableStringBuilder spannable = new SpannableStringBuilder(part1 
       + part2 + part3); 
     span1 = new ForegroundColorSpan(Color.GRAY); 
     spannable.setSpan(span1, 0, part1.length() - 1, 
       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     span2 = new UnderlineSpan(); 
     spannable.setSpan(span2, part1.length(), 
       part1.length() + part2.length(), 
       Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
     span3 = new ForegroundColorSpan(Color.GRAY); 
     spannable.setSpan(span3, (part1 + part2).length(), 
       (part1 + part2 + part3).length(), 
       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     return spannable; 
    } 

    @Override 
    protected void onSelectionChanged(int selStart, int selEnd) { 
     if (part1 == null) 
      return; 
     if (selStart >= getText().getSpanStart(span2) 
       && selEnd <= getText().getSpanEnd(span2)) { 
      setKeyListener((KeyListener) getTag()); 
      setCursorVisible(true); 
     } else { 
      setKeyListener(null); 
      setCursorVisible(false); 
     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode==KeyEvent.KEYCODE_ENTER) { 
      // Just ignore the [Enter] key 
      return true; 
     } 
     int selectionStart = getSelectionStart(); 
     int selectionEnd = getSelectionEnd(); 
     Log.d("partialedit", "OnKeyDown:" + selectionStart + ":" + selectionEnd + ":" + getText().getSpanStart(span2) + ":" + getText().getSpanEnd(span2)); 
     if (selectionStart < part1.length() + 1 
      || selectionStart >= getText().length() - part3.length()) { 
      return true; 
     } 

     // Handle all other keys in the default way 
     return super.onKeyDown(keyCode, event); 
    } 
} 
Cuestiones relacionadas