2012-05-30 8 views
86

Ich versuche, Kontaktblasen in der MultiAutoCompleteTextView ähnlich wie in der Google+ App implementiert zu erstellen. Unten ist ein Screenshot:Bubble EditText kontaktieren

Google+ Compose Post Screenshot .

Ich habe versucht, die DynamicDrawableSpan Klasse zu erweitern, um eine spannable ziehbar im Hintergrund eine Spanne von Text

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

Wo ist mein oval.xml ziehbar wie so definiert ist, zu erhalten:

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

In meiner Aktivitätsklasse, die die MulitAutoCompleteTextView hat, habe ich die Blase Spannweite wie so gesetzt:

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

Anstelle der ovalen Form, die hinter den ersten 6 Zeichen in der Zeichenfolge angezeigt wird, sind die Zeichen jedoch nicht sichtbar, und im Hintergrund ist kein ovales Zeichen vorhanden.

Wenn ich die BubbleSpan des getDrawable() -Methode ändern, um eine .png anstelle einer Form zu verwenden ziehbar:

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

Dann wird die .png angezeigt, aber die Zeichen in der Zeichenfolge, die ein Teil der sind span wird nicht angezeigt. Wie kann ich dafür sorgen, dass die Zeichen in der Spanne im Vordergrund angezeigt werden, während eine benutzerdefinierte Form im Hintergrund angezeigt wird?

Ich versuchte auch eine ImageSpan anstelle der Unterklasse DynamicDrawableSpan zu verwenden, war aber nicht erfolgreich.

+0

mögliche duplikate von [Android Labels oder Bubbles in EditText] (http://stackoverflow.com/questions/8090711/android-labels-or-bubbles-in-edittext) –

+0

Wie erhalten Sie ausgewählte Telefonnummern – srihari

+1

Everthing ist in Ordnung, jetzt, wie man mit Kreuzbild klickt, ich will um die Ansicht zu entfernen, wenn der Benutzer auf das Kreuzsymbol klickt, bitte helfen Sie. – shaby

Antwort

51

Dank @chrish für alle Hilfe.Also hier ist, wie ich es tat:

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

} 
+12

Ich fand, dass dies nicht in allen Geräten aufgrund von Skalierungsproblemen funktioniert. Eine bessere Möglichkeit besteht darin, die Bitmap aus der convertView-Datei zurückzugeben und dann die Abmessungen der tatsächlichen Bitmap beim Festlegen der Zeichenkanten zu verwenden. Z.B. 'BitmapDrawable bd = neu BitmapDrawable (Bitmap); bd.setBounds (0,0, bitmap.getWidth(), Bitmap.getHeight()); ' Das funktioniert in allen Geräten. – dmon

+0

Hallo, ich muss dies möglicherweise in einer neuen Frage posten, wollte aber wissen, ob Sie Probleme mit mehrzeiligen TextViews hatten. Ich laufe das auf Android 3.2 und "manchmal" sieht es so aus, als ob die Breite der Blase nicht gut berechnet ist. Wie im Text wird nicht auf die nächste Zeile fortgesetzt, sondern stattdessen außerhalb der TextView. Wenn Sie das gesehen haben, irgendwelche Tipps? –

+1

Wenn der Text mit Bubble breiter als Autocomplete ist, wird die Bubble zweimal in zwei Zeilen erstellt. Sie sollten dies auf textView setzen: textView.setMaxWidth (this.getWidth() - SOME_PADDING); 'Und ich benutze auch dies (wenn Text zu groß ist, ist in zwei Zeilen in Blase und mit ... am Ende) : textView.setEllipsize (TruncateAt.END); textView.setSingleLine (false); textView.setMaxLines (2); – koso

21

ist die komplette Lösung für Sie

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

} 

Dies ist die komplette Projektdatei, wenn einer von euch verwenden möchten Spannble

+1

danke ... Ihre Lösung funktioniert gut, aber meine Probleme ist, wenn ich ADD-Taste gedrückt Blase Text ist in Edit-Text hinzufügen, aber wenn ich Clear bearbeiten -Text und versuchen, erneut eingeben (drücken Sie die Schaltfläche Hinzufügen) zuvor hinzugefügt Blase ist übrig und neue wird auch angehängt. und ich entferne auch Blase, wenn ich rechtses Kreuzzeichen drücke. –

+0

Adressierung der ersten Ausgabe. Ich nehme an, Sie haben Text in der Liste gespeichert und beim Löschen von Text nicht gelöscht. ich kann nicht wright sein, es war nur eine Vermutung, wie ich nicht weiß, wie Sie programmieren. –

+0

Ich weiß, es ist ein alter Beitrag, aber ich brauche eine Antwort auf meine Frage .. Ich bin die gleiche Anwendung wie oben gezeigt..im mit MultiAutoCompleteTextView für die Vorschläge und dann die Blasen erstellen, wenn das Element angeklickt wird .. die Blasen erfolgreich erstellt werden aber mein Problem ist, ich möchte nicht, dass der Cursor zwischen den zwei Blasen erscheint ... Ich benutze Raumtokenizer für MultiAutoCompleteTextView .. eine Ahnung wie man das erreicht ?? – VijayRaj

5

ich eine Bibliothek bekam die tut, was Sie suchen mit:

  • Standard oder vollständig anpassbar (Sie können sogar Ihr eigenes Layout verwenden)
  • Multiline-Unterstützung
  • Click Zuhörer

Have a look here

Hier ist ein Schnellstart:

ChipView zum Layout hinzufügen oder es programmatisch erstellen:

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

Init es mit einer Liste von Daten, den abstrakten Chip und einen Klick Zuhörer erweitern (wenn Sie möchten):

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

Standard ChipView wird wie folgt wiedergegeben:

Default ChipView

Aber Sie können anpassen, wie Sie aus insgesamt auf Chip-Ebene mag:

Overall ChipView Custom ChipView

Dies ist kein MultiAutocomplete aber Sie können es zu imitieren verwalten (ich verwende es tatsächlich so)

+0

Sie sind mein Lebensretter. Danke vielmals –