I cannot for the life of me understand why this simple code to set a spannable string is not working on this textview. The method below adds a "Today" marker, which should be in green, before the text displaying the date if the date is the current day.
private void setTimeTextView(String timeString) {
Calendar c = Calendar.getInstance();
String todaysDateString = ApiContentFormattingUtil.getFullDateFormat(c.getTime());
if (timeString.equals(todaysDateString)){
String todayText = getResources().getString(R.string.today_marker);
Spannable timeSpannable = new SpannableString(todayText + timeString);
timeSpannable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.greenish_teal)), 0,
todayText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mDateTime.setText(timeSpannable);
} else {
mDateTime.setText(timeString);
}
}
However, the color won't change.
Here is the XML for this view
<TextView
android:id="@+id/newsfeed_date_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="23dp"
android:textSize="12sp"
android:textColor="@color/white_three"
android:letterSpacing="0.06"
app:fontPath="@string/opensans_bold_path"
tools:text="Monday, January 1st"
android:textAllCaps="true"
tools:ignore="MissingPrefix"
tools:targetApi="lollipop"/>
Use the Spannable. SPAN_EXCLUSIVE_INCLUSIVE flag to include inserted text, and use Spannable. SPAN_EXCLUSIVE_EXCLUSIVE to exclude the inserted text. val spannable = SpannableStringBuilder("Text is spantastic!")
Spans can also be used to change TextPaint properties, draw on Canvas, and even change the text layout. In order to use spans, we have to use one of the classes listed below. Class. Mutable Text. Mutable Markup.
gpetuhov/textview_limit_text. txt. This will limit number of lines to 1 and if text exceeds limit, TextView will display ... in the end of line.
On versions prior to Oreo, the android:textAllCaps="true"
attribute setting will cause the formatting spans to be stripped from your text. You'll need to remove that setting (or set it to false
), and handle the conversion to upper case yourself, before creating your SpannableString
from it. For example:
String todayText = getResources().getString(R.string.today_marker);
String text = todayText + timeString;
Spannable timeSpannable = new SpannableString(text.toUpperCase());
This is due to a known bug in the platform AllCapsTransformationMethod
class, which on versions Nougat 7.1 and below handles the text as a flat String
, basically stripping any formatting spans you may have set.
Unfortunately, the support/androidx libraries also use the platform AllCapsTransformationMethod
class, so this will happen for their textAllCaps
attributes, as well; i.e., app:textAllCaps
is broken pre-Oreo, too.
As indicated, this was corrected in Oreo, so this manual fix isn't strictly necessary on those newer versions. However, if you are still supporting pre-Oreo versions, it might be easier to just leave it off and handle the capitalization manually everywhere, rather than having to account for two different setups in your resources and code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With