I want to insert a image to a editText my code is:
CharSequence charSeq= editText.getText()+\" \";
SpannableString ss2 = new SpannableString(charSeq);
Do something like this (note: you can reuse SpannableStringBuilder)
editText = (EditText)mRoot.findViewById(R.id.content);
ImageSpan imageSpan = new ImageSpan(preview);
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(editText.getText());
// this is a string that will let you find a place, where the ImageSpan is.
String imgId = "[img=1]";
int selStart = editText.getSelectionStart();
// current selection is replaceв with imageId
builder.replace(editText.getSelectionStart(), editText.getSelectionEnd(), imgId);
// This adds a span to display image where the imageId is. If you do builder.toString() - the string will contain imageId where the imageSpan is.
// you can use it later - if you want to find location of imageSpan in text;
builder.setSpan(imageSpan, selStart, selStart + imgId.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(builder);
Note: See follow up answer for dealing with partial deletion of tags
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.content.Context;
import android.text.Spannable;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.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);
super.setText(s, BufferType.SPANNABLE);
}
private static final Spannable.Factory spannableFactory = Spannable.Factory.getInstance();
private static boolean addImages(Context context, Spannable spannable) {
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());
if (set) {
hasChanges = true;
spannable.setSpan( new ImageSpan(context, id),
matcher.start(),
matcher.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
return hasChanges;
}
private static Spannable getTextWithImages(Context context, CharSequence text) {
Spannable spannable = spannableFactory.newSpannable(text);
addImages(context, spannable);
return spannable;
}
}
Use:
in res/layout/mylayout.xml:
<com.xyz.customandroid.TextViewWithImages
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF00"
android:text="@string/can_try_again"
android:textSize="12dip"
style=...
/>
in res/values/strings.xml:
<string name="can_try_again">Press [img src=ok16/] to accept or [img src=retry16/] to retry</string>
where ok16.png and retry16.png are in the res/drawable/ folder
Try this, i hope you are in search of this:
<EditText
android:id="@+id/editText1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/icon">
</EditText>
The same thing you can try for:
android:drawableRight
android:drawableTop
android:drawableBottom
android:drawablePadding
I guess, You'll also need some functionality for text-editing: image should be removed if one character of it is removed; this class can help (removes all the image text-placeholder if a char of it is removed)
public class ImageSpanTextWatcher implements TextWatcher {
Object[] mTouchedSpans;
int[] mSpanLength;
boolean replacing = false;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (s instanceof SpannableStringBuilder) {
SpannableStringBuilder ssb = (SpannableStringBuilder) s;
mTouchedSpans = ssb.getSpans(start, start + count, ImageSpan.class);
if (mTouchedSpans != null && mTouchedSpans.length > 0) {
mSpanLength = new int[mTouchedSpans.length];
for (int i = 0; i < mTouchedSpans.length; i++) {
mSpanLength[i] = ssb.getSpanEnd(mTouchedSpans[i]) - ssb.getSpanStart(mTouchedSpans[i]);
}
}
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s instanceof SpannableStringBuilder) {
SpannableStringBuilder ssb = (SpannableStringBuilder) s;
if (replacing)
return;
replacing = true;
if (mTouchedSpans != null && mTouchedSpans.length > 0)
for (int i = 0; i < mTouchedSpans.length; i++) {
int newLen = ssb.getSpanEnd(mTouchedSpans[i]) - ssb.getSpanStart(mTouchedSpans[i]);
if (newLen < mSpanLength[i]) {
ssb.replace(ssb.getSpanStart(mTouchedSpans[i]), ssb.getSpanEnd(mTouchedSpans[i]), "");
}
}
mTouchedSpans = null;
mSpanLength = null;
replacing = false;
}
}
@Override
public void afterTextChanged(Editable s) {}
}
With this,you would get the image left align and also would get cursor after the image.Try using:
mEditText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon,0, 0,0);
I am an inserting and deleting an image in EditText by this way:
Customer button Insertion:
private void addImageInEditText(Drawable drawable) {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
int selectionCursorPos = messageEditText.getSelectionStart();
messageEditText.getText().insert(selectionCursorPos, ".");
selectionCursorPos = messageEditText.getSelectionStart();
SpannableStringBuilder builder = new SpannableStringBuilder(messageEditText.getText());
int startPos = selectionCursorPos - ".".length();
builder.setSpan(new ImageSpan(drawable), startPos, selectionCursorPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
messageEditText.setText(builder);
messageEditText.setSelection(selectionCursorPos);
}
Custom button Deletion:
private void deleteImageFromEditText() {
String msgEditText = messageEditText.getText().toString();
LOGE(TAG, "text length : " + msgEditText.length());
if (msgEditText.length() > 0) {
int selectionCursorPos = messageEditText.getSelectionStart();
int endPosition = messageEditText.getText().length();
LOGE(TAG, "cursor Pos: " + selectionCursorPos + " endPosition : " + endPosition);
if (selectionCursorPos > 0) {
int deletingObjectStartPos = selectionCursorPos - 1;
messageEditText.getText().delete(deletingObjectStartPos, selectionCursorPos);
messageEditText.setSelection(deletingObjectStartPos);
}
} else {
messageEditText.setText("");
}
}
Drawable can be pass by multiple ways for testing I am doing like this:
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_filter);
addImageBetweentext(drawable);