Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sample showing how to use Spannables to replace text with Images in Mono for Android.
using Android.App;
using Android.Text;
using Android.Text.Style;
using Android.Widget;
using Android.OS;
namespace MonoDroid.TextViewWithImages
{
[Activity(Label = "Text with Images", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
private EditText _editText;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var textView = FindViewById<TextView>(Resource.Id.textView1);
var imageSpan = new ImageSpan(this, Resource.Drawable.Icon); //Find your drawable.
var spannableString = new SpannableString(textView.Text); //Set text of SpannableString from TextView
spannableString.SetSpan(imageSpan, textView.Text.Length -1, textView.Text.Length, 0); //Add image at end of string
textView.TextFormatted = spannableString; //Assign string to TextView (Use TextFormatted for Spannables)
_editText = FindViewById<EditText>(Resource.Id.editText1);
_editText.AfterTextChanged += (sender, args) => SpannableTools.AddSmiles(this, args.Editable);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px">
<TextView
android:text="Hey there, I am a TextView with an image inside!"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/textView1" />
<EditText
android:inputType="textMultiLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/editText1"
android:hint="Type some text here" />
</LinearLayout>
using System.Collections.Generic;
using Android.Content;
using Android.Text;
using Android.Text.Style;
using Java.Lang;
namespace MonoDroid.TextViewWithImages
{
public static class SpannableTools
{
private static readonly Dictionary<string, int> Emoticons;
static SpannableTools()
{
Emoticons = new Dictionary<string, int>
{
{":-)", Resource.Drawable.Icon},
{":)", Resource.Drawable.Icon}
};
}
public static bool AddSmiles(Context context, ISpannable spannable)
{
var hasChanges = false;
foreach (var entry in Emoticons)
{
var smiley = entry.Key;
var smileyImage = entry.Value;
var indices = spannable.ToString().IndexesOf(smiley);
foreach (var index in indices)
{
var set = true;
foreach (ImageSpan span in spannable.GetSpans(index, index + smiley.Length, Java.Lang.Class.FromType(typeof(ImageSpan))))
{
if (spannable.GetSpanStart(span) >= index && spannable.GetSpanEnd(span) <= index + smiley.Length)
spannable.RemoveSpan(span);
else
{
set = false;
break;
}
}
if (set)
{
hasChanges = true;
spannable.SetSpan(new ImageSpan(context, smileyImage), index, index + smiley.Length, SpanTypes.ExclusiveExclusive );
}
}
}
return hasChanges;
}
public static ISpannable GetSmiledText(Context context, ICharSequence text)
{
var spannable = SpannableFactory.Instance.NewSpannable(text);
AddSmiles(context, spannable);
return spannable;
}
public static void AddSmiley(string textSmiley, int smileyResource)
{
Emoticons.Add(textSmiley, smileyResource);
}
}
//Taken from http://stackoverflow.com/a/767788/368379
public static class StringExtensions
{
public static IEnumerable<int> IndexesOf(this string haystack, string needle)
{
var lastIndex = 0;
while (true)
{
var index = haystack.IndexOf(needle, lastIndex);
if (index == -1)
{
yield break;
}
yield return index;
lastIndex = index + needle.Length;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.