2012-05-30 15 views
86

Estoy tratando de crear burbujas de contacto en el MultiAutoCompleteTextView de forma similar a cómo se implementa en la aplicación de Google+. Debajo hay una captura de pantalla:Contacto Bubble EditText

Google+ Compose Post Screenshot .

me han tratado de extender la clase DynamicDrawableSpan con el fin de obtener una dibujable spannable en el fondo de un fragmento de texto

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

Donde mi oval.xml estirable por lo que se define como:

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

En mi clase de actividad que tiene el MulitAutoCompleteTextView, que establecer el lapso de la burbuja de este modo:

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

Sin embargo, en lugar de la forma ovalada que se muestra detrás de los primeros 6 caracteres en la cadena, los caracteres no son visibles y no hay un dibujo ovalado en el fondo.

si cambio el método de BubbleSpan getDrawable() para utilizar un .png en lugar de una forma estirable:

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

Entonces el .png se mostrará, pero los caracteres de la cadena que son una parte de la span no aparecerá. ¿Cómo puedo hacerlo para que los caracteres del tramo se muestren en primer plano, mientras tanto, se visualiza un dibujable de forma personalizada en el fondo?

Intenté utilizar también un ImageSpan en lugar de crear subclases DynamicDrawableSpan pero no tuve éxito.

+0

posible duplicado de etiquetas [Android o burbujas en EditarTexto] (http://stackoverflow.com/questions/8090711/android-labels-or-bubbles-in-edittext) –

+0

números de contacto Cómo estás ser elegida – srihari

+1

Everthing está bien, ahora cómo manejar el clic de imagen cruzada, quiero para eliminar la vista si el usuario hace clic en el ícono de cruz, por favor ayuda. – shaby

Respuesta

51

Gracias @chrish por toda la ayuda.Así que aquí está cómo lo hice:

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

Encontré que esto no funcionaba en todos los dispositivos debido a problemas de escala. Una mejor forma de hacerlo es devolver el mapa de bits desde convertView, luego usar las dimensiones reales del mapa de bits al establecer los bordes dibujables. P.ej. 'BitmapDrawable bd = new BitmapDrawable (mapa de bits); bd.setBounds (0,0, bitmap.getWidth(), mapa de bits.getHeight()); ' Eso funciona en todos los dispositivos. – dmon

+0

Hola, es posible que necesite publicar esto en una nueva pregunta, pero quería saber si tuvo problemas con TextView multilínea. Estoy ejecutando esto en Android 3.2 y "a veces", parece que el ancho de la burbuja no se calcula bien. Como en el texto, no continuará a la siguiente línea, sino que continuará fuera de TextView. Si has visto esto, ¿algún consejo? –

+1

Si el texto con burbuja es más ancho que autocompletar, la burbuja se crea dos veces en dos filas. Debes configurar esto para textView: textView.setMaxWidth (this.getWidth() - SOME_PADDING); 'Y también estoy usando esto (si el texto es demasiado grande está en dos líneas en burbuja y con ... al final) : textView.setEllipsize (TruncateAt.END); textView.setSingleLine (falso); textView.setMaxLines (2); – koso

21

Aquí es una solución completa para usted

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

} 

Aquí está el archivo completo del proyecto, si alguno de ustedes desea utilizar Spannble

+1

gracias ... su solución funciona bien, pero mi problema es cuando presioné el botón AÑADIR botón burbuja-texto se agrega en el texto de edición pero cuando borro editar -text y tratando de reingresar (presione el botón Agregar) previamente se agregó la burbuja restante y se agrega una nueva. y también elimino la burbuja cuando presiono el signo de cruz del lado derecho. –

+0

Solucionando el primer problema. Supongo que almacenaste texto en la lista y no lo borraste mientras borraste el texto. Puede que no sea correcto, solo fue una suposición ya que no conozco la forma de codificar. –

+0

Sé que es una publicación anterior, pero necesito responder a mi pregunta ... Estoy compilando la misma aplicación que se muestra arriba ... utilizando MultiAutoCompleteTextView para las sugerencias y luego creo las burbujas cuando se hace clic en el elemento ... las burbujas se crean con éxito pero mi problema es que no quiero que el cursor aparezca entre las dos burbujas ... Estoy usando el tokenizador espacial para MultiAutoCompleteTextView ... ¿alguna pista de cómo lograr esto? – VijayRaj

5

Tengo una biblioteca que hace lo que usted está buscando con:

  • defecto o completamente personalizable (incluso se puede utilizar su propio diseño)
  • apoyo de varias líneas
  • Haga clic oyente

Have a look here

Aquí una guía de inicio rápido:

Añadir ChipView a su disposición o crear mediante programación:

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

Init con una lista de datos que se extienden Viruta abstracta y un oyente clic (si lo desea):

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 defecto aparece así:

Default ChipView

pero se puede personalizar a su gusto a partir general a nivel de chip:

Overall ChipView Custom ChipView

Esto no es un MultiAutocomplete pero que puede llegar a imitar (yo en realidad estoy usando el estilo)

+0

eres mi salvador de vidas. muchas gracias –