2012-07-13 12 views
7

Desidero consentire all'utente di modificare solo parte di una riga di testo nella mia app per Android. Vedo una classe chiamata EasyEditSpan ma quando la inserisco in una TextView non succede nulla. Ho provato a rendere modificabile il TextView ma non ha ancora alcun effetto. Se si passa a un EditText, l'intera riga di testo è modificabile, anch'essa errata. Qui è il mio codice:In che modo EasyEditSpan viene utilizzato in Android per consentire la modifica parziale del testo?

@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

Qual è la versione di Android vostro target app per funzionare? Nota che [EasyEditSpan] (http://developer.android.com/reference/android/text/style/EasyEditSpan.html) è una novità introdotta a partire dall'API Livello 14. Potrebbe rompersi sul vecchio sistema Android, anche se dovresti ottenere qualche eccezione di errore in Logcat. – yorkw

+0

Sono in esecuzione e test solo su Ice Cream Sandwich o superiore. – satur9nine

risposta

5

Dopo aver guardato il codice del framework riferimento alla EasyEditSpan (EasyEditSpan, TextView e TextUtils), diventa evidente che anche se si dice nella sua descrizione:

fornisce un facile modo per modificare una porzione di testo.

La funzionalità attualmente disponibile è limitato alla sola seconda parte della descrizione come segue:

Il TextView utilizza questo lasso di permettere all'utente di eliminare un mandrino di testo in uno scatto. il testo. TextView rimuove questo intervallo non appena il testo viene modificato o il cursore si sposta.

Ecco alcuni esempi di codice veloce che dimostra il suo 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(); 
    } 

} 

Così, purtroppo, se avete bisogno di un modo per consentire all'utente di modificare solo una parte di una riga di testo nella vostra applicazione, EasyEditSpan non lo fa sembra aiutare molto. È probabile che dovrai implementare del codice utilizzando ClickableSpan e probabilmente una finestra di dialogo personalizzata.

+0

Guardando il codice in TextView, non ho potuto vedere come EasyEditSpan ha reso facile modificare qualsiasi cosa. Anche il Javadoc dice che consente solo la cancellazione del testo. – sww314

3

Potrebbe essere meglio utilizzare ClickableSpan e visualizzare una finestra di dialogo per modificare il contenuto. Tuttavia, ho provato a implementare la visualizzazione di testo parzialmente modificabile. Questo non è completo e potrebbe avere alcuni spigoli. Utilizza tre span e sovrascrive i metodi onSelectionChanged (int selStart, int selEnd) e onKeyDown (int keyCode, KeyEvent event) per disabilitare le modifiche mentre il target è part1 o part3. Spero che sia d'aiuto.

//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); 
    } 
} 
Problemi correlati