Example usage for android.text SpannableStringBuilder length

List of usage examples for android.text SpannableStringBuilder length

Introduction

In this page you can find the example usage for android.text SpannableStringBuilder length.

Prototype

public int length() 

Source Link

Document

Return the number of chars in the buffer.

Usage

From source file:com.deliciousdroid.fragment.ViewBookmarkFragment.java

private void addTag(SpannableStringBuilder builder, Tag t, TagSpan.OnTagClickListener listener) {
    int flags = 0;

    if (builder.length() != 0) {
        builder.append("  ");
    }// www .  j av  a  2s. co  m

    int start = builder.length();
    builder.append(t.getTagName());
    int end = builder.length();

    TagSpan span = new TagSpan(t.getTagName());
    span.setOnTagClickListener(listener);

    builder.setSpan(span, start, end, flags);
}

From source file:com.pindroid.fragment.ViewBookmarkFragment.java

private void loadBookmark() {
    if (bookmark != null) {
        if (viewType == BookmarkViewType.VIEW) {

            Date d = new Date(bookmark.getTime());

            if (bookmark.getDescription() != null && !bookmark.getDescription().equals("null"))
                mTitle.setText(bookmark.getDescription());

            mUrl.setText(bookmark.getUrl());

            if (bookmark.getNotes() != null && !bookmark.getNotes().equals("null")
                    && !bookmark.getNotes().equals("")) {
                mNotes.setText(bookmark.getNotes());
                notesSection.setVisibility(View.VISIBLE);
            } else {
                notesSection.setVisibility(View.GONE);
            }/*from w w w  . j a  va2  s . c  o m*/

            mTime.setText(d.toString());

            mTags.setMovementMethod(LinkMovementMethod.getInstance());
            SpannableStringBuilder tagBuilder = new SpannableStringBuilder();

            if (bookmark.getTags().size() > 0) {
                for (Tag t : bookmark.getTags()) {
                    addTag(tagBuilder, t, tagOnClickListener);
                }

                mTags.setText(tagBuilder);

                tagsSection.setVisibility(View.VISIBLE);
            } else {
                tagsSection.setVisibility(View.GONE);
            }

            if (isMyself()) {
                Uri.Builder ub = new Uri.Builder();
                ub.scheme("content");
                ub.authority(BookmarkContentProvider.AUTHORITY);
                ub.appendPath("bookmark");
                ub.appendPath(Integer.toString(bookmark.getId()));

                getActivity().getContentResolver().unregisterContentObserver(observer);
                getActivity().getContentResolver().registerContentObserver(ub.build(), true, observer);

                mUsername.setText(bookmark.getAccount());

                if (bookmark.getToRead() && bookmark.getShared()) {
                    bookmarkIcon.setImageResource(R.drawable.ic_unread);
                } else if (!bookmark.getToRead() && bookmark.getShared()) {
                    bookmarkIcon.setImageResource(R.drawable.ic_bookmark);
                } else if (bookmark.getToRead() && !bookmark.getShared()) {
                    bookmarkIcon.setImageResource(R.drawable.ic_unread_private);
                } else if (!bookmark.getToRead() && !bookmark.getShared()) {
                    bookmarkIcon.setImageResource(R.drawable.ic_bookmark_private);
                }

            } else {
                if (bookmark.getAccount() != null) {
                    SpannableStringBuilder builder = new SpannableStringBuilder();
                    int start = builder.length();
                    builder.append(bookmark.getAccount());
                    int end = builder.length();

                    AccountSpan span = new AccountSpan(bookmark.getAccount());
                    span.setOnAccountClickListener(accountOnClickListener);

                    builder.setSpan(span, start, end, 0);

                    mUsername.setText(builder);
                }

                mUsername.setMovementMethod(LinkMovementMethod.getInstance());
            }
        } else if (viewType == BookmarkViewType.READ) {
            showInWebView(Constants.INSTAPAPER_URL + bookmark.getUrl());

            if (isMyself() && bookmark.getToRead() && SettingsHelper.getMarkAsRead(getActivity()))
                bookmarkSelectedListener.onBookmarkMark(bookmark);
        } else if (viewType == BookmarkViewType.WEB) {
            showInWebView(bookmark.getUrl());
        }
    } else {
        clearView();
    }
}

From source file:com.uwetrottmann.wpdisplay.ui.DisplayFragment.java

private void setText(TextView view, int labelResId, String value) {
    SpannableStringBuilder builder = new SpannableStringBuilder();

    builder.append(getString(labelResId));
    builder.setSpan(new TextAppearanceSpan(getActivity(), R.style.TextAppearance_AppCompat_Caption), 0,
            builder.length(), 0);

    builder.append("\n");

    int lengthOld = builder.length();
    builder.append(value);//from w  ww.java2s  . co  m
    builder.setSpan(new TextAppearanceSpan(getActivity(), R.style.TextAppearance_AppCompat_Display1), lengthOld,
            builder.length(), 0);

    view.setText(builder);
}

From source file:com.uwetrottmann.wpdisplay.ui.DisplayFragment.java

private void setTemperature(TextView view, int labelResId, double value) {
    SpannableStringBuilder builder = new SpannableStringBuilder();

    builder.append(getString(labelResId));
    builder.setSpan(new TextAppearanceSpan(getActivity(), R.style.TextAppearance_AppCompat_Caption), 0,
            builder.length(), 0);

    builder.append("\n");

    int lengthOld = builder.length();
    builder.append(String.format(Locale.getDefault(), "%.1f", value));
    builder.setSpan(new TextAppearanceSpan(getActivity(), R.style.TextAppearance_AppCompat_Display3), lengthOld,
            builder.length(), 0);//from w  w  w. ja v a  2  s .co  m

    lengthOld = builder.length();
    builder.append(getString(R.string.unit_celsius));
    builder.setSpan(new TextAppearanceSpan(getActivity(), R.style.TextAppearance_App_Unit), lengthOld,
            builder.length(), 0);

    view.setText(builder);
}

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  va2s.co  m

    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:nya.miku.wishmaster.ui.settings.AutohideActivity.java

@SuppressLint("InflateParams")
@Override//  w w  w  .ja  v  a  2 s .c o m
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    Object item = l.getItemAtPosition(position);
    final int changeId;
    if (item instanceof AutohideRule) {
        changeId = position - 1;
    } else {
        changeId = -1; //-1 - ?  
    }

    Context dialogContext = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
            ? new ContextThemeWrapper(this, R.style.Neutron_Medium)
            : this;
    View dialogView = LayoutInflater.from(dialogContext).inflate(R.layout.dialog_autohide_rule, null);
    final EditText regexEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_regex);
    final Spinner chanSpinner = (Spinner) dialogView.findViewById(R.id.dialog_autohide_chan_spinner);
    final EditText boardEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_boardname);
    final EditText threadEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_threadnum);
    final CheckBox inCommentCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_comment);
    final CheckBox inSubjectCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_subject);
    final CheckBox inNameCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_name);

    chanSpinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, chans));
    if (changeId != -1) {
        AutohideRule rule = (AutohideRule) item;
        regexEditText.setText(rule.regex);
        int chanPosition = chans.indexOf(rule.chanName);
        chanSpinner.setSelection(chanPosition != -1 ? chanPosition : 0);
        boardEditText.setText(rule.boardName);
        threadEditText.setText(rule.threadNumber);
        inCommentCheckBox.setChecked(rule.inComment);
        inSubjectCheckBox.setChecked(rule.inSubject);
        inNameCheckBox.setChecked(rule.inName);
    } else {
        chanSpinner.setSelection(0);
    }

    DialogInterface.OnClickListener save = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String regex = regexEditText.getText().toString();
            if (regex.length() == 0) {
                Toast.makeText(AutohideActivity.this, R.string.autohide_error_empty_regex, Toast.LENGTH_LONG)
                        .show();
                return;
            }

            try {
                Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
            } catch (Exception e) {
                CharSequence message = null;
                if (e instanceof PatternSyntaxException) {
                    String eMessage = e.getMessage();
                    if (!TextUtils.isEmpty(eMessage)) {
                        SpannableStringBuilder a = new SpannableStringBuilder(
                                getString(R.string.autohide_error_incorrect_regex));
                        a.append('\n');
                        int startlen = a.length();
                        a.append(eMessage);
                        a.setSpan(new TypefaceSpan("monospace"), startlen, a.length(),
                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        message = a;
                    }
                }
                if (message == null)
                    message = getString(R.string.error_unknown);
                Toast.makeText(AutohideActivity.this, message, Toast.LENGTH_LONG).show();
                return;
            }

            AutohideRule rule = new AutohideRule();
            int spinnerSelectedPosition = chanSpinner.getSelectedItemPosition();
            rule.regex = regex;
            rule.chanName = spinnerSelectedPosition > 0 ? chans.get(spinnerSelectedPosition) : ""; // 0 ? = ? 
            rule.boardName = boardEditText.getText().toString();
            rule.threadNumber = threadEditText.getText().toString();
            rule.inComment = inCommentCheckBox.isChecked();
            rule.inSubject = inSubjectCheckBox.isChecked();
            rule.inName = inNameCheckBox.isChecked();

            if (!rule.inComment && !rule.inSubject && !rule.inName) {
                Toast.makeText(AutohideActivity.this, R.string.autohide_error_no_condition, Toast.LENGTH_LONG)
                        .show();
                return;
            }

            if (changeId == -1) {
                rulesJson.put(rule.toJson());
            } else {
                rulesJson.put(changeId, rule.toJson());
            }
            rulesChanged();
        }
    };
    AlertDialog dialog = new AlertDialog.Builder(this).setView(dialogView)
            .setTitle(changeId == -1 ? R.string.autohide_add_rule_title : R.string.autohide_edit_rule_title)
            .setPositiveButton(R.string.autohide_save_button, save)
            .setNegativeButton(android.R.string.cancel, null).create();
    dialog.setCanceledOnTouchOutside(false);
    dialog.show();
}

From source file:com.deliciousdroid.fragment.ViewBookmarkFragment.java

public void loadBookmark() {
    if (bookmark != null) {

        if (isMyself() && bookmark.getId() != 0) {
            try {
                int id = bookmark.getId();
                bookmark = BookmarkManager.GetById(id, base);
            } catch (ContentNotFoundException e) {
            }// ww  w  .  java 2 s  .c  o m
        }

        if (viewType == BookmarkViewType.VIEW) {
            mBookmarkView.setVisibility(View.VISIBLE);
            readSection.setVisibility(View.GONE);
            mWebContent.setVisibility(View.GONE);
            if (isMyself()) {
                Date d = new Date(bookmark.getTime());

                mTitle.setText(bookmark.getDescription());
                mUrl.setText(bookmark.getUrl());
                mNotes.setText(bookmark.getNotes());
                mTime.setText(d.toString());
                mUsername.setText(bookmark.getAccount());

                if (mIcon != null) {
                    if (!bookmark.getShared()) {
                        mIcon.setImageResource(R.drawable.padlock);
                    }
                }

                SpannableStringBuilder tagBuilder = new SpannableStringBuilder();

                for (Tag t : bookmark.getTags()) {
                    addTag(tagBuilder, t, tagOnClickListener);
                }

                mTags.setText(tagBuilder);
                mTags.setMovementMethod(LinkMovementMethod.getInstance());
            } else {

                Date d = new Date(bookmark.getTime());

                if (bookmark.getDescription() != null && !bookmark.getDescription().equals("null"))
                    mTitle.setText(bookmark.getDescription());

                mUrl.setText(bookmark.getUrl());

                if (bookmark.getNotes() != null && !bookmark.getNotes().equals("null"))
                    mNotes.setText(bookmark.getNotes());

                mTime.setText(d.toString());

                SpannableStringBuilder tagBuilder = new SpannableStringBuilder();

                for (Tag t : bookmark.getTags()) {
                    addTag(tagBuilder, t, userTagOnClickListener);
                }

                mTags.setText(tagBuilder);
                mTags.setMovementMethod(LinkMovementMethod.getInstance());

                if (bookmark.getAccount() != null) {
                    SpannableStringBuilder builder = new SpannableStringBuilder();
                    int start = builder.length();
                    builder.append(bookmark.getAccount());
                    int end = builder.length();

                    AccountSpan span = new AccountSpan(bookmark.getAccount());
                    span.setOnAccountClickListener(accountOnClickListener);

                    builder.setSpan(span, start, end, 0);

                    mUsername.setText(builder);
                }

                mUsername.setMovementMethod(LinkMovementMethod.getInstance());
            }
        } else if (viewType == BookmarkViewType.READ) {
            new GetArticleTask().execute(bookmark.getUrl());
        } else if (viewType == BookmarkViewType.WEB) {
            showInWebView();
        }
    }
}

From source file:com.ruesga.rview.misc.Formatter.java

@BindingAdapter("userMessage")
public static void toUserMessage(TextView view, String msg) {
    if (msg == null) {
        view.setText(null);// w w  w.  j  av  a  2  s . c o  m
        return;
    }

    String message = EmojiHelper.createEmoji(msg);

    // This process mimics the Gerrit formatting process done in class
    // ./gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/SafeHtml.java

    // Split message into paragraphs
    String[] paragraphs = StringHelper.obtainParagraphs(message);
    StringBuilder sb = new StringBuilder();
    boolean formattedMessage = false;
    for (String p : paragraphs) {
        if (StringHelper.isQuote(p)) {
            sb.append(StringHelper.obtainQuote(StringHelper.removeLineBreaks(p)));
            formattedMessage = true;
        } else if (StringHelper.isList(p)) {
            sb.append(p);
            formattedMessage = true;
        } else if (StringHelper.isPreFormat(p)) {
            sb.append(StringHelper.obtainPreFormatMessage(p));
            formattedMessage = true;
        } else {
            sb.append(p);
        }
        sb.append("\n\n");
    }

    String userMessage = StringHelper.removeExtraLines(sb.toString());
    if (!formattedMessage) {
        view.setText(userMessage);
        return;
    }

    if (sQuoteColor == -1) {
        sQuoteColor = ContextCompat.getColor(view.getContext(), R.color.quote);
        sQuoteWidth = (int) view.getContext().getResources().getDimension(R.dimen.quote_width);
        sQuoteMargin = (int) view.getContext().getResources().getDimension(R.dimen.quote_margin);
    }

    String[] lines = userMessage.split("\n");
    SpannableStringBuilder spannable = new SpannableStringBuilder(userMessage
            .replaceAll(StringHelper.NON_PRINTABLE_CHAR, "").replaceAll(StringHelper.NON_PRINTABLE_CHAR2, ""));

    // Pre-Format
    int start = 0;
    int spans = 0;
    while ((start = userMessage.indexOf(StringHelper.NON_PRINTABLE_CHAR2, start)) != -1) {
        int end = userMessage.indexOf(StringHelper.NON_PRINTABLE_CHAR2, start + 1);
        if (end == -1) {
            //? This is supposed to be formatted by us. Skip it
            break;
        }

        // Find quote token occurrences
        int offset = StringHelper.countOccurrences(StringHelper.NON_PRINTABLE_CHAR, userMessage, 0, start);
        start -= offset;
        end -= offset;

        // Ensure bounds
        int spanStart = start - spans;
        int spanEnd = Math.min(end - spans - 1, spannable.length());
        if (spanStart < 0 || spanEnd < 0) {
            //Something was wrong. Skip it
            break;
        }
        spannable.setSpan(new RelativeSizeSpan(0.8f), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannable.setSpan(new TypefaceSpan("monospace"), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        start = end;
        spans++;
    }

    start = 0;
    for (String line : lines) {
        // Quotes
        int maxIndent = StringHelper.countOccurrences(StringHelper.NON_PRINTABLE_CHAR, line);
        for (int i = 0; i < maxIndent; i++) {
            QuotedSpan span = new QuotedSpan(sQuoteColor, sQuoteWidth, sQuoteMargin);
            spannable.setSpan(span, start, Math.min(start + line.length() - maxIndent, spannable.length()),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        // List
        if (StringHelper.isList(line)) {
            spannable.replace(start, start + 1, "\u2022");
            spannable.setSpan(new LeadingMarginSpan.Standard(sQuoteMargin), start,
                    Math.min(start + line.length(), spannable.length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        start += line.length() - maxIndent + 1;
    }

    view.setText(spannable);
}

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  w w w. j a v  a  2s  .  com

    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:org.mozilla.gecko.home.HistoryPanel.java

/**
 * Make Span that is clickable, italicized, and underlined
 * between the string markers <code>FORMAT_S1</code> and
 * <code>FORMAT_S2</code>./*from   ww w  .  j a v a2 s.co  m*/
 *
 * @param text String to format
 * @return formatted SpannableStringBuilder, or null if there
 * is not any text to format.
 */
private SpannableStringBuilder formatHintText(String text) {
    // Set formatting as marked by string placeholders.
    final int underlineStart = text.indexOf(FORMAT_S1);
    final int underlineEnd = text.indexOf(FORMAT_S2);

    // Check that there is text to be formatted.
    if (underlineStart >= underlineEnd) {
        return null;
    }

    final SpannableStringBuilder ssb = new SpannableStringBuilder(text);

    // Set italicization.
    ssb.setSpan(new StyleSpan(Typeface.ITALIC), 0, ssb.length(), 0);

    // Set clickable text.
    final ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.HOMESCREEN,
                    "hint-private-browsing");
            try {
                final JSONObject json = new JSONObject();
                json.put("type", "Menu:Open");
                EventDispatcher.getInstance().dispatchEvent(json, null);
            } catch (JSONException e) {
                Log.e(LOGTAG, "Error forming JSON for Private Browsing contextual hint", e);
            }
        }
    };

    ssb.setSpan(clickableSpan, 0, text.length(), 0);

    // Remove underlining set by ClickableSpan.
    final UnderlineSpan noUnderlineSpan = new UnderlineSpan() {
        @Override
        public void updateDrawState(TextPaint textPaint) {
            textPaint.setUnderlineText(false);
        }
    };

    ssb.setSpan(noUnderlineSpan, 0, text.length(), 0);

    // Add underlining for "Private Browsing".
    ssb.setSpan(new UnderlineSpan(), underlineStart, underlineEnd, 0);

    ssb.delete(underlineEnd, underlineEnd + FORMAT_S2.length());
    ssb.delete(underlineStart, underlineStart + FORMAT_S1.length());

    return ssb;
}