1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.dialer.spannable; 17 18 import android.content.Context; 19 import android.support.annotation.NonNull; 20 import android.text.SpannableString; 21 import android.text.Spanned; 22 import android.text.style.TypefaceSpan; 23 import com.android.dialer.common.Assert; 24 25 /** 26 * Creates {@link SpannableString SpannableStrings} which are styled appropriately for Dialer 27 * content with "Learn more" links. 28 * 29 * <p>Example usage: 30 * 31 * <pre> 32 * TextView content = ...; 33 * ContentWithLearnMoreSpanner creator = new ContentWithLearnMoreSpanner(getApplicationContext()); 34 * // myFeatureContent: "Try my feature. <xliff:g example="Learn more">%1$s</xliff:g>" 35 * String content = getString(R.string.myFeatureContent); 36 * 37 * SpannableString spannable = creator.create(content, "https://www.myFeatureHelp.com"); 38 * content.setText(spannable); 39 * </pre> 40 * 41 * Users will see: "Try my feature. Learn more" where "Learn more" links to the given url. 42 */ 43 public final class ContentWithLearnMoreSpanner { 44 45 private final Context context; 46 ContentWithLearnMoreSpanner(@onNull Context context)47 public ContentWithLearnMoreSpanner(@NonNull Context context) { 48 this.context = context.getApplicationContext(); 49 } 50 51 /** 52 * Creates a spannable string using the given content and learn more url. 53 * 54 * @param contentFormatString a format string {@see java.util.Formatter} with a single string 55 * format parameter, e.g. "Try my feature. %1$s". 56 * @param learnMoreUrl a url which the "Learn more" text will link to. 57 * @return a {@link SpannableString}. This string is put together by inserting the text "Learn 58 * more" into the given {@code contentFormatString}, setting "Learn more" to link to the given 59 * {@code learnMoreUrl}, then styling the "Learn more" text with common Dialer learn more 60 * styling. The "Learn more" text uses a non-breaking-space character to ensure it says on a 61 * single line. 62 * @throws java.util.IllegalFormatException if {@code contentFormatString} has an improper format 63 * @throws IllegalArgumentException if it wasn't possible to add "Learn more" to the given 64 * contentFormatString 65 */ 66 @NonNull create(@onNull String contentFormatString, @NonNull String learnMoreUrl)67 public SpannableString create(@NonNull String contentFormatString, @NonNull String learnMoreUrl) { 68 String learnMore = context.getString(R.string.general_learn_more); 69 70 SpannableString contents = new SpannableString(String.format(contentFormatString, learnMore)); 71 72 Assert.checkArgument( 73 contents.toString().contains(learnMore), 74 "Couldn't add learn more link to %s", 75 contentFormatString); 76 77 int learnMoreSpanStartIndex = contents.toString().lastIndexOf(learnMore); 78 int learnMoreSpanEndIndex = learnMoreSpanStartIndex + learnMore.length(); 79 80 contents.setSpan( 81 new TypefaceSpan("sans-serif-medium"), 82 learnMoreSpanStartIndex, 83 learnMoreSpanEndIndex, 84 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 85 86 contents.setSpan( 87 new UrlSpanWithoutUnderline(learnMoreUrl), 88 learnMoreSpanStartIndex, 89 learnMoreSpanEndIndex, 90 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 91 92 return contents; 93 } 94 } 95