İletişim Bubble EditText


89

MultiAutoCompleteTextViewGoogle+ uygulamasında nasıl uygulandığına benzer şekilde kişi balonları oluşturmaya çalışıyorum . Aşağıda bir ekran görüntüsü verilmiştir:

Google+ Gönderi Oluştur Ekran Görüntüsü .

DynamicDrawableSpanBir dizi metnin arka planında yayılabilir bir çekilebilirlik elde etmek için sınıfı genişletmeye çalıştım

public class BubbleSpan extends DynamicDrawableSpan {
  private Context c;

  public BubbleSpan(Context context) {
    super();
    c = context;
  }

  @Override
  public Drawable getDrawable() {
    Resources res = c.getResources();
    Drawable d = res.getDrawable(R.drawable.oval);
    d.setBounds(0, 0, 100, 20);
    return d;
  }
}

Oval.xml çekilebilir dosyam şu şekilde tanımlanır:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <solid android:color="#352765"/>
  <padding android:left="7dp" android:top="7dp"
    android:right="7dp" android:bottom="7dp" />
  <corners android:radius="6dp" />
</shape>

Şu özelliklere sahip Etkinlik sınıfımda MulitAutoCompleteTextView, kabarcık yayılımını şu şekilde ayarladım:

final Editable e = tv.getEditableText();
final SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append("some sample text");
sb.setSpan(new BubbleSpan(getApplicationContext()), 0, 6, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
e.append(sb); 

Ancak dizede ilk 6 karakterin arkasında görüntülenen oval şekil yerine karakterler görünmez ve arka planda oval bir çizilebilirlik yoktur.

BubbleSpan'ın getDrawable () yöntemini şekil çizilebilir bir şekil yerine .png kullanacak şekilde değiştirirsem:

public Drawable getDrawable() {
  Resources res = c.getResources();
  Drawable d = res.getDrawable(android.R.drawable.bottom_bar);
  d.setBounds(0, 0, 100, 20);
  return d;
}

Daha sonra .png görünecek, ancak dizedeki açıklığın bir parçası olan karakterler görünmeyecektir. Yayılma alanındaki karakterlerin ön planda görüntülenmesini, bu arada özel bir şekil çizilebilirinin arka planda görüntülenmesini nasıl sağlayabilirim?

ImageSpanAlt sınıflandırma yerine bir de kullanmayı denedim DynamicDrawableSpanama başarısız oldu.



Seçilen irtibat numaralarını nasıl alıyorsunuz
srihari

github.com/splitwise/TokenAutoComplete bazılarına yardımcı olabilir
john-

Yanıtlar:


55

Tüm yardımlar için teşekkürler @chrish. İşte bunu nasıl yaptım:

final SpannableStringBuilder sb = new SpannableStringBuilder();
TextView tv = createContactTextView(contactName);
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(0, 0, bd.getIntrinsicWidth(),bd.getIntrinsicHeight());

sb.append(contactName + ",");
sb.setSpan(new ImageSpan(bd), sb.length()-(contactName.length()+1), sb.length()-1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
to_input.setText(sb);

public TextView createContactTextView(String text){
  //creating textview dynamically
  TextView tv = new TextView(this);
  tv.setText(text);
  tv.setTextSize(20);
  tv.setBackgroundResource(R.drawable.oval);
  tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_clear_search_api_holo_light, 0);
  return tv;
}

public static Object convertViewToDrawable(View view) {
  int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
  view.measure(spec, spec);
  view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
  Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
            Bitmap.Config.ARGB_8888);
  Canvas c = new Canvas(b);
  c.translate(-view.getScrollX(), -view.getScrollY());
  view.draw(c);
  view.setDrawingCacheEnabled(true);
  Bitmap cacheBmp = view.getDrawingCache();
  Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
  view.destroyDrawingCache();
  return new BitmapDrawable(viewBmp);

}

13
Ölçeklendirme sorunları nedeniyle bunun tüm cihazlarda çalışmadığını buldum. Bunu yapmanın daha iyi bir yolu, bitmap'i convertView'dan döndürmek, ardından çizilebilir kenarları ayarlarken gerçek bitmap'in boyutlarını kullanmaktır. Örneğin BitmapDrawable bd = new BitmapDrawable(bitmap); bd.setBounds(0,0,bitmap.getWidth(), bitmap.getHeight()); , tüm cihazlarda çalışır.
dmon

Merhaba, bunu yeni bir soruda yayınlamam gerekebilir, ancak çok satırlı Metin Görünümleri ile sorun yaşayıp yaşamadığınızı öğrenmek istedim. Bunu Android 3.2'de çalıştırıyorum ve "bazen", balonun genişliği iyi hesaplanmıyor gibi görünüyor. Metinde olduğu gibi sonraki satıra geçmeyecek, bunun yerine TextView dışında devam edecektir. Bunu gördüyseniz, herhangi bir ipucu var mı?
Johann Hilbold

1
Kabarcık içeren metin balondan daha genişse, otomatik tamamlama iki satırda iki kez oluşturulur. Bunu textView olarak ayarlamalısınız: textView.setMaxWidth (this.getWidth () - SOME_PADDING); `Ve bunu da kullanıyorum (eğer metin çok büyükse iki satırda balonda ve sonunda ... ile): textView.setEllipsize (TruncateAt.END); textView.setSingleLine (yanlış); textView.setMaxLines (2);
SocialError

açılır listeden seçtiğinizde bu iyi çalışıyor. Eğer önceden tanımlanmış bazı değerleri edittext olarak ayarlamak isterseniz, bu metni kenarlık n çapraz düğmesiyle nasıl kaydırabilirim?
Braj

5
metni silmek için metin görünümündeki farklı öğeye tıklama dinleyiciyi nasıl ekleyeceğiniz.
Nambi

21

İşte sizin için eksiksiz bir Çözüm

//creating textview dynamicalyy
TextView textView=new TextView(context);
textview.setText("Lauren amos");
textview.setbackgroundResource(r.color.urovalshape);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_cross, 0);


BitmapDrawable dd = (BitmapDrawable) SmsUtil.getDrawableFromTExtView(textView);
edittext.settext(addSmily(dd));

//convert image to spannableString
public SpannableStringBuilder addSmily(Drawable dd) {
 dd.setBounds(0, 0, dd.getIntrinsicWidth(),dd.getIntrinsicHeight());
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(":-)");
builder.setSpan(new ImageSpan(dd), builder.length() - ":-)".length(),builder.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

return builder;
}

  //convert view to drawable
  public static Object getDrawableFromTExtView(View view) {

    int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    view.measure(spec, spec);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    c.translate(-view.getScrollX(), -view.getScrollY());
    view.draw(c);
    view.setDrawingCacheEnabled(true);
    Bitmap cacheBmp = view.getDrawingCache();
    Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
    view.destroyDrawingCache();
    return new BitmapDrawable(viewBmp);

}

Spannble'ı kullanmak isteyenler için tam proje dosyası burada.


1
teşekkürler ... çözümünüz iyi çalışıyor ancak sorunlarım, EKLE düğmesine bastığımda kabarcık metni düzenleme metnine ekleniyor, ancak düzenleme metnini temizlediğimde ve yeniden girmeye çalıştığımda (Ekle düğmesine basın) önceden eklenen balon kalıyor yenisi de eklenir. ve sağ taraftaki çarpı işaretine bastığımda balonu da kaldırıyorum.
Govind Rathod

İlk sorunu ele alıyorum. Sanırım listede metni sakladınız ve Metni düzenle'yi temizlerken temizlemediniz. Akıllı olmayabilirim, sadece bir tahmindi çünkü nasıl kod yazdığınızı bilmiyorum.
Krishna Shrestha

Eski bir gönderi olduğunu biliyorum, ancak soruma cevap vermem gerekiyor ... Yukarıda gösterilenle aynı uygulamayı oluşturuyorum ... Öneriler için MultiAutoCompleteTextView kullanıyorum ve sonra öğe tıklandığında baloncukları oluştur ... kabarcıklar başarıyla oluşturuldu ancak benim sorunum, imlecin iki baloncuk arasında görünmesini istemiyorum ... MultiAutoCompleteTextView için boşluk belirteç kullanıyorum .. bunu nasıl başaracağıma dair herhangi bir ipucu ??
VijayRaj

@chrish Bu kod için teşekkürler, yine de bir sorum var. Halihazırda yanımda bazı değerlerimin olduğu bir durum var ve bunları yayılabilir metinler olarak doğrudan düzenleme metnine yapıştıracağım. ancak, şimdi sadece spannable projedeki kodunuzu bu tür bir işlevsellikle birleştirmenin mümkün olup olmadığını merak ediyorum. Çalışma zamanında silme isimleri ekleme yeteneğine sahip olmak istiyorum, grup halinde ekleme olabilir, ancak silme her zamanki gibi (tek tek) .. teşekkürler
kuldeep

5

Aradığınızı yapan bir kütüphanem var:

  • Varsayılan veya tamamen özelleştirilebilir (kendi düzeninizi bile kullanabilirsiniz)
  • Çok satırlı destek
  • Tıklama dinleyicisi

Buraya bir bak

İşte hızlı bir başlangıç:

ChipView'i mizanpajınıza ekleyin veya programlı olarak oluşturun:

<com.plumillonforge.android.chipview.ChipView
    android:id="@+id/chipview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Soyut Çipi ve bir tıklama dinleyicisini genişleten bir veri listesi ile başlatın (isterseniz):

List<Chip> chipList = new ArrayList<>();
chipList.add(new Tag("Lorem"));
chipList.add(new Tag("Ipsum dolor"));
chipList.add(new Tag("Sit amet"));
chipList.add(new Tag("Consectetur"));
chipList.add(new Tag("adipiscing elit"));
ChipView chipDefault = (ChipView) findViewById(R.id.chipview);
chipDefault.setChipList(chipList);
chipDefault.setOnChipClickListener(new OnChipClickListener() {
        @Override
        public void onChipClick(Chip chip) {
            // Action here !
        }
    });

Varsayılan ChipView şu şekilde oluşturulur:

Varsayılan ChipView

Ancak genelden Çip seviyesine kadar istediğiniz gibi özelleştirebilirsiniz:

Genel ChipView Özel ChipView

Bu bir MultiAutocomplete değil, ancak onu taklit etmeyi başarabilirsiniz (aslında bunu böyle kullanıyorum)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.