2016-04-03 12 views
1

Bir kullanıcının bir EditText dosyasındaki bir spannable'ı silme veya değiştirme işlemini engellemenin bir yolu var mı? Daha spesifik olarak, EditText'in ilk karakteri olarak bir ImageSpan var. Kullanıcının bu ImageSpan'ı silemediğinden emin olmak istiyorum.Bir EditText'te bir silinebilir silme nasıl engellenir?

TextWatcher'ı kullanabileceğimi ve kullanıcı silerse ImageSpan'ı değiştirebileceğimin farkındayım. Bu oldukça çirkin ve ilk etapta silme işlemini engellemenin bir yolu olduğunu umuyorum.

Burada metin değeri ayarlamak kodunun Bir parça var:

Bitmap bitmap = <bitmap from elsewhere>; 
String text = <text to display after ImageSpan, from elsewhere>; 

SpannableString ss = new SpannableString (" " + text); 
ImageSpan image = new ImageSpan (getContext(), bitmap, ImageSpan.ALIGN_BOTTOM); 
ss.setSpan (image, 0, 1, 0); 

setText (ss); 
+0

Özel bir 'InputFilter' ayarlamak veya 'TextView' alt sınıfını oluşturmak ve 'InputConnection' kendi uygulamanızı geçersiz kılmanın bazı yöntemlerini sağlamak gibi istediğinizi yapmak için birden çok yol vardır. Ama 'TextWatcher' kullanmak benim bildiğim en basit çözümdür. – Michael

+0

Yani, bunun üstesinden gelmek için kullanılacak bir Spannable özelliği yok mu? –

+0

Bahsetmediğim bir yöntem var. Bir cevap olarak yazacağım. – Michael

cevap

4

Tamam, çözüm oldukça karmaşıktır ama işe yarıyor. Özel bir InputFilter ve SpanWatcher'a ihtiyacımız var. Hadi başlayalım.

İlk adım oldukça basit. Bir resim açıklığı ile düzenlenebilir olmayan bir ön ek ayarladık ve bu önekin ardından bir imleç ayarladık.

final String prefix = "?"; 
final ImageSpan image = new ImageSpan(this, R.drawable.image); 

edit.setText(prefix); 
edit.getText().setSpan(image, 0, prefix.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); 
edit.setSelection(prefix.length()); 

Sonra düzenleme açıklıklı önek önleyecek bir InputFilter ayarlayın. Önceden sonra başlaması için düzenlenmekte olan bir menzili hareket ettirerek yapılabilir.
edit.setFilters(new InputFilter[] { 
    new InputFilter() { 
     @Override 
     public CharSequence filter(final CharSequence source, final int start, 
      final int end, final Spanned dest, final int dstart, final int dend) { 
     final int newStart = Math.max(prefix.length(), dstart); 
     final int newEnd = Math.max(prefix.length(), dend); 
     if (newStart != dstart || newEnd != dend) { 
      final SpannableStringBuilder builder = new SpannableStringBuilder(dest); 
      builder.replace(newStart, newEnd, source); 
      if (source instanceof Spanned) { 
      TextUtils.copySpansFrom(
       (Spanned) source, 0, source.length(), null, builder, newStart); 
      } 
      Selection.setSelection(builder, newStart + source.length()); 
      return builder; 
     } else { 
      return null; 
     } 
     } 
    } 
}); 

Sonra seçim değişiklikleri saptamak ve önek aralığın dışında seçimini hareket edecek bir SpanWatcher oluşturun.

final SpanWatcher watcher = new SpanWatcher() { 
    @Override 
    public void onSpanAdded(final Spannable text, final Object what, 
     final int start, final int end) { 
    // Nothing here. 
    } 

    @Override 
    public void onSpanRemoved(final Spannable text, final Object what, 
     final int start, final int end) { 
    // Nothing here. 
    } 

    @Override 
    public void onSpanChanged(final Spannable text, final Object what, 
     final int ostart, final int oend, final int nstart, final int nend) { 
    if (what == Selection.SELECTION_START) { 
     if (nstart < prefix.length()) { 
     final int end = Math.max(prefix.length(), Selection.getSelectionEnd(text)); 
     Selection.setSelection(text, prefix.length(), end); 
     } 
    } else if (what == Selection.SELECTION_END) { 
     final int start = Math.max(prefix.length(), Selection.getSelectionEnd(text)); 
     final int end = Math.max(start, nstart); 
     if (end != nstart) { 
     Selection.setSelection(text, start, end); 
     } 
    } 
    } 
}; 

Ve nihayet biz sadece metne SpanWatcher ekleyin.

Ve hepsi bu. Yani bu çözümü sadece bir TextWatcher ekleyerek karşılaştırmak, ikinci yaklaşımı tercih ederim.

+0

Henüz kodunuzu geçmedim, ama içine koyduğunuz zamanı takdir ediyorum. Birisi Google'ın bir EditText'e yazılan karakterleri engellemeyi daha kolay bir hale getireceğini düşünürdü! –

+0

Bence 'TextView' en karmaşık UI bileşenlerinden biridir. Bununla bazı bariz şeyler yapmak gerçekten zor olabilir. – Michael

İlgili konular