List of usage examples for android.text SpannableStringBuilder setSpan
public void setSpan(Object what, int start, int end, int flags)
From source file:org.kontalk.ui.view.ConversationListItem.java
public final void bind(Context context, final Conversation conv) { mConversation = conv;//from w w w .j a v a 2 s.c om setChecked(false); Contact contact; // used for the conversation subject: either group subject or contact name String recipient = null; if (mConversation.isGroupChat()) { recipient = mConversation.getGroupSubject(); if (TextUtils.isEmpty(recipient)) recipient = context.getString(R.string.group_untitled); loadAvatar(null); } else { contact = mConversation.getContact(); if (contact != null) { recipient = contact.getDisplayName(); } if (recipient == null) { if (BuildConfig.DEBUG) { recipient = conv.getRecipient(); } else { recipient = context.getString(R.string.peer_unknown); } } loadAvatar(contact); } SpannableStringBuilder from = new SpannableStringBuilder(recipient); if (conv.getUnreadCount() > 0) from.setSpan(STYLE_BOLD, 0, from.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); // draft indicator int lastpos = from.length(); String draft = conv.getDraft(); if (draft != null) { from.append(" "); from.append(context.getResources().getString(R.string.has_draft)); from.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_color_draft)), lastpos, from.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } mFromView.setText(from); mDateView.setText(MessageUtils.formatTimeStampString(context, conv.getDate())); mSticky.setVisibility(conv.isSticky() ? VISIBLE : GONE); // error indicator int resId = -1; int statusId = -1; switch (conv.getStatus()) { case Messages.STATUS_SENDING: // use pending icon even for errors case Messages.STATUS_ERROR: case Messages.STATUS_PENDING: case Messages.STATUS_QUEUED: resId = R.drawable.ic_msg_pending; statusId = R.string.msg_status_sending; break; case Messages.STATUS_SENT: resId = R.drawable.ic_msg_sent; statusId = R.string.msg_status_sent; break; case Messages.STATUS_RECEIVED: resId = R.drawable.ic_msg_delivered; statusId = R.string.msg_status_delivered; break; // here we use the error icon case Messages.STATUS_NOTACCEPTED: resId = R.drawable.ic_thread_error; statusId = R.string.msg_status_notaccepted; break; case Messages.STATUS_NOTDELIVERED: resId = R.drawable.ic_msg_notdelivered; statusId = R.string.msg_status_notdelivered; break; } // no matching resource or draft - hide status icon boolean incoming = resId < 0; if (incoming || draft != null) { mErrorIndicator.setVisibility(GONE); int unread = mConversation.getUnreadCount(); if (unread > 0) { mCounterView.setText(String.valueOf(unread)); mCounterView.setVisibility(VISIBLE); } else { mCounterView.setVisibility(GONE); } } else { mCounterView.setVisibility(GONE); mErrorIndicator.setVisibility(VISIBLE); mErrorIndicator.setImageResource(resId); mErrorIndicator.setContentDescription(getResources().getString(statusId)); } CharSequence text; // last message or draft?? if (conv.getRequestStatus() == Threads.REQUEST_WAITING) { text = new SpannableString(context.getString(R.string.text_invitation_info)); ((Spannable) text).setSpan(STYLE_ITALIC, 0, text.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } else { String subject = conv.getSubject(); String source = (draft != null) ? draft : subject; if (source != null) { if (GroupCommandComponent.supportsMimeType(conv.getMime()) && draft == null) { if (incoming) { // content is in a special format GroupThreadContent parsed = GroupThreadContent.parseIncoming(subject); subject = parsed.command; } text = new SpannableString( GroupCommandComponent.getTextContent(getContext(), subject, incoming)); ((Spannable) text).setSpan(STYLE_ITALIC, 0, text.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } else { if (incoming && conv.isGroupChat()) { // content is in a special format GroupThreadContent parsed = GroupThreadContent.parseIncoming(subject); contact = parsed.sender != null ? Contact.findByUserId(context, parsed.sender) : null; source = parsed.command; String displayName = null; if (contact != null) displayName = contact.getDisplayName(); if (displayName == null) { if (BuildConfig.DEBUG) { displayName = conv.getRecipient(); } else { displayName = context.getString(R.string.peer_unknown); } } if (source == null) { // determine from mime type source = CompositeMessage.getSampleTextContent(conv.getMime()); } text = new SpannableString(displayName + ": " + source); ((Spannable) text).setSpan(STYLE_ITALIC, 0, displayName.length() + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } else { text = source; } } } else if (conv.isEncrypted()) { text = context.getString(R.string.text_encrypted); } else { // determine from mime type text = CompositeMessage.getSampleTextContent(conv.getMime()); } } if (conv.getUnreadCount() > 0) { text = new SpannableString(text); ((Spannable) text).setSpan(STYLE_BOLD, 0, text.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } mSubjectView.setText(text); }
From source file:org.mozilla.gecko.home.ReadingListPanel.java
private void updateUiFromCursor(Cursor c) { // We delay setting the empty view until the cursor is actually empty. // This avoids image flashing. if ((c == null || c.getCount() == 0) && mEmptyView == null) { final ViewStub emptyViewStub = (ViewStub) mTopView.findViewById(R.id.home_empty_view_stub); mEmptyView = emptyViewStub.inflate(); final TextView emptyHint = (TextView) mEmptyView.findViewById(R.id.home_empty_hint); if (HardwareUtils.isLowMemoryPlatform()) { emptyHint.setVisibility(View.GONE); } else {/*from w ww . j av a 2 s. c om*/ String readingListHint = emptyHint.getText().toString(); // Use an ImageSpan to include the reader icon in the "Tip". int imageSpanIndex = readingListHint.indexOf(MATCH_STRING); if (imageSpanIndex != -1) { final ImageSpan readingListIcon = new ImageSpan(getActivity(), R.drawable.reader_cropped, ImageSpan.ALIGN_BOTTOM); final SpannableStringBuilder hintBuilder = new SpannableStringBuilder(readingListHint); // Add additional spacing. hintBuilder.insert(imageSpanIndex + MATCH_STRING.length(), " "); hintBuilder.insert(imageSpanIndex, " "); // Add icon. hintBuilder.setSpan(readingListIcon, imageSpanIndex + 1, imageSpanIndex + MATCH_STRING.length() + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); emptyHint.setText(hintBuilder, TextView.BufferType.SPANNABLE); } } mList.setEmptyView(mEmptyView); } }
From source file:com.keylesspalace.tusky.activity.MainActivity.java
private void setupSearchView() { searchView.attachNavigationDrawerToMenuButton(drawer.getDrawerLayout()); searchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() { @Override/*from w w w .java2s . c o m*/ public void onSearchTextChanged(String oldQuery, String newQuery) { if (!oldQuery.equals("") && newQuery.equals("")) { searchView.clearSuggestions(); return; } if (newQuery.length() < 3) { return; } searchView.showProgress(); mastodonAPI.searchAccounts(newQuery, false, 5).enqueue(new Callback<List<Account>>() { @Override public void onResponse(Call<List<Account>> call, Response<List<Account>> response) { if (response.isSuccessful()) { searchView.swapSuggestions(response.body()); searchView.hideProgress(); } else { searchView.hideProgress(); } } @Override public void onFailure(Call<List<Account>> call, Throwable t) { searchView.hideProgress(); } }); } }); searchView.setOnSearchListener(new FloatingSearchView.OnSearchListener() { @Override public void onSuggestionClicked(SearchSuggestion searchSuggestion) { Account accountSuggestion = (Account) searchSuggestion; Intent intent = new Intent(MainActivity.this, AccountActivity.class); intent.putExtra("id", accountSuggestion.id); startActivity(intent); } @Override public void onSearchAction(String currentQuery) { } }); searchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() { @Override public void onBindSuggestion(View suggestionView, ImageView leftIcon, TextView textView, SearchSuggestion item, int itemPosition) { Account accountSuggestion = ((Account) item); Picasso.with(MainActivity.this).load(accountSuggestion.avatar) .placeholder(R.drawable.avatar_default).into(leftIcon); String searchStr = accountSuggestion.getDisplayName() + " " + accountSuggestion.username; final SpannableStringBuilder str = new SpannableStringBuilder(searchStr); str.setSpan(new StyleSpan(Typeface.BOLD), 0, accountSuggestion.getDisplayName().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(str); textView.setMaxLines(1); textView.setEllipsize(TextUtils.TruncateAt.END); } }); }
From source file:com.softminds.matrixcalculator.dialog_activity.FunctionMaker.java
private SpannableStringBuilder ConvertToExponent(String s) { //This Function makes the Normal text into Exponents and base, position being the index of exponent int position = s.indexOf("x") + 1; SpannableStringBuilder builder = new SpannableStringBuilder(s); builder.setSpan(new SuperscriptSpan(), position, position + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan(new RelativeSizeSpan(0.50f), position, position + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return builder; }
From source file:com.gh4a.fragment.RepositoryFragment.java
private void fillData() { TextView tvRepoName = (TextView) mContentView.findViewById(R.id.tv_repo_name); SpannableStringBuilder repoName = new SpannableStringBuilder(); repoName.append(mRepository.getOwner().getLogin()); repoName.append("/"); repoName.append(mRepository.getName()); repoName.setSpan(new IntentSpan(tvRepoName.getContext()) { @Override/* www .ja v a2 s .c o m*/ protected Intent getIntent() { return IntentUtils.getUserActivityIntent(getActivity(), mRepository.getOwner()); } }, 0, mRepository.getOwner().getLogin().length(), 0); tvRepoName.setText(repoName); tvRepoName.setMovementMethod(UiUtils.CHECKING_LINK_METHOD); TextView tvParentRepo = (TextView) mContentView.findViewById(R.id.tv_parent); if (mRepository.isFork() && mRepository.getParent() != null) { Repository parent = mRepository.getParent(); tvParentRepo.setVisibility(View.VISIBLE); tvParentRepo.setText( getString(R.string.forked_from, parent.getOwner().getLogin() + "/" + parent.getName())); tvParentRepo.setOnClickListener(this); tvParentRepo.setTag(parent); } else { tvParentRepo.setVisibility(View.GONE); } fillTextView(R.id.tv_desc, 0, mRepository.getDescription()); fillTextView(R.id.tv_language, R.string.repo_language, mRepository.getLanguage()); fillTextView(R.id.tv_url, 0, !StringUtils.isBlank(mRepository.getHomepage()) ? mRepository.getHomepage() : mRepository.getHtmlUrl()); mContentView.findViewById(R.id.cell_stargazers).setOnClickListener(this); mContentView.findViewById(R.id.cell_forks).setOnClickListener(this); mContentView.findViewById(R.id.cell_pull_requests).setOnClickListener(this); mContentView.findViewById(R.id.tv_contributors_label).setOnClickListener(this); mContentView.findViewById(R.id.other_info).setOnClickListener(this); mContentView.findViewById(R.id.tv_releases_label).setOnClickListener(this); Permissions permissions = mRepository.getPermissions(); updateClickableLabel(R.id.tv_collaborators_label, permissions != null && permissions.hasPushAccess()); updateClickableLabel(R.id.tv_downloads_label, mRepository.isHasDownloads()); updateClickableLabel(R.id.tv_wiki_label, mRepository.isHasWiki()); TextView tvStargazersCount = (TextView) mContentView.findViewById(R.id.tv_stargazers_count); tvStargazersCount.setText(String.valueOf(mRepository.getWatchers())); TextView tvForksCount = (TextView) mContentView.findViewById(R.id.tv_forks_count); tvForksCount.setText(String.valueOf(mRepository.getForks())); LinearLayout llIssues = (LinearLayout) mContentView.findViewById(R.id.cell_issues); if (mRepository.isHasIssues()) { llIssues.setVisibility(View.VISIBLE); llIssues.setOnClickListener(this); // value will be filled when PR count arrives } else { llIssues.setVisibility(View.GONE); } mContentView.findViewById(R.id.tv_private) .setVisibility(mRepository.isPrivate() ? View.VISIBLE : View.GONE); }
From source file:com.heath_bar.tvdb.EpisodeDetails.java
/** Update the GUI with the specified rating */ private void setUserRatingTextView(int rating) { TextView ratingTextView = (TextView) findViewById(R.id.rating); String communityRatingText = myEpisode.getRating() + " / 10"; String ratingTextA = communityRatingText + " ("; String ratingTextB = (rating == 0) ? "rate" : String.valueOf(rating); String ratingTextC = ")"; int start = ratingTextA.length(); int end = ratingTextA.length() + ratingTextB.length(); SpannableStringBuilder ssb = new SpannableStringBuilder(ratingTextA + ratingTextB + ratingTextC); ssb.setSpan(new NonUnderlinedClickableSpan() { @Override/*from w w w . j ava2 s . c o m*/ public void onClick(View v) { showRatingDialog(); } }, start, end, 0); ssb.setSpan(new TextAppearanceSpan(getApplicationContext(), R.style.episode_link), start, end, 0); // Set the style of the text ratingTextView.setText(ssb, BufferType.SPANNABLE); ratingTextView.setMovementMethod(LinkMovementMethod.getInstance()); }
From source file:org.amahi.anywhere.adapter.ServerFilesAdapter.java
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { final ServerFileViewHolder fileHolder = (ServerFileViewHolder) holder; final ServerFile file = filteredFiles.get(position); if (Mimes.match(file.getMime()) == Mimes.Type.DIRECTORY) { fileHolder.moreInfo.setVisibility(View.GONE); fileHolder.moreOptions.setVisibility(View.GONE); } else {//from w w w. j av a 2 s. c o m fileHolder.moreInfo.setVisibility(View.VISIBLE); fileHolder.moreOptions.setVisibility(View.VISIBLE); if (!isOfflineMode()) { fileHolder.fileSize.setText(Formatter.formatFileSize(context, getFileSize(file))); } else { if (isFileDownloading(fileHolder, file, position)) { fileHolder.moreInfo.setVisibility(View.GONE); fileHolder.progressBar.setVisibility(View.VISIBLE); } else { fileHolder.moreInfo.setVisibility(View.VISIBLE); fileHolder.progressBar.setVisibility(View.GONE); File localFile = new File(context.getFilesDir(), Downloader.OFFLINE_PATH + "/" + file.getName()); fileHolder.fileSize.setText(Formatter.formatFileSize(context, localFile.length())); } } Date d = getLastModified(file); SimpleDateFormat dt = new SimpleDateFormat("EEE LLL dd yyyy", Locale.getDefault()); fileHolder.fileLastModified.setText(dt.format(d)); } SpannableStringBuilder sb = new SpannableStringBuilder(file.getName()); if (queryString != null && !TextUtils.isEmpty(queryString)) { int searchMatchPosition = file.getName().toLowerCase().indexOf(queryString.toLowerCase()); if (searchMatchPosition != -1) sb.setSpan(fcs, searchMatchPosition, searchMatchPosition + queryString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); } fileHolder.fileTextView.setText(sb); if (Mimes.match(file.getMime()) == Mimes.Type.IMAGE) { setUpImageIcon(file, fileHolder.fileIconView); } else if (Mimes.match(file.getMime()) == Mimes.Type.AUDIO) { setUpAudioArt(file, fileHolder.fileIconView); } else { fileHolder.fileIconView.setImageResource(Mimes.getFileIcon(file)); } fileHolder.itemView.setOnClickListener(view -> { mListener.onItemClick(fileHolder.itemView, fileHolder.getAdapterPosition()); }); fileHolder.moreOptions.setOnClickListener(view -> { selectedPosition = fileHolder.getAdapterPosition(); mListener.onMoreOptionClick(fileHolder.itemView, fileHolder.getAdapterPosition()); }); }
From source file:systems.soapbox.ombuds.client.ui.WalletTransactionsFragment.java
@Override public void onLoadFinished(final Loader<List<Transaction>> loader, final List<Transaction> transactions) { final Direction direction = ((TransactionsLoader) loader).getDirection(); adapter.replace(transactions);/*from www .j av a 2 s.c om*/ if (transactions.isEmpty()) { viewGroup.setDisplayedChild(1); final SpannableStringBuilder emptyText = new SpannableStringBuilder("You have no Bitcoin."); emptyText.setSpan(new StyleSpan(Typeface.BOLD), 0, emptyText.length(), SpannableStringBuilder.SPAN_POINT_MARK); emptyText.append("\n\n").append(getString(R.string.profile_email_for_bitcoin)); emptyView.setText(emptyText); } else { viewGroup.setDisplayedChild(2); } }
From source file:com.android.messaging.datamodel.MessageNotificationState.java
/** * Performs a query on the database./*ww w .java2s. c o m*/ */ private static ConversationInfoList createConversationInfoList() { // Map key is conversation id. We use LinkedHashMap to ensure that entries are iterated in // the same order they were originally added. We scan unseen messages from newest to oldest, // so the corresponding conversations are added in that order, too. final Map<String, ConversationLineInfo> convLineInfos = new LinkedHashMap<>(); int messageCount = 0; Cursor convMessageCursor = null; try { final Context context = Factory.get().getApplicationContext(); final DatabaseWrapper db = DataModel.get().getDatabase(); convMessageCursor = db.rawQuery(ConversationMessageData.getNotificationQuerySql(), null); if (convMessageCursor != null && convMessageCursor.moveToFirst()) { if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) { LogUtil.v(TAG, "MessageNotificationState: Found unseen message notifications."); } final ConversationMessageData convMessageData = new ConversationMessageData(); HashMap<String, Integer> firstNames = null; String conversationIdForFirstNames = null; String groupConversationName = null; final int maxMessages = getMaxMessagesInConversationNotification(); do { convMessageData.bind(convMessageCursor); // First figure out if this is a valid message. String authorFullName = convMessageData.getSenderFullName(); String authorFirstName = convMessageData.getSenderFirstName(); final String messageText = convMessageData.getText(); final String convId = convMessageData.getConversationId(); final String messageId = convMessageData.getMessageId(); CharSequence text = messageText; final boolean isManualDownloadNeeded = convMessageData.getIsMmsNotification(); if (isManualDownloadNeeded) { // Don't try and convert the text from html if it's sms and not a sms push // notification. Assert.equals(MessageData.BUGLE_STATUS_INCOMING_YET_TO_MANUAL_DOWNLOAD, convMessageData.getStatus()); text = context.getResources().getString(R.string.message_title_manual_download); } ConversationLineInfo currConvInfo = convLineInfos.get(convId); if (currConvInfo == null) { final ConversationListItemData convData = ConversationListItemData .getExistingConversation(db, convId); if (!convData.getNotificationEnabled()) { // Skip conversations that have notifications disabled. continue; } final int subId = BugleDatabaseOperations.getSelfSubscriptionId(db, convData.getSelfId()); groupConversationName = convData.getName(); final Uri avatarUri = AvatarUriUtil.createAvatarUri( convMessageData.getSenderProfilePhotoUri(), convMessageData.getSenderFullName(), convMessageData.getSenderNormalizedDestination(), convMessageData.getSenderContactLookupKey()); currConvInfo = new ConversationLineInfo(convId, convData.getIsGroup(), groupConversationName, convData.getIncludeEmailAddress(), convMessageData.getReceivedTimeStamp(), convData.getSelfId(), convData.getNotificationSoundUri(), convData.getNotificationEnabled(), convData.getNotifiationVibrate(), avatarUri, convMessageData.getSenderContactLookupUri(), subId, convData.getParticipantCount()); convLineInfos.put(convId, currConvInfo); } // Prepare the message line if (currConvInfo.mTotalMessageCount < maxMessages) { if (currConvInfo.mIsGroup) { if (authorFirstName == null) { // authorFullName might be null as well. In that case, we won't // show an author. That is better than showing all the group // names again on the 2nd line. authorFirstName = authorFullName; } } else { // don't recompute this if we don't need to if (!TextUtils.equals(conversationIdForFirstNames, convId)) { firstNames = scanFirstNames(convId); conversationIdForFirstNames = convId; } if (firstNames != null) { final Integer count = firstNames.get(authorFirstName); if (count != null && count > 1) { authorFirstName = authorFullName; } } if (authorFullName == null) { authorFullName = groupConversationName; } if (authorFirstName == null) { authorFirstName = groupConversationName; } } final String subjectText = MmsUtils.cleanseMmsSubject(context.getResources(), convMessageData.getMmsSubject()); if (!TextUtils.isEmpty(subjectText)) { final String subjectLabel = context.getString(R.string.subject_label); final SpannableStringBuilder spanBuilder = new SpannableStringBuilder(); spanBuilder.append( context.getString(R.string.notification_subject, subjectLabel, subjectText)); spanBuilder.setSpan(new TextAppearanceSpan(context, R.style.NotificationSubjectText), 0, subjectLabel.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); if (!TextUtils.isEmpty(text)) { // Now add the actual message text below the subject header. spanBuilder.append(System.getProperty("line.separator") + text); } text = spanBuilder; } // If we've got attachments, find the best one. If one of the messages is // a photo, save the url so we'll display a big picture notification. // Otherwise, show the first one we find. Uri attachmentUri = null; String attachmentType = null; final MessagePartData messagePartData = getMostInterestingAttachment(convMessageData); if (messagePartData != null) { attachmentUri = messagePartData.getContentUri(); attachmentType = messagePartData.getContentType(); } currConvInfo.mLineInfos .add(new MessageLineInfo(currConvInfo.mIsGroup, authorFullName, authorFirstName, text, attachmentUri, attachmentType, isManualDownloadNeeded, messageId)); } messageCount++; currConvInfo.mTotalMessageCount++; } while (convMessageCursor.moveToNext()); } } finally { if (convMessageCursor != null) { convMessageCursor.close(); } } if (convLineInfos.isEmpty()) { return null; } else { return new ConversationInfoList(messageCount, Lists.newLinkedList(convLineInfos.values())); } }
From source file:com.android.mms.ui.ConversationListItem.java
private CharSequence formatMessage() { final int color = android.R.styleable.Theme_textColorSecondary; String from = mConversation.getRecipients().formatNames(", "); if (MessageUtils.isWapPushNumber(from)) { String[] mAddresses = from.split(":"); from = mAddresses[mContext.getResources().getInteger(R.integer.wap_push_address_index)]; }//from www . j a va2 s.c o m /** * Add boolean to know that the "from" haven't the Arabic and '+'. * Make sure the "from" display normally for RTL. */ boolean isEnName = false; boolean isLayoutRtl = (TextUtils .getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL); if (isLayoutRtl && from != null) { if (from.length() >= 1) { Pattern pattern = Pattern.compile("[^-]+"); Matcher matcher = pattern.matcher(from); isEnName = matcher.matches(); if (isEnName && from.charAt(0) != '\u202D') { from = "\u202D" + from + "\u202C"; } } } SpannableStringBuilder buf = new SpannableStringBuilder(from); if (mConversation.getMessageCount() > 1) { int before = buf.length(); if (isLayoutRtl && isEnName) { buf.insert(1, mConversation.getMessageCount() + " "); buf.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.message_count_color)), 1, buf.length() - before, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } else { buf.append(mContext.getResources().getString(R.string.message_count_format, mConversation.getMessageCount())); buf.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.message_count_color)), before, buf.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } } if (mConversation.hasDraft()) { if (isLayoutRtl && isEnName) { int before = buf.length(); buf.insert(1, '\u202E' + mContext.getResources().getString(R.string.draft_separator) + '\u202C'); buf.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.drawable.text_color_black)), 1, buf.length() - before + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); before = buf.length(); int size; buf.insert(1, mContext.getResources().getString(R.string.has_draft)); size = android.R.style.TextAppearance_Small; buf.setSpan(new TextAppearanceSpan(mContext, size), 1, buf.length() - before + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); buf.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.drawable.text_color_red)), 1, buf.length() - before + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } else { buf.append(mContext.getResources().getString(R.string.draft_separator)); int before = buf.length(); int size; buf.append(mContext.getResources().getString(R.string.has_draft)); size = android.R.style.TextAppearance_Small; buf.setSpan(new TextAppearanceSpan(mContext, size, color), before, buf.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); buf.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.drawable.text_color_red)), before, buf.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } } // Unread messages are shown in bold if (mConversation.hasUnreadMessages()) { buf.setSpan(STYLE_BOLD, 0, buf.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } return buf; }