android.text.SpannableStringBuilder#append ( )源码实例Demo

下面列出了android.text.SpannableStringBuilder#append ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: 365browser   文件: AnswerTextBuilder.java
/**
 * Builds a Spannable containing all of the styled text in the supplied ImageLine.
 *
 * @param line All text fields within this line will be added to the returned Spannable.
 *             types.
 * @param metrics Font metrics which will be used to properly size and layout images and top-
 *                aligned text.
 * @param density Screen density which will be used to properly size and layout images and top-
 *                aligned text.
 */
static Spannable buildSpannable(
        SuggestionAnswer.ImageLine line, Paint.FontMetrics metrics, float density) {
    SpannableStringBuilder builder = new SpannableStringBuilder();

    // Determine the height of the largest text element in the line.  This
    // will be used to top-align text and scale images.
    int maxTextHeightSp = getMaxTextHeightSp(line);

    List<SuggestionAnswer.TextField> textFields = line.getTextFields();
    for (int i = 0; i < textFields.size(); i++) {
        appendAndStyleText(builder, textFields.get(i), maxTextHeightSp, metrics, density);
    }
    if (line.hasAdditionalText()) {
        builder.append("  ");
        SuggestionAnswer.TextField additionalText = line.getAdditionalText();
        appendAndStyleText(builder, additionalText, maxTextHeightSp, metrics, density);
    }
    if (line.hasStatusText()) {
        builder.append("  ");
        SuggestionAnswer.TextField statusText = line.getStatusText();
        appendAndStyleText(builder, statusText, maxTextHeightSp, metrics, density);
    }

    return builder;
}
 
源代码2 项目: AIIA-DNN-benchmark   文件: ImageClassifierTF.java
/** Classifies a frame from the preview stream. */
void classifyFrame(Bitmap bitmap, SpannableStringBuilder builder) {
  if (tflite == null) {
    Log.e(TAG, "Image classifier has not been initialized; Skipped.");
    builder.append(new SpannableString("Uninitialized Classifier."));
  }
  convertBitmapToByteBuffer(bitmap);
  // Here's where the magic happens!!!
  long startTime = SystemClock.uptimeMillis();
  runInference();
  long endTime = SystemClock.uptimeMillis();
  Log.d(TAG, "Timecost to run model inference: " + Long.toString(endTime - startTime));

  // Smooth the results across frames.
  applyFilter();

  // Print the results.
  printTopKLabels(builder);
  long duration = endTime - startTime;
  SpannableString span = new SpannableString(duration + " ms");
  span.setSpan(new ForegroundColorSpan(android.graphics.Color.LTGRAY), 0, span.length(), 0);
  builder.append(span);
}
 
源代码3 项目: AndroidChromium   文件: InfoBarLayout.java
/**
 * Prepares text to be displayed as the infobar's main message, including setting up a
 * clickable link if the infobar requires it.
 */
private CharSequence prepareMainMessageString() {
    SpannableStringBuilder fullString = new SpannableStringBuilder();

    if (mMessageMainText != null) fullString.append(mMessageMainText);

    // Concatenate the text to display for the link and make it clickable.
    if (!TextUtils.isEmpty(mMessageLinkText)) {
        if (fullString.length() > 0) fullString.append(" ");
        int spanStart = fullString.length();

        fullString.append(mMessageLinkText);
        fullString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View view) {
                mInfoBarView.onLinkClicked();
            }
        }, spanStart, fullString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return fullString;
}
 
源代码4 项目: FastTextView   文件: ReadMoreTextView.java
@NonNull
@Override
protected StaticLayout makeLayout(CharSequence text, int maxWidth, boolean exactly) {
  mWithEllipsisLayout = super.makeLayout(text, maxWidth, exactly);
  SpannableStringBuilder textWithExtraEnd = new SpannableStringBuilder(text);
  textWithExtraEnd.append(COLLAPSE_NORMAL);
  if (mCollapseSpan != null) {
    textWithExtraEnd.setSpan(mCollapseSpan, textWithExtraEnd.length() - 1,
        textWithExtraEnd.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
  }
  StaticLayoutBuilderCompat layoutBuilder =
      createAllStaticLayoutBuilder(textWithExtraEnd, 0, textWithExtraEnd.length(), getPaint(),
          maxWidth > 0 ? Math.min(maxWidth, mWithEllipsisLayout.getWidth()) :
              mWithEllipsisLayout.getWidth());
  layoutBuilder.setLineSpacing(mAttrsHelper.mSpacingAdd, mAttrsHelper.mSpacingMultiplier)
      .setAlignment(TextViewAttrsHelper.getLayoutAlignment(this, getGravity()))
      .setIncludePad(true);
  beforeAllStaticLayoutBuild(layoutBuilder);
  mAllTextLayout = layoutBuilder.build();
  return mWithEllipsisLayout;
}
 
源代码5 项目: droidkaigi2016   文件: AppUtil.java
public static void linkify(Activity activity, TextView textView, String linkText, String url) {
    String text = textView.getText().toString();

    SpannableStringBuilder builder = new SpannableStringBuilder();
    builder.append(text);
    builder.setSpan(
            new ClickableSpan() {
                @Override
                public void onClick(View view) {
                    showWebPage(activity, url);
                }
            },
            text.indexOf(linkText),
            text.indexOf(linkText) + linkText.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    );

    textView.setText(builder);
    textView.setMovementMethod(LinkMovementMethod.getInstance());
}
 
源代码6 项目: RxAndroidBootstrap   文件: EditTextUtil.java
/**
     * Sets the edittext's hint icon and text.
     *
     * @param editText
     * @param drawableResource
     * @param hintText
     */
    public static void setSearchHintWithColorIcon(EditText editText, int drawableResource, int textColor, String hintText) {
        try {

            SpannableStringBuilder stopHint = new SpannableStringBuilder("   ");
            stopHint.append(hintText);

// Add the icon as an spannable
            Drawable searchIcon = editText.getContext().getResources().getDrawable(drawableResource);
            Float rawTextSize = editText.getTextSize();
            int textSize = (int) (rawTextSize * 1.25);
            searchIcon.setBounds(0, 0, textSize, textSize);
            stopHint.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            // Set the new hint text
            editText.setHint(stopHint);
            //searchBox.setTextColor(Color.WHITE);
            editText.setHintTextColor(textColor);

        } catch (Exception e) {
            Log.e("EditTextUtil", e.getMessage(), e);
        }
    }
 
源代码7 项目: AndFChat   文件: ChatEntry.java
public Spannable getChatMessage(Context context) {
    if (spannedText == null) {
        Spannable dateSpan = createDateSpannable(context);
        Spannable textSpan = createText(context);

        // Time
        SpannableStringBuilder finishedText = new SpannableStringBuilder(dateSpan);
        // Delimiter
        finishedText.append(delimiterBetweenDateAndName);
        // Name
        finishedText.append(new NameSpannable(owner, getNameColorId(), context.getResources()));
        // Delimiter
        finishedText.append(delimiterBetweenNameAndText);
        // Message
        finishedText.append(textSpan);

        // Add overall styles
        if (getTypeFace() != null) {
            finishedText.setSpan(new StyleSpan(getTypeFace()), DATE_CHAR_LENGTH, finishedText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }

        spannedText = finishedText;
    }
    return spannedText;
}
 
源代码8 项目: Yahala-Messenger   文件: GroupCreateActivity.java
public XImageSpan createAndPutChipForUser(TLRPC.User user) {
    LayoutInflater lf = (LayoutInflater) parentActivity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    View textView = lf.inflate(R.layout.group_create_bubble, null);
    TextView text = (TextView) textView.findViewById(R.id.bubble_text_view);
    String name = Utilities.formatName(user.first_name, user.last_name);
    if (name.length() == 0 && user.phone != null && user.phone.length() != 0) {
        name = PhoneFormat.getInstance().format("+" + user.phone);
    }
    text.setText(name + ", ");

    int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    textView.measure(spec, spec);
    textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
    Bitmap b = Bitmap.createBitmap(textView.getWidth(), textView.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(b);
    canvas.translate(-textView.getScrollX(), -textView.getScrollY());
    textView.draw(canvas);
    textView.setDrawingCacheEnabled(true);
    Bitmap cacheBmp = textView.getDrawingCache();
    Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
    textView.destroyDrawingCache();

    final BitmapDrawable bmpDrawable = new BitmapDrawable(b);
    bmpDrawable.setBounds(0, 0, b.getWidth(), b.getHeight());

    SpannableStringBuilder ssb = new SpannableStringBuilder("");
    XImageSpan span = new XImageSpan(bmpDrawable, ImageSpan.ALIGN_BASELINE);
    allSpans.add(span);
    selectedContacts.put(user.jid, span);
    for (ImageSpan sp : allSpans) {
        ssb.append("<<");
        ssb.setSpan(sp, ssb.length() - 2, ssb.length(), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    userSelectEditText.setText(ssb);
    userSelectEditText.setSelection(ssb.length());
    return span;
}
 
源代码9 项目: EhViewer   文件: GalleryListScene.java
@Override
public CharSequence getText(float textSize) {
    Drawable bookImage = DrawableManager.getVectorDrawable(getContext2(), R.drawable.v_book_open_x24);
    SpannableStringBuilder ssb = new SpannableStringBuilder("    ");
    ssb.append(getResources2().getString(R.string.gallery_list_search_bar_open_gallery));
    int imageSize = (int) (textSize * 1.25);
    if (bookImage != null) {
        bookImage.setBounds(0, 0, imageSize, imageSize);
        ssb.setSpan(new ImageSpan(bookImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    return ssb;
}
 
源代码10 项目: FoldText_Java   文件: SpannableFoldTextView.java
/**
 * 增加提示文字
 *
 * @param span
 * @param type
 */
private void addTip(SpannableStringBuilder span, BufferType type) {
    if (!(isExpand && !isShowTipAfterExpand)) {
        //折叠或者展开并且展开后显示提示
        if (mTipGravity == END) {
            span.append("  ");
        } else {
            span.append("\n");
        }
        int length;
        if (isExpand) {
            span.append(mExpandText);
            length = mExpandText.length();
        } else {
            span.append(mFoldText);
            length = mFoldText.length();
        }
        if (mTipClickable) {
            span.setSpan(mSpan, span.length() - length, span.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            if (isParentClick) {
                setMovementMethod(MyLinkMovementMethod.getInstance());
                setClickable(false);
                setFocusable(false);
                setLongClickable(false);
            } else {
                setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
        span.setSpan(new ForegroundColorSpan(mTipColor), span.length() - length, span.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    }
    super.setText(span, type);
}
 
源代码11 项目: adt-leanback-support   文件: StreamingTextView.java
public void updateRecognizedText(String stableText, String pendingText) {
    if (DEBUG) Log.d(TAG, "updateText(" + stableText + "," + pendingText + ")");

    if (stableText == null) {
        stableText = "";
    }

    SpannableStringBuilder displayText = new SpannableStringBuilder(stableText);

    if (DOTS_FOR_STABLE) {
        addDottySpans(displayText, stableText, 0);
    }

    if (pendingText != null) {
        int pendingTextStart = displayText.length();
        displayText.append(pendingText);
        if (DOTS_FOR_PENDING) {
            addDottySpans(displayText, pendingText, pendingTextStart);
        } else {
            int pendingColor = getResources().getColor(
                    R.color.lb_search_plate_hint_text_color);
            addColorSpan(displayText, pendingColor, pendingText, pendingTextStart);
        }
    }

    // Start streaming in dots from beginning of partials, or current position,
    // whichever is larger
    mStreamPosition = Math.max(stableText.length(), mStreamPosition);

    // Copy the text and spans to a SpannedString, since editable text
    // doesn't redraw in invalidate() when hardware accelerated
    // if the text or spans havent't changed. (probably a framework bug)
    updateText(new SpannedString(displayText));

    if (ANIMATE_DOTS_FOR_PENDING) {
        startStreamAnimation();
    }
}
 
源代码12 项目: mvvm-template   文件: HrHandler.java
@Override public void handleTagNode(TagNode tagNode, SpannableStringBuilder spannableStringBuilder, int i, int i1) {
    spannableStringBuilder.append("\n");
    SpannableStringBuilder builder = new SpannableStringBuilder("$");
    HrSpan hrSpan = new HrSpan(color, width);
    builder.setSpan(hrSpan, 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.setSpan(new CenterSpan(), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.append("\n");
    spannableStringBuilder.append(builder);
}
 
源代码13 项目: lttrs-android   文件: BindingAdapters.java
@BindingAdapter("android:text")
public static void setText(TextView text, SubjectWithImportance subjectWithImportance) {
    if (subjectWithImportance == null || subjectWithImportance.subject == null) {
        text.setText(null);
        return;
    }
    if (subjectWithImportance.important) {
        SpannableStringBuilder header = new SpannableStringBuilder(subjectWithImportance.subject);
        header.append("\u2004\u00bb"); // 1/3 em - 1/2 em would be 2002
        header.setSpan(new ImageSpan(text.getContext(), R.drawable.ic_important_amber_22sp, DynamicDrawableSpan.ALIGN_BASELINE), header.length() - 1, header.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        text.setText(header);
    } else {
        text.setText(subjectWithImportance.subject);
    }
}
 
源代码14 项目: EhViewer   文件: GalleryListScene.java
private void setSearchBarHint(Context context, SearchBar searchBar) {
    Resources resources = context.getResources();
    Drawable searchImage = DrawableManager.getVectorDrawable(context, R.drawable.v_magnify_x24);
    SpannableStringBuilder ssb = new SpannableStringBuilder("   ");
    ssb.append(resources.getString(EhUrl.SITE_EX == Settings.getGallerySite() ?
            R.string.gallery_list_search_bar_hint_exhentai :
            R.string.gallery_list_search_bar_hint_e_hentai));
    int textSize = (int) (searchBar.getEditTextTextSize() * 1.25);
    if (searchImage != null) {
        searchImage.setBounds(0, 0, textSize, textSize);
        ssb.setSpan(new ImageSpan(searchImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    searchBar.setEditTextHint(ssb);
}
 
源代码15 项目: RxAndroidBootstrap   文件: SearchViewUtil.java
/**
     * Sets the searchview's hint icon and text.
     *
     * @param searchView
     * @param drawableResource
     * @param hintText
     */
    public static void setSearchHintIcon(SearchView searchView, int drawableResource, String hintText) {
        try {
            // Accessing the SearchAutoComplete
            int queryTextViewId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
            View autoComplete = searchView.findViewById(queryTextViewId);

            //Class<?> clazz = Class.forName("android.widget.SearchView$SearchAutoComplete");

            TextView searchBox = (TextView) searchView.findViewById(R.id.search_src_text);


            SpannableStringBuilder stopHint = new SpannableStringBuilder("   ");
            stopHint.append(hintText);

// Add the icon as an spannable
            Drawable searchIcon = searchView.getContext().getResources().getDrawable(drawableResource);
            Float rawTextSize = searchBox.getTextSize();
            int textSize = (int) (rawTextSize * 1.25);
            searchIcon.setBounds(0, 0, textSize, textSize);
            stopHint.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            // Set the new hint text
            searchBox.setHint(stopHint);
            //searchBox.setTextColor(Color.WHITE);
            searchBox.setHintTextColor(Color.LTGRAY);

        } catch (Exception e) {
            Log.e("SearchView", e.getMessage(), e);
        }
    }
 
源代码16 项目: Slide   文件: PopulateSubmissionViewHolder.java
public void doText(SubmissionViewHolder holder, Submission submission, Context mContext,
        String baseSub, boolean full) {
    SpannableStringBuilder t = SubmissionCache.getTitleLine(submission, mContext);
    SpannableStringBuilder l = SubmissionCache.getInfoLine(submission, mContext, baseSub);
    SpannableStringBuilder c = SubmissionCache.getCrosspostLine(submission, mContext);

    int[] textSizeAttr = new int[]{R.attr.font_cardtitle, R.attr.font_cardinfo};
    TypedArray a = mContext.obtainStyledAttributes(textSizeAttr);
    int textSizeT = a.getDimensionPixelSize(0, 18);
    int textSizeI = a.getDimensionPixelSize(1, 14);


    t.setSpan(new AbsoluteSizeSpan(textSizeT), 0, t.length(), 0);
    l.setSpan(new AbsoluteSizeSpan(textSizeI), 0, l.length(), 0);

    SpannableStringBuilder s = new SpannableStringBuilder();
    if (SettingValues.titleTop) {
        s.append(t);
        s.append("\n");
        s.append(l);
    } else {
        s.append(l);
        s.append("\n");
        s.append(t);
    }
    if(!full && c != null){
        c.setSpan(new AbsoluteSizeSpan(textSizeI), 0, c.length(), 0);
        s.append("\n");
        s.append(c);
    }
    a.recycle();

    holder.title.setText(s);

}
 
源代码17 项目: android_9.0.0_r45   文件: SearchView.java
private CharSequence getDecoratedHint(CharSequence hintText) {
    // If the field is always expanded or we don't have a search hint icon,
    // then don't add the search icon to the hint.
    if (!mIconifiedByDefault || mSearchHintIcon == null) {
        return hintText;
    }

    final int textSize = (int) (mSearchSrcTextView.getTextSize() * 1.25);
    mSearchHintIcon.setBounds(0, 0, textSize, textSize);

    final SpannableStringBuilder ssb = new SpannableStringBuilder("   ");
    ssb.setSpan(new ImageSpan(mSearchHintIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.append(hintText);
    return ssb;
}
 
源代码18 项目: EhViewer   文件: FavoritesScene.java
private void updateSearchBar() {
    Context context = getContext2();
    if (null == context || null == mUrlBuilder || null == mSearchBar || null == mFavCatArray) {
        return;
    }

    // Update title
    int favCat = mUrlBuilder.getFavCat();
    String favCatName;
    if (favCat >= 0 && favCat < 10) {
        favCatName = mFavCatArray[favCat];
    } else if (favCat == FavListUrlBuilder.FAV_CAT_LOCAL) {
        favCatName = getString(R.string.local_favorites);
    } else {
        favCatName = getString(R.string.cloud_favorites);
    }
    String keyword = mUrlBuilder.getKeyword();
    if (TextUtils.isEmpty(keyword)) {
        if (!ObjectUtils.equal(favCatName, mOldFavCat)) {
            mSearchBar.setTitle(getString(R.string.favorites_title, favCatName));
        }
    } else {
        if (!ObjectUtils.equal(favCatName, mOldFavCat) || !ObjectUtils.equal(keyword, mOldKeyword)) {
            mSearchBar.setTitle(getString(R.string.favorites_title_2, favCatName, keyword));
        }
    }

    // Update hint
    if (!ObjectUtils.equal(favCatName, mOldFavCat)) {
        Drawable searchImage = DrawableManager.getVectorDrawable(context, R.drawable.v_magnify_x24);
        SpannableStringBuilder ssb = new SpannableStringBuilder("   ");
        ssb.append(getString(R.string.favorites_search_bar_hint, favCatName));
        int textSize = (int) (mSearchBar.getEditTextTextSize() * 1.25);
        if (searchImage != null) {
            searchImage.setBounds(0, 0, textSize, textSize);
            ssb.setSpan(new ImageSpan(searchImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        mSearchBar.setEditTextHint(ssb);
    }

    mOldFavCat = favCatName;
    mOldKeyword = keyword;

    // Save recent fav cat
    Settings.putRecentFavCat(mUrlBuilder.getFavCat());
}
 
@Override
public Notification buildNotification(Context context) {
    Notification.Builder builder = buildBasicNotification(context);

    Notification.BigTextStyle style = new Notification.BigTextStyle();

    SpannableStringBuilder title = new SpannableStringBuilder();
    appendStyled(title, "Stylized", new StyleSpan(Typeface.BOLD_ITALIC));
    title.append(" title");
    SpannableStringBuilder text = new SpannableStringBuilder("Stylized text: ");
    appendStyled(text, "C", new ForegroundColorSpan(Color.RED));
    appendStyled(text, "O", new ForegroundColorSpan(Color.GREEN));
    appendStyled(text, "L", new ForegroundColorSpan(Color.BLUE));
    appendStyled(text, "O", new ForegroundColorSpan(Color.YELLOW));
    appendStyled(text, "R", new ForegroundColorSpan(Color.MAGENTA));
    appendStyled(text, "S", new ForegroundColorSpan(Color.CYAN));
    text.append("; ");
    appendStyled(text, "1.25x size", new RelativeSizeSpan(1.25f));
    text.append("; ");
    appendStyled(text, "0.75x size", new RelativeSizeSpan(0.75f));
    text.append("; ");
    appendStyled(text, "underline", new UnderlineSpan());
    text.append("; ");
    appendStyled(text, "strikethrough", new StrikethroughSpan());
    text.append("; ");
    appendStyled(text, "bold", new StyleSpan(Typeface.BOLD));
    text.append("; ");
    appendStyled(text, "italic", new StyleSpan(Typeface.ITALIC));
    text.append("; ");
    appendStyled(text, "sans-serif-thin", new TypefaceSpan("sans-serif-thin"));
    text.append("; ");
    appendStyled(text, "monospace", new TypefaceSpan("monospace"));
    text.append("; ");
    appendStyled(text, "sub", new SubscriptSpan());
    text.append("script");
    appendStyled(text, "super", new SuperscriptSpan());

    style.setBigContentTitle(title);
    style.bigText(text);

    builder.setStyle(style);
    return builder.build();
}
 
源代码20 项目: MediaSDK   文件: Cea608Decoder.java
public Cue build(@Cue.AnchorType int forcedPositionAnchor) {
  SpannableStringBuilder cueString = new SpannableStringBuilder();
  // Add any rolled up captions, separated by new lines.
  for (int i = 0; i < rolledUpCaptions.size(); i++) {
    cueString.append(rolledUpCaptions.get(i));
    cueString.append('\n');
  }
  // Add the current line.
  cueString.append(buildCurrentLine());

  if (cueString.length() == 0) {
    // The cue is empty.
    return null;
  }

  int positionAnchor;
  // The number of empty columns before the start of the text, in the range [0-31].
  int startPadding = indent + tabOffset;
  // The number of empty columns after the end of the text, in the same range.
  int endPadding = SCREEN_CHARWIDTH - startPadding - cueString.length();
  int startEndPaddingDelta = startPadding - endPadding;
  if (forcedPositionAnchor != Cue.TYPE_UNSET) {
    positionAnchor = forcedPositionAnchor;
  } else if (captionMode == CC_MODE_POP_ON
      && (Math.abs(startEndPaddingDelta) < 3 || endPadding < 0)) {
    // Treat approximately centered pop-on captions as middle aligned. We also treat captions
    // that are wider than they should be in this way. See
    // https://github.com/google/ExoPlayer/issues/3534.
    positionAnchor = Cue.ANCHOR_TYPE_MIDDLE;
  } else if (captionMode == CC_MODE_POP_ON && startEndPaddingDelta > 0) {
    // Treat pop-on captions with less padding at the end than the start as end aligned.
    positionAnchor = Cue.ANCHOR_TYPE_END;
  } else {
    // For all other cases assume start aligned.
    positionAnchor = Cue.ANCHOR_TYPE_START;
  }

  float position;
  switch (positionAnchor) {
    case Cue.ANCHOR_TYPE_MIDDLE:
      position = 0.5f;
      break;
    case Cue.ANCHOR_TYPE_END:
      position = (float) (SCREEN_CHARWIDTH - endPadding) / SCREEN_CHARWIDTH;
      // Adjust the position to fit within the safe area.
      position = position * 0.8f + 0.1f;
      break;
    case Cue.ANCHOR_TYPE_START:
    default:
      position = (float) startPadding / SCREEN_CHARWIDTH;
      // Adjust the position to fit within the safe area.
      position = position * 0.8f + 0.1f;
      break;
  }

  int lineAnchor;
  int line;
  // Note: Row indices are in the range [1-15].
  if (captionMode == CC_MODE_ROLL_UP || row > (BASE_ROW / 2)) {
    lineAnchor = Cue.ANCHOR_TYPE_END;
    line = row - BASE_ROW;
    // Two line adjustments. The first is because line indices from the bottom of the window
    // start from -1 rather than 0. The second is a blank row to act as the safe area.
    line -= 2;
  } else {
    lineAnchor = Cue.ANCHOR_TYPE_START;
    // Line indices from the top of the window start from 0, but we want a blank row to act as
    // the safe area. As a result no adjustment is necessary.
    line = row;
  }

  return new Cue(
      cueString,
      Alignment.ALIGN_NORMAL,
      line,
      Cue.LINE_TYPE_NUMBER,
      lineAnchor,
      position,
      positionAnchor,
      Cue.DIMEN_UNSET);
}