Search in sources :

Example 86 with StyleSpan

use of android.text.style.StyleSpan in project Android-Week-View by alamkanak.

the class WeekView method drawEventTitle.

/**
     * Draw the name of the event on top of the event rectangle.
     * @param event The event of which the title (and location) should be drawn.
     * @param rect The rectangle on which the text is to be drawn.
     * @param canvas The canvas to draw upon.
     * @param originalTop The original top position of the rectangle. The rectangle may have some of its portion outside of the visible area.
     * @param originalLeft The original left position of the rectangle. The rectangle may have some of its portion outside of the visible area.
     */
private void drawEventTitle(WeekViewEvent event, RectF rect, Canvas canvas, float originalTop, float originalLeft) {
    if (rect.right - rect.left - mEventPadding * 2 < 0)
        return;
    if (rect.bottom - rect.top - mEventPadding * 2 < 0)
        return;
    // Prepare the name of the event.
    SpannableStringBuilder bob = new SpannableStringBuilder();
    if (event.getName() != null) {
        bob.append(event.getName());
        bob.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, bob.length(), 0);
        bob.append(' ');
    }
    // Prepare the location of the event.
    if (event.getLocation() != null) {
        bob.append(event.getLocation());
    }
    int availableHeight = (int) (rect.bottom - originalTop - mEventPadding * 2);
    int availableWidth = (int) (rect.right - originalLeft - mEventPadding * 2);
    // Get text dimensions.
    StaticLayout textLayout = new StaticLayout(bob, mEventTextPaint, availableWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
    int lineHeight = textLayout.getHeight() / textLayout.getLineCount();
    if (availableHeight >= lineHeight) {
        // Calculate available number of line counts.
        int availableLineCount = availableHeight / lineHeight;
        do {
            // Ellipsize text to fit into event rect.
            textLayout = new StaticLayout(TextUtils.ellipsize(bob, mEventTextPaint, availableLineCount * availableWidth, TextUtils.TruncateAt.END), mEventTextPaint, (int) (rect.right - originalLeft - mEventPadding * 2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            // Reduce line count.
            availableLineCount--;
        // Repeat until text is short enough.
        } while (textLayout.getHeight() > availableHeight);
        // Draw text.
        canvas.save();
        canvas.translate(originalLeft + mEventPadding, originalTop + mEventPadding);
        textLayout.draw(canvas);
        canvas.restore();
    }
}
Also used : StyleSpan(android.text.style.StyleSpan) StaticLayout(android.text.StaticLayout) SpannableStringBuilder(android.text.SpannableStringBuilder) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint)

Example 87 with StyleSpan

use of android.text.style.StyleSpan in project plaid by nickbutcher.

the class Bypass method recurseElement.

// The 'numberOfSiblings' parameters refers to the number of siblings within the parent, including
// the 'element' parameter, as in "How many siblings are you?" rather than "How many siblings do
// you have?".
private CharSequence recurseElement(Element element, int indexWithinParent, int numberOfSiblings, TextView textView, LoadImageCallback loadImageCallback) {
    Type type = element.getType();
    boolean isOrderedList = false;
    if (type == Type.LIST) {
        String flagsStr = element.getAttribute("flags");
        if (flagsStr != null) {
            int flags = Integer.parseInt(flagsStr);
            isOrderedList = (flags & Element.F_LIST_ORDERED) != 0;
            if (isOrderedList) {
                mOrderedListNumber.put(element, 1);
            }
        }
    }
    int size = element.size();
    CharSequence[] spans = new CharSequence[size];
    for (int i = 0; i < size; i++) {
        spans[i] = recurseElement(element.children[i], i, size, textView, loadImageCallback);
    }
    // Clean up after we're done
    if (isOrderedList) {
        mOrderedListNumber.remove(this);
    }
    CharSequence concat = TextUtils.concat(spans);
    SpannableStringBuilder builder = new ReverseSpannableStringBuilder();
    String text = element.getText();
    if (element.size() == 0 && element.getParent() != null && element.getParent().getType() != Type.BLOCK_CODE) {
        text = text.replace('\n', ' ');
    }
    switch(type) {
        case LIST:
            if (element.getParent() != null && element.getParent().getType() == Type.LIST_ITEM) {
                builder.append("\n");
            }
            break;
        case LINEBREAK:
            builder.append("\n");
            break;
        case LIST_ITEM:
            builder.append(" ");
            if (mOrderedListNumber.containsKey(element.getParent())) {
                int number = mOrderedListNumber.get(element.getParent());
                builder.append(Integer.toString(number) + ".");
                mOrderedListNumber.put(element.getParent(), number + 1);
            } else {
                builder.append(mOptions.mUnorderedListItem);
            }
            builder.append("  ");
            break;
        case AUTOLINK:
            builder.append(element.getAttribute("link"));
            break;
        case HRULE:
            // This ultimately gets drawn over by the line span, but
            // we need something here or the span isn't even drawn.
            builder.append("-");
            break;
        case IMAGE:
            if (loadImageCallback != null && !TextUtils.isEmpty(element.getAttribute("link"))) {
                // prepend a new line so that images are always on a new line
                builder.append("\n");
                // Display alt text (or title text) if there is no image
                String alt = element.getAttribute("alt");
                if (TextUtils.isEmpty(alt)) {
                    alt = element.getAttribute("title");
                }
                if (!TextUtils.isEmpty(alt)) {
                    alt = "[" + alt + "]";
                    builder.append(alt);
                } else {
                    // Character to be replaced
                    builder.append("");
                }
            } else {
                // Character to be replaced
                builder.append("");
            }
            break;
    }
    builder.append(text);
    builder.append(concat);
    // of the last child within the parent.
    if (element.getParent() != null || indexWithinParent < (numberOfSiblings - 1)) {
        if (type == Type.LIST_ITEM) {
            if (element.size() == 0 || !element.children[element.size() - 1].isBlockElement()) {
                builder.append("\n");
            }
        } else if (element.isBlockElement() && type != Type.BLOCK_QUOTE) {
            if (type == Type.LIST) {
                // If this is a nested list, don't include newlines
                if (element.getParent() == null || element.getParent().getType() != Type.LIST_ITEM) {
                    builder.append("\n");
                }
            } else if (element.getParent() != null && element.getParent().getType() == Type.LIST_ITEM) {
                // List items should never double-space their entries
                builder.append("\n");
            } else {
                builder.append("\n\n");
            }
        }
    }
    switch(type) {
        case HEADER:
            String levelStr = element.getAttribute("level");
            int level = Integer.parseInt(levelStr);
            setSpan(builder, new RelativeSizeSpan(mOptions.mHeaderSizes[level - 1]));
            setSpan(builder, new StyleSpan(Typeface.BOLD));
            break;
        case LIST:
            setBlockSpan(builder, new LeadingMarginSpan.Standard(mListItemIndent));
            break;
        case EMPHASIS:
            setSpan(builder, new StyleSpan(Typeface.ITALIC));
            break;
        case DOUBLE_EMPHASIS:
            setSpan(builder, new StyleSpan(Typeface.BOLD));
            break;
        case TRIPLE_EMPHASIS:
            setSpan(builder, new StyleSpan(Typeface.BOLD_ITALIC));
            break;
        case BLOCK_CODE:
            setSpan(builder, new LeadingMarginSpan.Standard(mCodeBlockIndent));
            setSpan(builder, new TypefaceSpan("monospace"));
            break;
        case CODE_SPAN:
            setSpan(builder, new TypefaceSpan("monospace"));
            break;
        case LINK:
        case AUTOLINK:
            String link = element.getAttribute("link");
            if (!TextUtils.isEmpty(link) && Patterns.EMAIL_ADDRESS.matcher(link).matches()) {
                link = "mailto:" + link;
            }
            setSpan(builder, new TouchableUrlSpan(link, textView.getLinkTextColors(), textView.getHighlightColor()));
            break;
        case BLOCK_QUOTE:
            // We add two leading margin spans so that when the order is reversed,
            // the QuoteSpan will always be in the same spot.
            setBlockSpan(builder, new LeadingMarginSpan.Standard(mBlockQuoteIndent));
            //setBlockSpan(builder, new QuoteSpan(mOptions.mBlockQuoteLineColor));
            setBlockSpan(builder, new FancyQuoteSpan(mBlockQuoteLineWidth, mBlockQuoteLineIndent, mOptions.mBlockQuoteLineColor));
            setBlockSpan(builder, new ForegroundColorSpan(mOptions.mBlockQuoteTextColor));
            setBlockSpan(builder, new LeadingMarginSpan.Standard(mBlockQuoteIndent));
            setBlockSpan(builder, new StyleSpan(Typeface.ITALIC));
            break;
        case STRIKETHROUGH:
            setSpan(builder, new StrikethroughSpan());
            break;
        case HRULE:
            setSpan(builder, new HorizontalLineSpan(mOptions.mHruleColor, mHruleSize, mHruleTopBottomPadding));
            break;
        case IMAGE:
            String url = element.getAttribute("link");
            if (loadImageCallback != null && !TextUtils.isEmpty(url)) {
                setPrependedNewlineSpan(builder, mOptions.mPreImageLinebreakHeight);
                ImageLoadingSpan loadingSpan = new ImageLoadingSpan();
                setSpanWithPrependedNewline(builder, loadingSpan);
                // make the (eventually loaded) image span clickable to open in browser
                setSpanWithPrependedNewline(builder, new TouchableUrlSpan(url, textView.getLinkTextColors(), textView.getHighlightColor()));
                loadImageCallback.loadImage(url, loadingSpan);
            }
            break;
    }
    return builder;
}
Also used : TouchableUrlSpan(in.uncod.android.bypass.style.TouchableUrlSpan) HorizontalLineSpan(in.uncod.android.bypass.style.HorizontalLineSpan) ForegroundColorSpan(android.text.style.ForegroundColorSpan) FancyQuoteSpan(in.uncod.android.bypass.style.FancyQuoteSpan) RelativeSizeSpan(android.text.style.RelativeSizeSpan) Type(in.uncod.android.bypass.Element.Type) StyleSpan(android.text.style.StyleSpan) LeadingMarginSpan(android.text.style.LeadingMarginSpan) ImageLoadingSpan(in.uncod.android.bypass.style.ImageLoadingSpan) SpannableStringBuilder(android.text.SpannableStringBuilder) TypefaceSpan(android.text.style.TypefaceSpan) StrikethroughSpan(android.text.style.StrikethroughSpan)

Example 88 with StyleSpan

use of android.text.style.StyleSpan in project SeriesGuide by UweTrottmann.

the class NotificationService method onNotify.

private void onNotify(final Cursor upcomingEpisodes, List<Integer> notifyPositions, long latestAirtime) {
    final Context context = getApplicationContext();
    CharSequence tickerText;
    CharSequence contentTitle;
    CharSequence contentText;
    PendingIntent contentIntent;
    // base intent for task stack
    final Intent showsIntent = new Intent(context, ShowsActivity.class);
    showsIntent.putExtra(ShowsActivity.InitBundle.SELECTED_TAB, ShowsActivity.InitBundle.INDEX_TAB_UPCOMING);
    final int count = notifyPositions.size();
    if (count == 1) {
        // notify in detail about one episode
        upcomingEpisodes.moveToPosition(notifyPositions.get(0));
        final String showTitle = upcomingEpisodes.getString(NotificationQuery.SHOW_TITLE);
        // show title and number, like 'Show 1x01'
        contentTitle = TextTools.getShowWithEpisodeNumber(this, showTitle, upcomingEpisodes.getInt(NotificationQuery.SEASON), upcomingEpisodes.getInt(NotificationQuery.NUMBER));
        tickerText = getString(R.string.upcoming_show, contentTitle);
        // "8:00 PM on Network"
        final String releaseTime = TimeTools.formatToLocalTime(this, TimeTools.applyUserOffset(this, upcomingEpisodes.getLong(NotificationQuery.EPISODE_FIRST_RELEASE_MS)));
        final String network = upcomingEpisodes.getString(NotificationQuery.NETWORK);
        contentText = getString(R.string.upcoming_show_detailed, releaseTime, network);
        Intent episodeDetailsIntent = new Intent(context, EpisodesActivity.class);
        episodeDetailsIntent.putExtra(EpisodesActivity.InitBundle.EPISODE_TVDBID, upcomingEpisodes.getInt(NotificationQuery._ID));
        episodeDetailsIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime);
        contentIntent = TaskStackBuilder.create(context).addNextIntent(showsIntent).addNextIntent(episodeDetailsIntent).getPendingIntent(REQUEST_CODE_SINGLE_EPISODE, PendingIntent.FLAG_CANCEL_CURRENT);
    } else {
        // notify about multiple episodes
        tickerText = getString(R.string.upcoming_episodes);
        contentTitle = getString(R.string.upcoming_episodes_number, count);
        contentText = getString(R.string.upcoming_display);
        contentIntent = TaskStackBuilder.create(context).addNextIntent(showsIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime)).getPendingIntent(REQUEST_CODE_MULTIPLE_EPISODES, PendingIntent.FLAG_CANCEL_CURRENT);
    }
    final NotificationCompat.Builder nb = new NotificationCompat.Builder(context);
    boolean richNotification = AndroidUtils.isJellyBeanOrHigher();
    if (richNotification) {
        // JELLY BEAN and above
        if (count == 1) {
            // single episode
            upcomingEpisodes.moveToPosition(notifyPositions.get(0));
            maybeSetPoster(nb, upcomingEpisodes.getString(NotificationQuery.POSTER));
            if (!DisplaySettings.preventSpoilers(context)) {
                final String episodeTitle = upcomingEpisodes.getString(NotificationQuery.TITLE);
                final String episodeSummary = upcomingEpisodes.getString(NotificationQuery.OVERVIEW);
                final SpannableStringBuilder bigText = new SpannableStringBuilder();
                bigText.append(TextUtils.isEmpty(episodeTitle) ? "" : episodeTitle);
                bigText.setSpan(new StyleSpan(Typeface.BOLD), 0, bigText.length(), 0);
                bigText.append("\n");
                bigText.append(TextUtils.isEmpty(episodeSummary) ? "" : episodeSummary);
                nb.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText).setSummaryText(contentText));
            }
            // Action button to check in
            Intent checkInActionIntent = new Intent(context, QuickCheckInActivity.class);
            checkInActionIntent.putExtra(QuickCheckInActivity.InitBundle.EPISODE_TVDBID, upcomingEpisodes.getInt(NotificationQuery._ID));
            checkInActionIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime);
            checkInActionIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            PendingIntent checkInIntent = PendingIntent.getActivity(context, REQUEST_CODE_ACTION_CHECKIN, checkInActionIntent, PendingIntent.FLAG_CANCEL_CURRENT);
            nb.addAction(R.drawable.ic_action_checkin, getString(R.string.checkin), checkInIntent);
            // Action button to set watched
            Intent setWatchedIntent = new Intent(context, NotificationActionReceiver.class);
            setWatchedIntent.putExtra(NotificationActionReceiver.EXTRA_EPISODE_TVDBID, upcomingEpisodes.getInt(NotificationQuery._ID));
            // data to handle delete
            checkInActionIntent.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime);
            PendingIntent setWatchedPendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE_ACTION_SET_WATCHED, setWatchedIntent, PendingIntent.FLAG_CANCEL_CURRENT);
            nb.addAction(R.drawable.ic_action_tick, getString(R.string.action_watched), setWatchedPendingIntent);
            nb.setNumber(1);
        } else {
            // multiple episodes
            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
            // display at most the first five
            for (int displayIndex = 0; displayIndex < Math.min(count, 5); displayIndex++) {
                if (!upcomingEpisodes.moveToPosition(notifyPositions.get(displayIndex))) {
                    // could not go to the desired position (testing just in case)
                    break;
                }
                final SpannableStringBuilder lineText = new SpannableStringBuilder();
                // show title and number, like 'Show 1x01'
                String title = TextTools.getShowWithEpisodeNumber(this, upcomingEpisodes.getString(NotificationQuery.SHOW_TITLE), upcomingEpisodes.getInt(NotificationQuery.SEASON), upcomingEpisodes.getInt(NotificationQuery.NUMBER));
                lineText.append(title);
                lineText.setSpan(new StyleSpan(Typeface.BOLD), 0, lineText.length(), 0);
                lineText.append(" ");
                // "8:00 PM on Network"
                String releaseTime = TimeTools.formatToLocalTime(this, TimeTools.applyUserOffset(this, upcomingEpisodes.getLong(NotificationQuery.EPISODE_FIRST_RELEASE_MS)));
                String network = upcomingEpisodes.getString(NotificationQuery.NETWORK);
                lineText.append(getString(R.string.upcoming_show_detailed, releaseTime, network));
                inboxStyle.addLine(lineText);
            }
            // tell if we could not display all episodes
            if (count > 5) {
                inboxStyle.setSummaryText(getString(R.string.more, count - 5));
            }
            nb.setStyle(inboxStyle);
            nb.setNumber(count);
        }
    } else {
        // ICS and below
        if (count == 1) {
            // single episode
            upcomingEpisodes.moveToPosition(notifyPositions.get(0));
            maybeSetPoster(nb, upcomingEpisodes.getString(NotificationQuery.POSTER));
        }
    }
    // notification sound
    final String ringtoneUri = NotificationSettings.getNotificationsRingtone(context);
    // If the string is empty, the user chose silent...
    boolean hasSound = ringtoneUri.length() != 0;
    if (hasSound) {
        // ...otherwise set the specified ringtone
        nb.setSound(Uri.parse(ringtoneUri));
    }
    // vibration
    boolean vibrates = NotificationSettings.isNotificationVibrating(context);
    if (vibrates) {
        nb.setVibrate(VIBRATION_PATTERN);
    }
    nb.setDefaults(Notification.DEFAULT_LIGHTS);
    nb.setWhen(System.currentTimeMillis());
    nb.setAutoCancel(true);
    nb.setTicker(tickerText);
    nb.setContentTitle(contentTitle);
    nb.setContentText(contentText);
    nb.setContentIntent(contentIntent);
    nb.setSmallIcon(R.drawable.ic_notification);
    nb.setColor(ContextCompat.getColor(this, R.color.accent_primary));
    nb.setPriority(NotificationCompat.PRIORITY_DEFAULT);
    Intent i = new Intent(this, NotificationService.class);
    i.putExtra(KEY_EPISODE_CLEARED_TIME, latestAirtime);
    PendingIntent deleteIntent = PendingIntent.getService(this, REQUEST_CODE_DELETE_INTENT, i, PendingIntent.FLAG_CANCEL_CURRENT);
    nb.setDeleteIntent(deleteIntent);
    // build the notification
    Notification notification = nb.build();
    // use a unique id within the app
    NotificationManagerCompat nm = NotificationManagerCompat.from(getApplicationContext());
    nm.notify(SgApp.NOTIFICATION_EPISODE_ID, notification);
    Timber.d("Notification: count=%d, rich(JB+)=%s, sound=%s, vibrate=%s, delete=%d", count, richNotification ? "YES" : "NO", hasSound ? "YES" : "NO", vibrates ? "YES" : "NO", latestAirtime);
}
Also used : Context(android.content.Context) TaskStackBuilder(android.support.v4.app.TaskStackBuilder) SpannableStringBuilder(android.text.SpannableStringBuilder) NotificationManagerCompat(android.support.v4.app.NotificationManagerCompat) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) SuppressLint(android.annotation.SuppressLint) Notification(android.app.Notification) StyleSpan(android.text.style.StyleSpan) NotificationCompat(android.support.v4.app.NotificationCompat) PendingIntent(android.app.PendingIntent) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 89 with StyleSpan

use of android.text.style.StyleSpan in project xabber-android by redsolution.

the class MessageNotificationCreator method getContactNameAndMessage.

private Spannable getContactNameAndMessage(MessageNotification messageNotification, boolean showText) {
    String userName = getContactName(messageNotification);
    Spannable spannableString;
    if (showText) {
        String contactAndMessage = application.getString(R.string.chat_contact_and_message, userName, messageNotification.getText());
        spannableString = new SpannableString(contactAndMessage);
    } else {
        spannableString = new SpannableString(userName);
    }
    spannableString.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, userName.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannableString;
}
Also used : SpannableString(android.text.SpannableString) StyleSpan(android.text.style.StyleSpan) SpannableString(android.text.SpannableString) Spannable(android.text.Spannable)

Example 90 with StyleSpan

use of android.text.style.StyleSpan in project Shuttle by timusus.

the class PlaylistUtils method getPlaylistRemoveString.

private static SpannableStringBuilder getPlaylistRemoveString(Context context, Song song) {
    SpannableStringBuilder spannableString = new SpannableStringBuilder(String.format(context.getString(R.string.dialog_message_playlist_add_duplicate), song.artistName, song.name));
    final StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
    spannableString.setSpan(boldSpan, 0, song.artistName.length() + song.name.length() + 3, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    return spannableString;
}
Also used : StyleSpan(android.text.style.StyleSpan) SpannableStringBuilder(android.text.SpannableStringBuilder)

Aggregations

StyleSpan (android.text.style.StyleSpan)145 SpannableString (android.text.SpannableString)56 SpannableStringBuilder (android.text.SpannableStringBuilder)36 RelativeSizeSpan (android.text.style.RelativeSizeSpan)32 ForegroundColorSpan (android.text.style.ForegroundColorSpan)25 View (android.view.View)18 TextView (android.widget.TextView)17 UnderlineSpan (android.text.style.UnderlineSpan)16 Spannable (android.text.Spannable)14 StrikethroughSpan (android.text.style.StrikethroughSpan)13 TypefaceSpan (android.text.style.TypefaceSpan)12 TypedArray (android.content.res.TypedArray)10 TextPaint (android.text.TextPaint)10 SubscriptSpan (android.text.style.SubscriptSpan)10 SuperscriptSpan (android.text.style.SuperscriptSpan)10 Handler (android.os.Handler)9 Message (android.os.Message)9 URLSpan (android.text.style.URLSpan)8 JustifiedSpan (com.bluejamesbond.text.style.JustifiedSpan)8 ArticleBuilder (com.bluejamesbond.text.util.ArticleBuilder)8