Android: Textview cannot be unbolded/italcized - android

A TextView is displayed in one activity and the user goes to another activity to edit the properties of the text such as color, size, bold, italics, and underlined. When the user chooses to make the text bold, italic, or bold_italic it works. If the user unselects the checkbox the TextView does not return to normal. It can shift between the styles (ie if I check bold, then uncheck bold and check italic the TextView will be italic, not bold) but it cannot have a normal TypeFace.
I've searched around and everything I've found says that using the setTypeface method with Typeface.NORMAL should work but it is not working.
I would appreciate some help in solving this. The relevant code is below. Thank you!
TextView mDisplayMessage = (TextView) findViewById(R.id.message);
mDisplayMessage.setTypeface(mDisplayMessage.getTypeface(), Typeface.NORMAL);
//TODO: Cannot return all the way back to normal. Remains bold/italic/bold_italic
if (mIsBold && mIsItalic) mDisplayMessage.setTypeface(mDisplayMessage.getTypeface(), Typeface.BOLD_ITALIC);
else if (mIsBold) mDisplayMessage.setTypeface(mDisplayMessage.getTypeface(), Typeface.BOLD);
else if (mIsItalic) mDisplayMessage.setTypeface(mDisplayMessage.getTypeface(), Typeface.ITALIC);
else mDisplayMessage.setTypeface(mDisplayMessage.getTypeface(), Typeface.NORMAL);
if (mIsUnderlined) {
mDisplayMessage.setPaintFlags(mDisplayMessage.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
} else {
mDisplayMessage.setPaintFlags(0);
}

If you didn't care about font family you can use
mDisplayMessage.setTypeface(Typeface.DEFAULT);
Because Typeface.DEFAULT change the font family(serif, sans-serif, monospace), but the below can keep the same font family with style changed.
Typeface typeface = mDisplayMessage.getTypeface();
int style = Typeface.NORMAL;
if(mIsBold && mIsItalic) {
style = Typeface.BOLD_ITALIC;
} else if(mIsBold) {
style = Typeface.BOLD;
} else if(mIsItalic) {
style = Typeface.ITALIC;
}
Typeface newTypeface = Typeface.create(typeface, style);
mDisplayMessage.setTypeface(newTypeface);

Try this,
mDisplayMessage.setTypeface(Typeface.DEFAULT);
OR
mDisplayMessage.setTypeface(null, Typeface.NORMAL);

Related

Cannot toggle TextView style dynamically

In my project, I need to toggle TextView style to Normal and Bold. Here is the code:
mTitleTextView.setTypeface(mTitleTextView.getTypeface(), letterItem.isRead() ? Typeface.NORMAL : Typeface.BOLD);
This works good when TextView is not bold. But when current state is bold, it doesn't return to normal state.
mTitleTextView.setTypeface(null, letterItem.isRead() ? Typeface.NORMAL : Typeface.BOLD);
Above line fixes the problem, but I have used custom font and passing null for current typeface removes the font.
After tying for a while this works for me :
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textView.invalidate();
if(isCliked){
isCliked = false;
Typeface face=Typeface.createFromAsset(getAssets(), "test.ttf");
textView.setTypeface(face,Typeface.NORMAL);
}
else{
Typeface face=Typeface.createFromAsset(getAssets(), "test.ttf");
textView.setTypeface(face, Typeface.BOLD);
isCliked = true;
}
Log.i("MainActivity", "onClick: "+isCliked);
}
});
the typeface will remain the same, and change only bold and normal

Android unicode u23F8 (pause symbol) color

I can't change color of the u23F8 (pause symbol).
play symbol looks ok and I can change its color
playPauseButton = new Button(mContext);
playPauseButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 72);
playPauseButton.setTextColor(Color.WHITE);
...
if (mPlayer.isPlaying()) {
playPauseButton.setText("\u23F8");
} else {
playPauseButton.setText("\u25B6")
}
The TextView font renders \u23F8 and \u25B6 as an emoji, which means it basically uses a predefined image, so font colors are ignored on these.

Change text edit error notification font in android

I know we can change edit text font by using Typeface. But what about errors we set for edit text?
Look at codes below:
Typeface font = Typeface.createFromAsset(getAssets(), "fonts/ATaha.ttf");
private EditText mPasswordView;
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setTypeface(font);
With this code I could only change edit text font but when I set error like this:
mPasswordView.setError(getString(R.string.error_field_required));
The error notification font is android default font and didn't change by using type face. How can I change that?
You can use a SpannableString to set the font:
SpannableString s = new SpannableString(errorString);
s.setSpan(new TypefaceSpan(font), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mPasswordView.setError(s);
A custom Span class that has a specific Typeface set:
public class TypefaceSpan extends MetricAffectingSpan {
private Typeface mTypeface;
public TypefaceSpan(Typeface typeface) {
mTypeface = typeface;
}
#Override
public void updateMeasureState(TextPaint p) {
p.setTypeface(mTypeface);
p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
#Override
public void updateDrawState(TextPaint tp) {
tp.setTypeface(mTypeface);
tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
}
Since you can't directly set a Typeface for error text, you can achieve it by setting an HTML string as a text inside it.
You can see HTML Tags supported by a TextView in The CommonsBlog
We have face attribute for font, which means you can change the font-family.
mPasswordView.setError(Html.fromHtml("<font face='MONOSPACE'>Error font is MONOSPACE</font>"));
By setting spannable string in error message or extend EditText and overrite your own error draw mechanism.

How to support italic font and bold font for Chinese

My android application will use Chinese. The regular font is OK, but the italic font and bold font does not work.
So which font files should I use for Chinese italic and bold font?
I assume you are using TextView to show Chinese words.
If you want the whatever words in TextView to be bold or italic, it would be easy.
Just use
testView.getPaint().setFakeBoldText(true);
to make all words bold.
For italic, use:
testView.getPaint().setTextSkewX(-0.25f);
However, if you only want some words to be bold or italic. Normally you can set StyleSpan on specific range of your Spannablebut it is not work on Chinese word.
Therefore, I suggest you create a class extends StyleSpan
public class ChineseStyleSpan extends StyleSpan{
public ChineseStyleSpan(int src) {
super(src);
}
public ChineseStyleSpan(Parcel src) {
super(src);
}
#Override
public void updateDrawState(TextPaint ds) {
newApply(ds, this.getStyle());
}
#Override
public void updateMeasureState(TextPaint paint) {
newApply(paint, this.getStyle());
}
private static void newApply(Paint paint, int style){
int oldStyle;
Typeface old = paint.getTypeface();
if(old == null)oldStyle =0;
else oldStyle = old.getStyle();
int want = oldStyle | style;
Typeface tf;
if(old == null)tf = Typeface.defaultFromStyle(want);
else tf = Typeface.create(old, want);
int fake = want & ~tf.getStyle();
if ((want & Typeface.BOLD) != 0)paint.setFakeBoldText(true);
if ((want & Typeface.ITALIC) != 0)paint.setTextSkewX(-0.25f);
//The only two lines to be changed, the normal StyleSpan will set you paint to use FakeBold when you want Bold Style but the Typeface return say it don't support it.
//However, Chinese words in Android are not bold EVEN THOUGH the typeface return it can bold, so the Chinese with StyleSpan(Bold Style) do not bold at all.
//This Custom Class therefore set the paint FakeBold no matter typeface return it can support bold or not.
//Italic words would be the same
paint.setTypeface(tf);
}
}
Set this span to your Chinese words and I should be work.
Be aware to check it is only set on Chinese words only. I have not test on it but I can imagine that set fakebold on a bold English characters would be very ugly.
I'd suggest you don't use bold and italic fonts when displaying chinese text.
Bold is likely to distort the text and italic will only artificially skew the text.

How to set the font style to bold, italic and underlined in an Android TextView?

I want to make a TextView's content bold, italic and underlined. I tried the following code and it works, but doesn't underline.
<Textview android:textStyle="bold|italic" ..
How do I do it? Any quick ideas?
This should make your TextView bold, underlined and italic at the same time.
strings.xml
<resources>
<string name="register"><u><b><i>Copyright</i></b></u></string>
</resources>
To set this String to your TextView, do this in your main.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/register" />
or In JAVA,
TextView textView = new TextView(this);
textView.setText(R.string.register);
Sometimes the above approach will not be helpful when you might have to use Dynamic Text. So in that case SpannableString comes into action.
String tempString="Copyright";
TextView text=(TextView)findViewById(R.id.text);
SpannableString spanString = new SpannableString(tempString);
spanString.setSpan(new UnderlineSpan(), 0, spanString.length(), 0);
spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0);
spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, spanString.length(), 0);
text.setText(spanString);
OUTPUT
I don't know about underline, but for bold and italic there is "bolditalic". There is no mention of underline here: http://developer.android.com/reference/android/widget/TextView.html#attr_android:textStyle
Mind you that to use the mentioned bolditalic you need to, and I quote from that page
Must be one or more (separated by '|') of the following constant values.
so you'd use bold|italic
You could check this question for underline: Can I underline text in an android layout?
Or just like this in Kotlin:
val tv = findViewById(R.id.textViewOne) as TextView
tv.setTypeface(null, Typeface.BOLD_ITALIC)
// OR
tv.setTypeface(null, Typeface.BOLD or Typeface.ITALIC)
// OR
tv.setTypeface(null, Typeface.BOLD)
// OR
tv.setTypeface(null, Typeface.ITALIC)
// AND
tv.paintFlags = tv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Or in Java:
TextView tv = (TextView)findViewById(R.id.textViewOne);
tv.setTypeface(null, Typeface.BOLD_ITALIC);
// OR
tv.setTypeface(null, Typeface.BOLD|Typeface.ITALIC);
// OR
tv.setTypeface(null, Typeface.BOLD);
// OR
tv.setTypeface(null, Typeface.ITALIC);
// AND
tv.setPaintFlags(tv.getPaintFlags()|Paint.UNDERLINE_TEXT_FLAG);
Keep it simple and in one line :)
For bold and italic whatever you are doing is correct for underscore use following code
HelloAndroid.java
package com.example.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.widget.TextView;
public class HelloAndroid extends Activity {
TextView textview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textview = (TextView)findViewById(R.id.textview);
SpannableString content = new SpannableString(getText(R.string.hello));
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textview.setText(content);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/hello"
android:textStyle="bold|italic"/>
string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, HelloAndroid!</string>
<string name="app_name">Hello, Android</string>
</resources>
This is an easy way to add an underline, while maintaining other settings:
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
Programmatialy:
You can do programmatically using setTypeface() method:
Below is the code for default Typeface
textView.setTypeface(null, Typeface.NORMAL); // for Normal Text
textView.setTypeface(null, Typeface.BOLD); // for Bold only
textView.setTypeface(null, Typeface.ITALIC); // for Italic
textView.setTypeface(null, Typeface.BOLD_ITALIC); // for Bold and Italic
and if you want to set custom Typeface:
textView.setTypeface(textView.getTypeface(), Typeface.NORMAL); // for Normal Text
textView.setTypeface(textView.getTypeface(), Typeface.BOLD); // for Bold only
textView.setTypeface(textView.getTypeface(), Typeface.ITALIC); // for Italic
textView.setTypeface(textView.getTypeface(), Typeface.BOLD_ITALIC); // for Bold and Italic
XML:
You can set Directly in XML file in like:
android:textStyle="normal"
android:textStyle="normal|bold"
android:textStyle="normal|italic"
android:textStyle="bold"
android:textStyle="bold|italic"
If you are reading that text from a file or from the network.
You can achieve it by adding HTML tags to your text like mentioned
This text is <i>italic</i> and <b>bold</b>
and <u>underlined</u> <b><i><u>bolditalicunderlined</u></b></i>
and then you can use the HTML class that processes HTML strings into displayable styled text.
// textString is the String after you retrieve it from the file
textView.setText(Html.fromHtml(textString));
Without quotes works for me:
<item name="android:textStyle">bold|italic</item>
You can achieve it easily by using Kotlin's buildSpannedString{} under its core-ktx dependency.
val formattedString = buildSpannedString {
append("Regular")
bold { append("Bold") }
italic { append("Italic") }
underline { append("Underline") }
bold { italic {append("Bold Italic")} }
}
textView.text = formattedString
Just one line of code in xml
android:textStyle="italic"
style="?android:attr/listSeparatorTextViewStyle
by making this style, u can achieve underlining

Categories

Resources