Cómo insertar texto extraíble

Quiero insertar imágenes pequeñas, como iconos de flecha por ejemplo, en ciertas posiciones de contenido de un TextView .

La foto de abajo muestra exactamente lo que quiero:

Así es como quiero incrustar iconos en el texto

Obviamente, la solución más ingenua es usar múltiples TextView a cada lado de los pequeños objetos ImageView . Pero esto es demasiado laborioso y amateur.

Tengo curiosidad por saber si alguien ha superado este problema con algún truco simple pero inteligente. (Tal vez con la ayuda de HTML-que no soy un experto-o una biblioteca externa)

Cualquier solución eficiente es muy apreciada.

Editar:

Estoy usando el método de reVerse y obteniendo este error:

 08-21 18:28:43.740: E/AndroidRuntime(4610): FATAL EXCEPTION: main 08-21 18:28:43.740: E/AndroidRuntime(4610): java.lang.NullPointerException 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.style.DynamicDrawableSpan.getSize(DynamicDrawableSpan.java:81) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.TextLine.handleReplacement(TextLine.java:842) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.TextLine.handleRun(TextLine.java:937) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.TextLine.measureRun(TextLine.java:414) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.TextLine.measure(TextLine.java:293) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.TextLine.metrics(TextLine.java:267) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.Layout.measurePara(Layout.java:1556) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.Layout.getDesiredWidth(Layout.java:87) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.text.Layout.getDesiredWidth(Layout.java:67) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.TextView.onMeasure(TextView.java:6168) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1034) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.LinearLayout.onMeasure(LinearLayout.java:590) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:681) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1217) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.ScrollView.onMeasure(ScrollView.java:321) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 08-21 18:28:43.740: E/AndroidRuntime(4610): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2176) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.View.measure(View.java:15518) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1876) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1089) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1265) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4353) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:760) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.Choreographer.doCallbacks(Choreographer.java:573) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.Choreographer.doFrame(Choreographer.java:543) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:746) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.os.Handler.handleCallback(Handler.java:725) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.os.Handler.dispatchMessage(Handler.java:92) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.os.Looper.loop(Looper.java:137) 08-21 18:28:43.740: E/AndroidRuntime(4610): at android.app.ActivityThread.main(ActivityThread.java:5041) 08-21 18:28:43.740: E/AndroidRuntime(4610): at java.lang.reflect.Method.invokeNative(Native Method) 08-21 18:28:43.740: E/AndroidRuntime(4610): at java.lang.reflect.Method.invoke(Method.java:511) 08-21 18:28:43.740: E/AndroidRuntime(4610): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 08-21 18:28:43.740: E/AndroidRuntime(4610): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 08-21 18:28:43.740: E/AndroidRuntime(4610): at dalvik.system.NativeStart.main(Native Method) 

Y este es mi diseño XML:

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:background="@drawable/background" android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/nav_left" android:layout_marginLeft="15dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:clickable="true" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:src="@drawable/leftnav" /> <ImageView android:id="@+id/nav_right" android:layout_marginRight="15dp" android:focusable="false" android:clickable="true" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:src="@drawable/rightnav" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/padding_vertical" android:paddingBottom="@dimen/padding_vertical" android:paddingLeft="@dimen/padding_horizontal" android:paddingRight="@dimen/padding_horizontal" > <TextView android:id="@+id/textView_header" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:fontFamily="sans-serif-light" android:textSize="32sp" android:textColor="@android:color/holo_blue_bright" android:text="Large Text For Header" android:textAppearance="?android:attr/textAppearanceLarge" /> <LinearLayout android:layout_marginTop="20dp" android:id="@+id/linear_layout_text_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_below="@+id/textView_header" android:orientation="horizontal" > <com.iseemedia.mguide.model.TextViewWithImages android:id="@+id/textView_body" android:layout_width="0dp" android:layout_weight="0.7" android:layout_height="wrap_content" android:text="@string/aaa" android:textAppearance="?android:attr/textAppearanceMedium" /> <ImageView android:id="@+id/imageView_body" android:layout_width="0dp" android:layout_weight="0.3" android:layout_height="wrap_content" android:src="@drawable/myapp" /> </LinearLayout> <ImageView android:id="@+id/imageView_whole_page" android:layout_below="@id/linear_layout_text_img" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <ListView android:id="@+id/listView_title_description" android:layout_width="match_parent" android:layout_height="200dp" android:layout_below="@+id/imageView_whole_page" android:layout_centerHorizontal="true" > </ListView> <TableLayout android:layout_below="@id/listView_title_description" android:layout_width="match_parent" android:layout_height="wrap_content" android:stretchColumns="1"> <TableRow> <TextView android:background="@drawable/table_header_cell_shape" android:layout_width="0dp" android:layout_column="1" android:textSize="@dimen/table_cell_text_size" android:text="@string/type" android:layout_weight="0.33" android:padding="3dip" /> <TextView android:background="@drawable/table_header_cell_shape" android:layout_width="0dp" android:layout_weight="1" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_header_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_header_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_header_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_header_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_width="0dp" android:layout_weight="0.33" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/type" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_width="0dp" android:layout_weight="0.33" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/type" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_width="0dp" android:layout_weight="0.33" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/type" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_width="0dp" android:layout_weight="0.33" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/type" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_width="0dp" android:layout_weight="0.33" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/type" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/format" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/encoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_column="1" android:background="@drawable/table_cell_shape" android:text="@string/decoder" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:layout_column="1" android:text="@string/specifications" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/table_cell_shape" android:text="@string/supporrting_file_types" android:textSize="@dimen/table_cell_text_size" android:padding="3dip" /> </TableRow> </TableLayout> </RelativeLayout> </RelativeLayout> </ScrollView> 

Puede crear SpannableString y agregar cualquier objeto a su cadena

 TextView textView = (TextView) findViewById(R.id.textView); ImageSpan imageSpan = new ImageSpan(this, R.drawable.ic_launcher); SpannableString spannableString = new SpannableString(textView.getText()); int start = 3; int end = 4; int flag = 0; spannableString.setSpan(imageSpan, start, end, flag); textView.setText(spannableString); 

Había una pregunta similar hace un tiempo y alguien llegó con una solución impresionante. Acabo de ajustar esto un poco para que el tamaño de la imagen es siempre tan alto como la línea. Tan básicamente sus iconos escalarán con el textSize .

Paso 1 – Crear una nueva vista

Crear una nueva clase Java que extienda TextView

 public class TextViewWithImages extends TextView { public TextViewWithImages(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public TextViewWithImages(Context context, AttributeSet attrs) { super(context, attrs); } public TextViewWithImages(Context context) { super(context); } @Override public void setText(CharSequence text, BufferType type) { Spannable s = getTextWithImages(getContext(), text, this.getLineHeight()); super.setText(s, BufferType.SPANNABLE); } private static final Spannable.Factory spannableFactory = Spannable.Factory.getInstance(); private static boolean addImages(Context context, Spannable spannable, float height) { Pattern refImg = Pattern.compile("\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E"); boolean hasChanges = false; Matcher matcher = refImg.matcher(spannable); while (matcher.find()) { boolean set = true; for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) { if (spannable.getSpanStart(span) >= matcher.start() && spannable.getSpanEnd(span) <= matcher.end() ) { spannable.removeSpan(span); } else { set = false; break; } } String resName = spannable.subSequence(matcher.start(1), matcher.end(1)).toString().trim(); int id = context.getResources().getIdentifier(resName, "drawable", context.getPackageName()); Drawable mDrawable = context.getResources().getDrawable(id); mDrawable.setBounds(0, 0, (int)height, (int)height); if (set) { hasChanges = true; spannable.setSpan( new ImageSpan(mDrawable), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); } } return hasChanges; } private static Spannable getTextWithImages(Context context, CharSequence text, float height) { Spannable spannable = spannableFactory.newSpannable(text); addImages(context, spannable, height); return spannable; } } 

Paso 2 – Uso en el diseño

Ahora en su layout-xml sólo use la clase TextViewWithImages

 <com.stacko.examples.TextViewWithImages android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp" android:text="@string/my_string_with_icons" /> 

Paso 3 – Crear cadenas con iconos

Como se puede ver en la función addImages(...) de la clase TextViewWithImages , se TextViewWithImages un patrón especial ( [img src=my_icon/] ) dentro de la cadena para agregar las imágenes. Así que aquí está un ejemplo:

 <string name="my_string_with_icons">The [img src=ic_action_trash/] is used to delete an item while the [img src=ic_action_edit/] is to edit one.</string> 

La salida:

Introduzca aquí la descripción de la imagen

Y como se dijo anteriormente que se escala con su textSize :

Introduzca aquí la descripción de la imagen

Como se dijo inicialmente la mayor parte de este post se toma de 18446744073709551615 respuesta aquí . Creo que esto debe ser publicado como una biblioteca, ya que es un caso de uso común para tener imágenes en el texto. : <

Una opción es utilizar un WebView lugar de un TextView . Esto también le permite mostrar imágenes de su carpeta de activos.

Vea Android Development: Uso de la imagen de los activos en el HTML de WebView para obtener más detalles.

  • La carátula de TextView de Android no funciona
  • TextView "fill_parent" no rellena el padre
  • ¿Cómo crear sugerencias en el cuadro de edición textview que desaparecen cuando textview tiene foco?
  • Cómo deshabilitar Word-wrap en Multiline Android TextView?
  • Forzar la siguiente palabra a una nueva línea si la palabra es demasiado larga para la vista de texto
  • Sombra larga de Android TextView
  • TextView setScaleX () / setScaleY () y setTextIsSelectable (true) selección
  • ¿Por qué la marquesina no funciona en Widget?
  • IllegalArgumentException al seleccionar texto en Android TextView
  • OnFling para que un TextView no funcione
  • Android TextView: ¿hay una manera de forzar la animación de la marquesina con texto corto?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.