2012-05-30 46 views
86

我正在嘗試在MultiAutoCompleteTextView中創建聯繫人泡泡,與Google+應用中的實現方式類似。以下是一個截圖:聯繫人泡泡EditText

Google+ Compose Post Screenshot

我曾試圖擴大,以獲得spannable繪製文本

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繪製被定義爲這樣的背景下DynamicDrawableSpan類:

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

在我的Activity類具有MulitAutoCompleteTextView,我設置了泡跨度像這樣:

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

但是,字符串中前六個字符後面顯示的橢圓形不是橢圓形,而是字符不可見,並且在背景中沒有橢圓形可繪製。

如果我改變BubbleSpan的getDrawable()方法,而不是使用一個形狀繪製爲.png:

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

然後巴紐會出現,但該字符串中的字符是的一部分跨度不會顯示出來。我怎樣才能做到這一點,以便跨度中的字符顯示在前臺,同時可以在後臺顯示自定義形狀drawable?

我試圖也使用ImageSpan,而不是繼承DynamicDrawableSpan但不成功。

+0

[Android的標籤或泡泡在EditText]可能的重複(http://stackoverflow.com/questions/8090711/android-labels-or-bubbles-in-edittext) –

+0

如何獲取選定的聯繫電話 – srihari

+1

Everthing很好,現在如何處理十字圖像點擊,我想要的如果用戶點擊十字圖標,請刪除該視圖,請幫助。 – shaby

回答

51

感謝@chrish所有幫助。因此,這裏是我是如何做的:

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

我發現這並不適用於所有設備由於縮放問題。更好的方法是從convertView返回位圖,然後在設置可繪製邊時使用實際位圖的尺寸。例如。 'BitmapDrawable bd = new BitmapDrawable(bitmap); bd.setBounds(0,0,bitmap.getWidth(),位圖。getHeight());' 適用於所有設備。 – dmon

+0

嗨,我可能需要發佈這個新的問題,但想知道你是否遇到多行TextViews的問題。我在Android 3.2和「有時」上運行這個,看起來泡泡的寬度計算不準確。在文本中不會繼續到下一行,而是在TextView之外繼續。如果你看過這個,有什麼建議? –

+1

如果帶氣泡的文本比自動完成的氣泡寬兩倍,則會在兩行中創建氣泡兩次。你把這個設置爲textView: textView.setMaxWidth(this.getWidth() - SOME_PADDING);'我也使用它(如果文本太大,則在兩行中,在泡沫中,並在...末尾) :textView.setEllipsize(TruncateAt.END); textView.setSingleLine(假); textView.setMaxLines(2); – koso

21

這裏是你

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

+1

謝謝...您的解決方案正常工作,但我的問題是當我按下添加按鈕泡泡文本添加編輯文本,但當我清除編輯文本並嘗試重新輸入(按添加按鈕)以前添加的泡泡是剩餘的,並且新的也被添加。當按右側十字標記時,我也會刪除氣泡。 –

+0

解決第一個問題。我猜你保存了列表中的文本,並且在清除編輯文本時沒有清除。我可能不會懷疑,這只是一個猜測,因爲我不知道你是如何編碼的。 –

+0

我知道它的一箇舊帖子,但我需要回答我的問題..我正在構建相同的應用程序,如上所示..使用MultiAutoCompleteTextView作爲建議,然後創建氣泡,當項目被點擊..泡沫成功創建但我的問題是我不希望光標出現在兩個氣泡之間...我用MultiAutoCompleteTextView使用空間tokenizer ..任何線索如何實現這? – VijayRaj

5

我得到了一個庫,做你要找的內容有:

  • 默認或完全可定製的(你甚至可以使用自己的佈局)
  • 多行支持
  • 點擊收聽

Have a look here

這裏的快速啓動:

添加ChipView到您的佈局或編程方式創建它:與擴展抽象的芯片和點擊監聽器(如果你想)數據的列表

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

初始化它:

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 ChipView

但是你可以定製你從整體到芯片級,如:

Overall ChipView Custom ChipView

這不是MultiAutocomplete但你可以設法模仿它(我真正使用它像)

+0

你是我的救星。非常感謝 –