android ImageSpan setBounds when use lineSpacingExtra in Textview - android

i want to add ImageSpan in textview and every thing is ok with this code :
final SpannableStringBuilder sb = new SpannableStringBuilder();
MyAyehNumber Tag1 = new MyAyehNumber(My_Context, null);
Tag1.set_tagtitle(Title);
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(Tag1);
int dWidth = bd.getIntrinsicWidth();
int dHeight = bd.getIntrinsicHeight();
bd.setBounds(0,0, dWidth,dHeight);
ImageSpan mImageSpan= new ImageSpan(bd);
sb.append(contactName);
sb.setSpan(mImageSpan, sb.length()-(contactName.length()), sb.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Txt_Ayeh.append(sb);
but when i set android:lineSpacingExtra for Textview... ImageSpan is located below of text !
how can set bounds to center ???
tnx

Related

Prevent typing in SearchView before SpannableString

Inside android SearchView i made a TextView and added "This Site" to it then converted the view to bitmap and added span using a shape drawable.
I dont want my cursor to type before the Span and setSelection doesn't seems to work for me
final SearchView sv = new SearchView(getActivity());
final String tokenName = "This Site";
final SpannableStringBuilder sb = new SpannableStringBuilder();
TextView tv = createSearchTokenTextView(tokenName);
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(0, 0, bd.getIntrinsicWidth(), bd.getIntrinsicHeight());
sb.append(tokenName + " ");
sb.setSpan(new ImageSpan(bd), sb.length() - (tokenName.length() + 1), sb.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Selection.setSelection(sb, 0, sb.toString().length());
sv.setQuery(sb, false);

EditText is too slow when there are many ImageSpan in it

I want to customize EditText's behavior like HandRite.
So I tried examing EditText's editing performance when there are many ImageSpan, but it was too slow when adding or deleting character on middle using touch screen and IME after below code.
How can I speed up this performance?
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(' ');
}
SpannableString ss = new SpannableString(sb.toString());
Random random = new Random();
for (int i = 0; i < 1000; i++) {
Drawable d = new ColorDrawable(random.nextInt());
d.setBounds(0, 0, mEditText.getLineHeight(), mEditText.getLineHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mEditText.setText(ss);
HandRite's behavior
Since the number of ImageSpan objects are very large almost 1000 in your SpannableString which is causing it getting slow.
Try to use HTML teext along with ImageGetter and check peformance :
ImageGetter imageGetter = new ImageGetter() {
public Drawable getDrawable(String source) {
StringTokenizer st = new StringTokenizer(index, ".");
Drawable d = new BitmapDrawable(getResources(),emoticons[Integer.parseInt(st.nextToken()) - 1]);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
};
Spanned cs = Html.fromHtml("<img src ='"+ index +"'/>", imageGetter, null);

how set margin between spannable textview?

I am trying to create spannable textview and showing it in EditText. So user can type something in EditText and if user pressed enter button of keyboard then i am converting this text in to spannable textview after this user can start typing again and press enter button of keyboard then again second spannable textview will create ans will show it in edittext but.
Where i stuck?
when i create two spannable textview then this two textview slightly overlapping on each other. And i want to set margin between this two textview.
I also tried to set margin between textview using LayoutParam but not success.
Here is image which showing textview overlapping on each other in EditText.
y of spicy is hidden below tasty
Here is my code.
txtDishTags.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_GO) {
txtDishTags.dismissDropDown();
if(txtDishTags.getText().toString().trim().length()>=1){
isEntered = true;
String[] separated = tags.split(",");
tags = separated[separated.length-1];
if(tags.trim().length()>=1){
TextView tv = createContactTextView(tags);
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(-20, 0, bd.getIntrinsicWidth(),
bd.getIntrinsicHeight());
sb.append(tags + ",");
sb1 = new SpannableStringBuilder();
sb1.append(tags + ",");
sb.setSpan(new ImageSpan(bd),
sb.length() - tags.length(), sb.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(clickSpan, sb.length() - tags.length(),
sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
txtDishTags.setText("");
txtDishTags.setText(sb);
int length = sb.length();
txtDishTags.setSelection(length, length);
}
}
}
return false;
}
});
public TextView createContactTextView(String text) {
//llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 44);
//llp.setMargins(5, 0, 20, 0);
TextView tv = new TextView(this);
tv.setText(text);
tv.setTextSize(30);
Typeface faceBook = Typeface.createFromAsset(getAssets(),
"fonts/eau_sans_book.otf");
tv.setTypeface(faceBook);
tv.setTextColor(getResources().getColor(R.color.backgroundcolor));
tv.setBackgroundResource(R.color.textviewbubble);
//tv.setLayoutParams(llp);
Resources r = getResources();
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
44, r.getDisplayMetrics());
tv.setHeight(px);
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);
}
I tried to set margin between textview using following code
llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 44);
llp.setMargins(5, 0, 20, 0);
tv.setLayoutParams(llp);
I also set LeftPadding for Textview but seems first textview not getting it.Even i set height to textview but seems textview not getting layout parameter at all. Like
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
44, r.getDisplayMetrics());
tv.setHeight(px);
Please give reference or hint.
Thanks in advance
There are a few problems that I have identified. You need to make the specified changes and everything should work.
Step 1) Update setBounds parameters
In the following line, update the setBounds parameters from -20 to 0 as follows:
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(0, 0, bd.getIntrinsicWidth(), bd.getIntrinsicHeight());
This is important because you are setting the wrong bounds, which causes tags to overlap.
Step 2) Fix bug in sb.setSpan
If you followed step 1, and you run the code, you will realize that when you attempt to replace text with ImageSpan, you are passing the wrong values (you are not taking into account the ","(comma) character in the end). Update the following line to include -1:
sb.setSpan(new ImageSpan(bd), sb.length() - tags.length() - 1, sb.length() - 1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Now you output will appear correct and with comma in the middle.
Step 3) Add spacing between Tags
To answer your original question, how to add spacing, I would recommend that you modify your code to include ", " between different spans. You can also modify it to use just " " space. Define a contentBetweenTags variable and set it to your desired value. Here is how you can do that:
String contentBetweenTags = ", ";
sb.append(tags + contentBetweenTags);
sb1 = new SpannableStringBuilder();
sb1.append(tags + contentBetweenTags);
sb.setSpan(new ImageSpan(bd),
sb.length() - tags.length() - contentBetweenTags.length(),
sb.length() - contentBetweenTags.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Step 4) Picking the right "space" character
Just in case you are not happy with the "margin/spacing" between two tags, you could use one of the many unicode space characters available. They have different widths and you could use any one of them based on your desire / liking.
Here is the final code and sample screenshot using unicode \u2002:
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(0, 0, bd.getIntrinsicWidth(), bd.getIntrinsicHeight());
String contentBetweenTags = ",\u2002";
sb.append(tags + contentBetweenTags);
sb1 = new SpannableStringBuilder();
sb1.append(tags + contentBetweenTags);
sb.setSpan(new ImageSpan(bd),
sb.length() - tags.length() - contentBetweenTags.length(),
sb.length() - contentBetweenTags.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Drawable in string resource

I want to show AlertDialog that shows its message with string and icons together.
Is it possible to insert icons/images/drawables in string resource? Is there any way to show drawables with the string in the AlertDialog.
EDIT
If its was not clear, the drawables need to be inside the string. like "click the icon [icon-image] and then click on..."
SpannableString spannableString = new SpannableString("#");
Drawable d = getResources().getDrawable(R.drawable.your_drawable);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);
spannableString.setSpan(span, spannableString.toString().indexOf("#"), spannableString.toString().indexOf("#")+1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
yourTextView.setText(spannableString);
The AlertDialog.Builder class has a method setIcon(int iconRes) or setIcon(Drawable icon) that you can use for this.
EDIT:
If you need it in the middle of the string, you could use an ImageSpan:
String src = "Here's an icon: # isn't it nice?";
SpannableString str = new SpannableString(src);
int index = str.indexOf("#");
str.setSpan(new ImageSpan(getResources().getDrawable(R.drawable.my_icon), index, index + 1, ImageSpan.ALIGN_BASELINE));
AlertDialog.Builder x = new AlertDialog.Builder(myContext);
x.setMessage(str);
You can use custom view or custom title with ImageView or TextView containing compound drawables.

Align bitmap in SpannableStringBuilder

How can I align a bitmap to the text in a SpannableString?
SpannableStringBuilder ssb = new SpannableStringBuilder(arr_messages.get(position));
String msg1 = ssb.toString();
for (int i=0; i<smileys.length; i++)
{
if (msg1.indexOf(smileys[i]) > 0)
{
int t = msg1.indexOf(smileys[i]);
ssb.setSpan(new ImageSpan(bitmapArray.get(i)), t, t+2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
holder.txtName.setText(ssb, BufferType.SPANNABLE);
I would like to demonstrate the problem with these images:
What I want is to center both the text and the image vertically (the text is ok, but the image screws it up).
The result is:
Try ...new ImageSpan(bitmapArray.get(i), ImageSpan.ALIGN_BASELINE)...!

Categories

Resources