想要使用StringBuilder添加带有TextView数字的上标

时间:2019-03-19 12:06:38

标签: java android kotlin

public class SuperscriptFormatter {
    private static final String SUPERSCRIPT_REGEX = "(?<=\\b\\d{0,10})(st|nd|rd|th)(?=\\b)";
    private static final Pattern PATTERN = Pattern.compile(SUPERSCRIPT_REGEX);
    private static final float PROPORTION = 0.5f;

    private final SpannableStringBuilder stringBuilder;

    public SuperscriptFormatter (@NonNull SpannableStringBuilder stringBuilder) {
        this.stringBuilder = stringBuilder;
    }

    public void format(TextView textView) {
        CharSequence text = textView.getText();
        Matcher matcher = PATTERN.matcher(text);
        stringBuilder.clear();
        stringBuilder.append(text);
        while (matcher.find()) {
            int start = matcher.start();
            int end = matcher.end();
            createSuperscriptSpan(start, end);
        }
        textView.setText(stringBuilder);
    }

    private void createSuperscriptSpan(int start, int end) {
        SuperscriptSpan superscript = new SuperscriptSpan();
        RelativeSizeSpan size = new RelativeSizeSpan(PROPORTION);
        stringBuilder.setSpan(superscript, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        stringBuilder.setSpan(size, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

问题是我无法获得带有数字的上标。 我正在传递“ 1”,“ 2”作为文本,而matcher.find()每次都返回false,我不知道模式或文本发生了什么。 我想要第一,第二,第三...等作为文本

2 个答案:

答案 0 :(得分:1)

In above code there You have to set the text in your Activity class or .xml file in layout folder.

textView.setText( "21st, 22nd, 11th, 13th");

or xml file textview

android:text= "21st, 22nd, 11th, 13th"

like this there are no auto put superscript in there.

答案 1 :(得分:0)

我写了我自己的逻辑,用数字加上标。 在这里,我正在使用Kotlin开发RecyclerView适配器,我正在共享onBindViewHolder的代码。

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="styles.css">
</head>

<body>

  <div id="reserve_form" class="container1">

    <div id="pickup_date">
      <p>
        <label class="form">Todays Date:</label>
        <input type="date" class="textbox" id="pick_date" name="pickup_date" disabled onchange="cal()">
      </p>
    </div>

    <div id="dropoff_date">
      <p>
        <label class="form">Dropoff Date:</label>
        <input type="date" class="textbox" id="drop_date" name="dropoff_date" />
      </p>
    </div>

    <div id="numdays">
      <label class="form">Number of days:</label>
      <input type="text" class="textbox" id="numdays2" name="numdays" />
    </div>

  </div>
</body>

</html>

}

// start和end是超级脚本开始和停止的索引

    var stringBuilder: SpannableStringBuilder = SpannableStringBuilder()


  override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    // for 1 till 9
    if (yourNo  in 1..9) {
        if (yourNo  == 1)
            changeSuperScripts(1, 3, yourNo + "st", holder.textView)
        else if (contestStandingItem.rank == 2)
            changeSuperScripts(1, 3, yourNo + "nd", holder.textView)
        else if (contestStandingItem.rank == 3) {
            changeSuperScripts(1, 3, yourNo + "rd", holder.textView)
        } else
            changeSuperScripts(1, 3, yourNo + "th", holder.textView)
    }

    // for 10 till 19
    else if (yourNo  in 10..19)
        changeSuperScripts(2, 4, yourNo  + "th", holder.textView)


    // for 20 till 99
    else if(yourNo  in 20..99) {
         if (yourNo  % 10 == 0)
            changeSuperScripts(2, 4, yourNo  + "th", holder.textView)
        else if (yourNo  % 10 == 1)
            changeSuperScripts(2, 4, yourNo  + "st", holder.textView)
        else if (yourNo  % 10 == 2)
            changeSuperScripts(2, 4, yourNo  + "nd", holder.textView)
        else if (yourNo  % 10 == 3)
            changeSuperScripts(2, 4, yourNo  + "rd", holder.textView)
        else
            changeSuperScripts(2, 4, yourNo  + "th", holder.textView)
    }

    // for 100 till 999
    else if (yourNo  in 100..999){
        if (yourNo  % 10 == 0)
            changeSuperScripts(3, 5, yourNo  + "th", holder.textView)
        else if (yourNo  % 10 == 1)
            changeSuperScripts(3, 5, yourNo  + "st", holder.textView)
        else if (yourNo  % 10 == 2)
            changeSuperScripts(3, 5, yourNo  + "nd", holder.textView)
        else if (yourNo  % 10 == 3)
            changeSuperScripts(3, 5, yourNo  + "rd", holder.textView)
        else
            changeSuperScripts(3, 5, yourNo  + "th", holder.textView)
    }

//这是一个用Java编写的用于将文本转换为上标的单独类,我已使其每次使用同一对象成为单例(仅用于性能)

公共类OrdinalSuperscriptFormatter {

     fun changeSuperScripts(start: Int, end: Int, text: String, textView: TextView) {
    stringBuilder.clear()
    stringBuilder.append(text)
    val formatter = OrdinalSuperscriptFormatter.getInstance(stringBuilder)
    formatter.createSuperscriptSpan(start, end, textView)
}

}

//当您再次开始活动或再次启动fragmnet刷新列表时,会刷新

public static OrdinalSuperscriptFormatter ordinalSuperscriptFormatter;

private static final String SUPERSCRIPT_REGEX = "(?<=\\b\\d{0,10})(st|nd|rd|th)(?=\\b)";
private static final Pattern PATTERN = Pattern.compile(SUPERSCRIPT_REGEX);
private static final float PROPORTION = 0.5f;
SuperscriptSpan superscript = new SuperscriptSpan();
RelativeSizeSpan size = new RelativeSizeSpan(PROPORTION);

private final SpannableStringBuilder stringBuilder;

public static OrdinalSuperscriptFormatter getInstance(SpannableStringBuilder stringBuilder){
    if (ordinalSuperscriptFormatter == null) {
        ordinalSuperscriptFormatter = new OrdinalSuperscriptFormatter(stringBuilder);
        return  ordinalSuperscriptFormatter;
    }
    else
        return  ordinalSuperscriptFormatter;
}

public static void refreshInstance(){
    ordinalSuperscriptFormatter = null;
}

private OrdinalSuperscriptFormatter(@NonNull SpannableStringBuilder stringBuilder) {
    this.stringBuilder = stringBuilder;
}

public void createSuperscriptSpan(int start, int end,TextView textView) {
    stringBuilder.setSpan(superscript, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    stringBuilder.setSpan(size, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(stringBuilder);
}