Android - 使用html数据从textview获取文本位置

时间:2016-04-06 07:17:16

标签: android textview

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

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

像这样,我的HTML可能有很多html标签。如果我想制作&#34; android&#34;单词粗体,如何用&#34; android &#34;替换原始html字符串。

我希望<p>hello this is <strong>android</strong> testing</p>为结果。

3 个答案:

答案 0 :(得分:1)

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

在下面的示例中,选定的单词将被<strong>...</strong>包围。

例如,选择“testing”将使以下字符串显示在TextView中。

  

你好这是android 测试 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) {}
    }
}

答案 1 :(得分:0)

使用SelectableTextView获取所选文本。您可以在github here上看到此实现。

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

你可以使用标签加粗

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

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

答案 2 :(得分:0)

使用以下代码,您可以多次突出显示格式化文本,并且每次都可以获得所有高光的累积结果。

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));
    }
}