Hubungi Bubble EditText


89

Saya mencoba membuat gelembung kontak yang MultiAutoCompleteTextViewserupa dengan penerapannya di aplikasi Google+. Di bawah ini adalah tangkapan layarnya:

Tangkapan Layar Posting Google+ .

Saya telah mencoba memperluas DynamicDrawableSpankelas untuk mendapatkan drawable yang dapat digambar di latar belakang rentang teks

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;
  }
}

Di mana drawable oval.xml saya didefinisikan sebagai:

<?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>

Di kelas Aktivitas saya yang memiliki MulitAutoCompleteTextView, saya mengatur rentang gelembung seperti ini:

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); 

Namun, alih-alih menampilkan bentuk oval di belakang 6 karakter pertama dalam string, karakter tersebut tidak terlihat dan tidak ada drawable oval di latar belakang.

Jika saya mengubah metode getDrawable () BubbleSpan untuk menggunakan .png sebagai ganti drawable bentuk:

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

Kemudian .png akan muncul tetapi karakter dalam string yang merupakan bagian dari span tidak akan muncul. Bagaimana cara membuatnya sehingga karakter dalam span ditampilkan di latar depan, sementara drawable bentuk kustom ditampilkan di latar belakang?

Saya mencoba juga menggunakan an ImageSpanalih - alih subclass DynamicDrawableSpantetapi tidak berhasil.



Bagaimana Anda mendapatkan nomor kontak yang dipilih
srihari

github.com/splitwise/TokenAutoComplete bisa berguna bagi sebagian orang
john-salib

Jawaban:


55

Terima kasih @chrish untuk semua bantuannya. Jadi, inilah cara saya melakukannya:

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
Saya menemukan bahwa ini tidak berfungsi di semua perangkat karena masalah penskalaan. Cara yang lebih baik untuk melakukannya adalah dengan mengembalikan bitmap dari convertView, lalu menggunakan dimensi bitmap yang sebenarnya saat menyetel tepi drawable. Misalnya BitmapDrawable bd = new BitmapDrawable(bitmap); bd.setBounds(0,0,bitmap.getWidth(), bitmap.getHeight()); Itu berfungsi di semua perangkat.
dmon

Hai, saya mungkin perlu memposting ini di pertanyaan baru, tetapi ingin tahu apakah Anda mengalami masalah dengan TextView multi baris. Saya menjalankan ini di Android 3.2 dan "terkadang", sepertinya lebar balon tidak dihitung dengan baik. Seperti di teks tidak akan melanjutkan ke baris berikutnya, tetapi melanjutkan di luar TextView. Jika Anda pernah melihat ini, ada tips?
Johann Hilbold

1
Jika teks dengan gelembung lebih lebar maka pelengkapan otomatis daripada gelembung dibuat dua kali dalam dua baris. Anda harus mengatur ini ke textView: textView.setMaxWidth (this.getWidth () - SOME_PADDING); `Dan saya juga menggunakan ini (jika teks terlalu besar dalam dua baris dalam gelembung dan dengan ... di akhir): textView.setEllipsize (TruncateAt.END); textView.setSingleLine (false); textView.setMaxLines (2);
SocialError

ini berfungsi dengan baik jika Anda memilih dari daftar dropdown. Dalam kasus, jika Anda ingin mengatur beberapa nilai yang telah ditentukan ke teks edit, lalu, bagaimana saya bisa membungkus teks itu dengan tombol silang n perbatasan?
Braj

5
bagaimana Anda menambahkan clicklistener ke item berbeda di textview untuk menghapus teks.
Nambi

21

Inilah Solusi lengkap untuk Anda

//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);

}

Berikut ini file proyek lengkapnya, jika ada di antara Anda yang ingin menggunakan Spannble


1
terima kasih ... solusi Anda berfungsi dengan baik tetapi masalah saya adalah ketika saya menekan tombol TAMBAH, teks gelembung ditambahkan dalam teks edit tetapi ketika saya Hapus teks edit dan mencoba masuk kembali (tekan tombol Tambah) gelembung yang ditambahkan sebelumnya masih tersisa dan yang baru juga ditambahkan. dan saya juga menghapus gelembung saat menekan tanda silang sisi kanan.
Govind Rathod

Mengatasi masalah pertama. Saya kira Anda menyimpan teks dalam daftar dan Anda tidak menghapus saat menghapus Edit teks. saya mungkin tidak akan baik-baik saja, itu hanya tebakan karena saya tidak tahu bagaimana Anda membuat kode.
Krishna Shrestha

Saya tahu ini adalah posting lama, tapi saya butuh jawaban untuk pertanyaan saya..Saya sedang membangun aplikasi yang sama seperti yang ditunjukkan di atas..im menggunakan MultiAutoCompleteTextView untuk saran dan kemudian membuat gelembung ketika item diklik .. gelembung berhasil dibuat tetapi masalah saya adalah saya tidak ingin kursor muncul di antara dua gelembung ... Saya menggunakan tokenizer spasi untuk MultiAutoCompleteTextView .. ada petunjuk bagaimana mencapai ini ??
VijayRaj

@chrish Terima kasih untuk kode ini, saya punya satu pertanyaan. Saya memiliki situasi di mana saya sudah memiliki beberapa nilai dengan saya, dan saya akan menempelkannya langsung ke teks edit sebagai teks yang dapat dipisahkan. Namun, sekarang saya hanya ingin tahu apakah mungkin untuk menggabungkan kode Anda dari proyek spannable dengan fungsi semacam ini. Saya ingin memiliki kemampuan untuk menambahkan nama hapus pada waktu proses, penambahan dapat terjadi secara berkelompok, namun hapus seperti biasa (satu per satu) .. terima kasih
kuldeep

5

Saya mendapat perpustakaan yang melakukan apa yang Anda cari:

  • Default atau sepenuhnya dapat disesuaikan (Anda bahkan dapat menggunakan tata letak Anda sendiri)
  • Dukungan multiline
  • Klik pendengar

Lihat di sini

Berikut panduan memulai:

Tambahkan ChipView ke layout Anda atau buat secara terprogram:

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

Masukkan dengan daftar data yang memperluas Chip abstrak dan pendengar klik (jika Anda mau):

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 !
        }
    });

ChipView default ditampilkan seperti ini:

ChipView default

Tetapi Anda dapat menyesuaikan sesuka Anda dari keseluruhan ke level Chip:

ChipView keseluruhan ChipView Kustom

Ini bukan MultiAutocomplete tetapi Anda dapat menirunya (saya sebenarnya menggunakannya seperti itu)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.