SpannableString(Builder) is not selectable in EditText - android

I have created an EditText and added some text which contains formatting to it as in the following code:
EditText richTextView = (EditText)findViewById(R.id.rich_text);
// this is the text we'll be operating on
SpannableStringBuilder text = new SpannableStringBuilder("Lorem ipsum dolor sit amet");
// make "Lorem" (characters 0 to 5) red
text.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);
// make "ipsum" (characters 6 to 11) one and a half time bigger than the textbox
text.setSpan(new RelativeSizeSpan(1.5f), 6, 11, 0);
// make "dolor" (characters 12 to 17) display a toast message when touched
final Context context = this;
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View view) {
Toast.makeText(context, "dolor", Toast.LENGTH_LONG).show();
}
};
text.setSpan(clickableSpan, 12, 17, 0);
// make "sit" (characters 18 to 21) struck through
text.setSpan(new StrikethroughSpan(), 18, 21, 0);
// make "amet" (characters 22 to 26) twice as big, green and a link to this site.
// it's important to set the color after the URLSpan or the standard
// link color will override it.
text.setSpan(new RelativeSizeSpan(2f), 22, 26, 0);
text.setSpan(new ForegroundColorSpan(Color.GREEN), 22, 26, 0);
// make our ClickableSpans and URLSpans work
richTextView.setMovementMethod(LinkMovementMethod.getInstance());
// shove our styled text into the TextView
richTextView.setText(text, BufferType.EDITABLE);
My problem is that the text is not selectable when running the program (tried on both the emulator and my own device). If I click on any of the words except "dolor", no cursor appears, but if I type, it starts typing from before "Lorem". However, if I click "dolor", it selects the word and I can replace it (but I can't type without replacing).
I can't select any other parts of the words, and can't place the cursor where I want it (it doesn't even show up).
I am wondering how I can get normal text selection features like those that are present when using normal text instead of SpannableString or SpannableStringBuilder? (I have tried both) If I use plain text, I can select any part of any word and start inputting text from there.
Edit1
The text selection works in landscape mode, but not in portrait. So the code is valid to some degree...
Edit2
Actually text selection works in landscape mode on my phone, but not on the emulator.

Just figured it out. The problematic code was richTextView.setMovementMethod(LinkMovementMethod.getInstance());
So I just removed it. It makes the links non-responsive, but I don't really need links anyway so it's fine.
Used in this way, setMovementMethod was completely blocking selection by touch events for some reason (I'll have to dig into the source to figure out exactly why).
Note to self: Don't add code till you fully understand it.

Related

set drawable to some part text of android textview

I have text in textview "To get free recharge use "80FC" promo code.
I want to set and rectangle to background of 80FC text.
Please help!!
TextView TV = (TextView) findViewById(R.id.mytextview01);
Spannable wordtoSpan = new SpannableString("To get free recharge use \"80FC\" promo code.");
wordtoSpan.setSpan(new BackgroundColorSpan(Color.RED), 37, 41, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(wordtoSpan);
Code above should set a background of 80FC to red. I might mistaken with the index of start and end. You can play with it, and get the correct result.

Duplicate images appear in EditText after insert one ImageSpan in Android 4.x

I have below code slice to insert a bitmap into an EditText widget. With Android 5.x, it works fine, but with Android 4.x, duplicate images will show after insert one bitmap. Dose anyone know how to fix this with Android 4.x?
insertPicIntoEditText(getBitmapSpannable(resized_bm, upload_uri));
private SpannableString getBitmapSpannable(Bitmap pic, String uri_string) {
SpannableString ss = new SpannableString(uri_string);
ImageSpan span = new ImageSpan(this, pic);
ss.setSpan(span, 0, uri_string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return ss;
}
private void insertPicIntoEditText(SpannableString ss) {
Editable et = mContentEditor.getText();
int start = mContentEditor.getSelectionStart();
et.insert(start, ss);
et.insert(start + ss.length(), "\n");
mContentEditor.setText(et);
mContentEditor.setSelection(start + ss.length() + 1);
}
This was being caused by the height set in setBounds being greater than that of the Bitmap the drawable was created from earlier in the activity. When this occurs there are two things that seem to happen..
First, if the size only slightly (I haven't extensively tested this once I got it working so I'm unsure of exact figures) exceeds the size of the Bitmap then a large blank space is added to the span, this blank space is the same size as the bitmap inserted.
Second, an extra copy of the Drawable is added to the span, directly below the blank space.
The resolution was relatively simple.. Ensure that the Bitmap used to create the Drawable was set to the intended final size before creating the Drawable and calling setBounds.
This may not work in all cases but worked for me and hopefully will be helpful for someone.
I also noticed images are repeated if the spannable string has line breaks.

Editable.setSpan() on Gingerbread: start and end parameters ignored

I want to highlight two parts of the text in EditText. Here's how I do it:
EditText etOpenAnswer;
int correctPartEndIndex;
UnderlineSpan correctPartSpan=new UnderlineSpan();
StrikethroughSpan incorrectPartSpan=new StrikethroughSpan();
if (etOpenAnswer.length()>=correctPartEndIndex) {
etOpenAnswer.getText().setSpan(correctPartSpan, 0, correctPartEndIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
etOpenAnswer.getText().setSpan(incorrectPartSpan, correctPartEndIndex, etOpenAnswer.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
}
So first part of the text is from 0 to correctPartEndIndex (it is underlined), second is from correctPartEndIndex to the end (it is striked through).
Everything works as expected on ICS and later, but on 2.2 and 2.3.3 both spans are applied to the whole text (text is underlined and striked through at the same time), which makes me think start and end parameters are just ignored.
What am I doing wrong?

Text Styling in Android

I want to show user text-data opened in edittext where text is stylish. Like, some words are bold , some are italiac , lines are colored differently based on user preferences etc.. How can I show such stylish data to user ; is it possible using edittext ?
Also, is there a way I can embed CSS like quality in my app without its interaction with web. I just want to create a beautiful and colorful app. Please provide any tips. I'm too new to android.
Thanks.
You can use a Spannable String.
EditText et = (EditText) findViewById(R.id.ed);
String s= "Hello Everyone";
SpannableString ss1= new SpannableString(s);
ss1.setSpan(new RelativeSizeSpan(2f), 0,5, 0);
ss1.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);
ss1.setSpan(new StyleSpan(Typeface.ITALIC), 0, 5, 0);
ss1.setSpan(new StyleSpan(Typeface.BOLD), 0, ss1.length(), 0);
ss1.setSpan(new ForegroundColorSpan(Color.RED), 0, ss1.length(), 0);
et.append(ss1);
For more styling check the link # http://blog.stylingandroid.com/archives/177
You can use TTF files and store in your assets folder .
Typeface font = Typeface.createFromAsset(getAssets(),"Tangerine_Regular.ttf");
nametodisplay.setTypeface(font);
nametodisplay is a text view .
Try similar for edittext.I never tried it myself though.

Android TextView's subscript being clipped off

The Android TextView clips off my text subscripts (see image below) even when I use android:layout_height="wrap_content" for the TextView.
Is there a fix/work-around for this?
P/S: Superscripts work fine
Note: padding doesn't work.
I tried even adding a padding of 50dip but it did not help.
I can use an absolute height such as 50dip but that messes everything up when I need text to wrap around.
Sample Code:
mtTextView.setText(Html.fromHtml("HC0<sub>3</sub>"));
Most answers suggest to add paddings or to use smaller sub/superscripts. These might be serviceable workarounds, but they don't really solve the problem. Ideally, we want Android to take the sub/superscript into account when calculating line height. I think I found how to do it, and I'm sharing it for people googling this issue.
SpannableStringBuilder sb = new SpannableStringBuilder("X2");
sb.setSpan(new SuperscriptSpan(), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sb, BufferType.SPANNABLE);
The trick is in BufferType.SPANNABLE. Apparently it makes TextView pay more attention to the markup and calculate line heights properly.
This solution worked for me.
Superscripted text is usually made smaller when the browser renders it, that doesn't seem to happen here so you can replicate that (and solve this problem) by doing this:
someTextView.setText(Html.fromHtml("Some text<sup><small>1</small></sup>"));
For subscript a slight variation to the above suggestion is needed, two small tags:
textView.setText(Html.fromHtml(
"HCO<sub><small><small>3</small></small></sub>));
android:lineSpacingExtra="4dp" should solve it
this will add extra line spacing below your text, and keep subscript from getting cutoff. I haven't tried it with superscript so it might now fix that.
I had the same issue, so after reading the posts, I found this to be working.
Example : H2O
simply use :
textView.setText(Html.fromHtml("H<sub>2</sub>O"),BufferType.SPANNABLE);
BufferType.SPANNABLE is important as it will tell textview to consider the superscript span.
If you are using custom tag handler for HTML you can also use it like this:
textView.setText(Html.fromHtml(data, null, new CustomHtmlTagHandler(),BufferType.SPANNABLE);
Hope it helps someone looking for same problem.
I'm displaying fractions and mixed numbers so I'm using both super and subscripting together. The Html.fromHtml didn't work for me, it either clipped the top or the bottom.
Oddly, mixed numbers worked correctly, but fractions by themselves did not.
I ended up using a SpannableString with a SubscriptSpan or a SuperscriptSpan, then setting the font size in a TextAppearanceSpan.
Once I had done that I had to expand the height of the TextView as well.
TextView number = (TextView)findViewById(R.id.number);
String temp = "1 1/2";
SpannableString s = new SpannableString(temp);
// if the string has a fraction in it, superscript the numerator and subscript the denominator
if (temp.indexOf('/') != -1)
{
int len = temp.length();
s.setSpan(new SuperscriptSpan(), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 2, len - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new SubscriptSpan(), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
number.setText(s);
Then I had to expand the height:
RelativeLayout.LayoutParams parms = (RelativeLayout.LayoutParams)number.getLayoutParams();
Rect frame = CalcSize(number.getTextSize(), quantityMaxString);
parms.height = frame.height() + fractionAdjustment;
number.setLayoutParams(parms);
CalcSize returns a bounding rectangle of the largest string in the array of display elements.
fractionAdjustment is an emperically selected value that works for the selected font size adjusted for screen geometry.
Note: This is TextView is inside a ListView, so that might have some impact as well.
// calculate the field dimensions, given the font size and longest string
private static Rect CalcSize(float fontSize, String maxString)
{
Rect bounds = new Rect();
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(fontSize);
paint.getTextBounds(maxString, 0, maxString.length(), bounds);
return bounds;
}
Empirical values:
fractionAdjustment = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, resources.getDisplayMetrics());
fractionFontSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 11, resources.getDisplayMetrics());
I have faced the same issue in ICS and below android versions. I fixed the issue by a simple step
Give a minimum height to the Text View . It will fix the problem.
You can set minimum height through xml .
android:minHeight="30dp"
Or dynamically
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
tv.setMinHeight(52);
}
This worked for me along with the Small tag.
Inside the TextView add
android:paddingBottom="1dp"
Use the small Tag after the subscript
yourTextView.setText(Html.fromHtml("" +" Hey< sub >< small >2< /small > < /sub >"));
Note Please note , step 1 is important , My text was still cutting down in some case,using paddingBottom resolved it.
Don't forget to remove the spaces in sub and small tags that are present in my answer :)
The More number of <small> </small> tags in there, the smaller the subscript will get and you should be able to see it without being clipped.
Eg: H2O
Html.fromHtml("H<sub><small><small><small>2</small></small></small></sub>O");

Categories

Resources