【问题标题】:Android - get text position from textview with html dataAndroid - 从带有 html 数据的 textview 获取文本位置
【发布时间】:2016-07-26 10:31:44
【问题描述】:

我已将 html 数据设置为我的 textview。当我从 textview 中选择任何单词/字符时,我想将该单词加粗并用新的替换原始 html 数据。

String html = "<p>hello this is android testing</p>";

像这样我的 html 中可能有很多 html 标签。如果我想让“android”字加粗,如何用“android”替换原始html字符串。

我想要&lt;p&gt;hello this is &lt;strong&gt;android&lt;/strong&gt; testing&lt;/p&gt; 作为结果。

【问题讨论】:

  • 你的方法在哪里?
  • 如果我们从 textview 获取文本位置,它将返回您可以看到的文本中的位置,而不是来自 html 数据的实际位置。例如。 textview 将返回位置 14,但实际是 17。

标签: android textview


【解决方案1】:

使用 SelectableTextView 获取选中的文本。你可以在 github here 上看到这个实现。

检查答案here。这可能对你有帮助

你可以使用标签加粗,

 String string= "<b>" + android + "</b> " + remainingString;   

 textView.setText(Html.fromHtml(string));

【讨论】:

  • 好的,我会检查解决方案并通知您。谢谢
【解决方案2】:

您可以先将字符串内容设置到TextView,然后使用setCustomSelectionActionModeCallback(...) 截取TextView 中的选择。

在下面的示例中,所选单词将被 &lt;strong&gt;...&lt;/strong&gt; 包围。

例如选择“测试”将使以下字符串在 TextView 中可见。

你好,这是 android testing android bla bla android bla bla android bla

然后在已转换的 TextView 内容中选择“android”上的最后一个实例将使以下字符串在 TextVIew 中可见。

你好这是android测试android bla bla android bla bla android bla

代码:

public class MainActivity extends AppCompatActivity {

    String yourString = "<p>hello this is android testing android bla bla android bla bla android bla</p>";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView)findViewById(R.id.opening_today);
        tv.setText(Html.fromHtml(yourString));
        tv.setCustomSelectionActionModeCallback(new CallbackListener(tv));
    }

    class CallbackListener implements ActionMode.Callback{

        private TextView tv;
        private String strongS = "<strong>";
        private String strongE = "</strong>";

        public CallbackListener(TextView tv) {
            this.tv = tv;
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            int start = tv.getSelectionStart();
            int end = tv.getSelectionEnd();

            if( start == 0 && end == 0)
                return false;

            String content = tv.getText().toString();
            String token = content.substring(start, end);
            String before = content.substring(0, start);
            String after = content.substring(end, content.length());
            content = makeItStrong(before, after, token);
            tv.setText(Html.fromHtml(content));
            return false;
        }

        private String makeItStrong(String before, String after, String token){
            return cleanTags(before, strongS, strongE) + strongS + token + strongE + cleanTags(after, strongS, strongE);
        }

        private String cleanTags(String source, String... exp){
            for(String s: exp){
                source = source.replace(s, "");
            }
            return source;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return true; }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }

        @Override
        public void onDestroyActionMode(ActionMode mode) {}
    }
}

【讨论】:

  • 但我希望先在 html 中应用该更改,然后将 html 重新加载到 textview 以查看粗体更改。我想要“

    hello this is android testing

    ”结果。我的段落中可能有很多可能的 android 词,所以很难找到确切的。
  • 不行,我们正在设置 txtview.setText(Html.fromHtml(ourhtmldata));我们从干净的 html 字符串中获取选定的文本位置,它返回错误的位置。
  • @Kuldeep Sakhiya 请看看我的“最后”意图......如果它不是一个好的意图,也许我无法理解你真正需要的东西。顺便说一句,使用 txtview.setText(Html.fromHtml(ourhtmldata));您将始终从干净的 html 字符串中获得位置,因为此方法返回标签已“删除”的“Spanned”实例。
【解决方案3】:

使用下面的代码,可以多次高亮格式化文本,每次都可以得到所有高亮的累加结果。

int getOccuranceNumber(String text ,String selection, int selectionStartIndex){
    int index = text.indexOf(selection);
    int occuranceNumber = 0;
    while (index >= 0) {
        if(index == selectionStartIndex){
            return occuranceNumber;
        }else {
            index = text.indexOf(selection, index + 1);
            occuranceNumber++;
        }
    }
    return occuranceNumber;
}
int getOccuranceIndex(String text ,String selection, int occuranceNumber){
    int index = text.indexOf(selection);
    int i = 0;
    while (i!=occuranceNumber) {

            index = text.indexOf(selection, index + 1);
            i++;

    }
    return index;
}
public String toHex(String arg) {
    TextView textV = new TextView(context);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        textV.setText(Html.fromHtml(arg,Html.FROM_HTML_MODE_LEGACY));
    }else{
        textV.setText(Html.fromHtml(arg));
    }
    String textFormated ="";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        textFormated =  Html.toHtml((Spanned) textV.getText(),TO_HTML_PARAGRAPH_LINES_CONSECUTIVE).toString();
    }else{
        textFormated =  Html.toHtml((Spanned) textV.getText()).toString();
    }
    return textFormated.replace("<p dir=\"rtl\">","").replace("</p>","").replace("\n","");
}
public void highLightText(TextView textView){
    String textFormated ="";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        textFormated =  Html.toHtml((Spanned) textView.getText(),TO_HTML_PARAGRAPH_LINES_CONSECUTIVE).toString();
    }else{
        textFormated =  Html.toHtml((Spanned) textView.getText()).toString();
    }

    String text = textView.getText().toString();
    String selection = text.substring(textView.getSelectionStart(),textView.getSelectionEnd());
    int occuranceNum = getOccuranceNumber(text,selection,textView.getSelectionStart());
    String selectionHex = toHex(selection);

    int formatedTextSelectionStart = getOccuranceIndex(textFormated,selectionHex,occuranceNum);
    if(formatedTextSelectionStart<0)return;
    int formatedTextSelectionEnd = formatedTextSelectionStart + selectionHex.length();
    String formatedTextPart1 = textFormated.substring(0,formatedTextSelectionStart);
    String formatedTextPart2 = textFormated.substring(formatedTextSelectionStart,formatedTextSelectionEnd);
    String formatedTextPart3 = textFormated.substring(formatedTextSelectionEnd,textFormated.length());
    String colorOpenTag="<font color=\"#f7c627\">";
    String colorCloseTag="</font>";
    String finalText = formatedTextPart1+colorOpenTag+formatedTextPart2+colorCloseTag+formatedTextPart3;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        textView.setText(Html.fromHtml(finalText,Html.FROM_HTML_MODE_LEGACY));
    }else{
        textView.setText(Html.fromHtml(finalText));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 2012-03-09
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多