txt文件中的可点击单词

时间:2018-07-16 10:26:36

标签: android string clickable spannablestring

我使用以下代码从textview的文件夹中读取了一个.txt文件:

    String txt = "";
        StringBuffer sbuffer1 = new StringBuffer();
        InputStream is = this.getResources().openRawResource(R.raw.file);
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        try {

            while ((txt = reader.readLine()) !=null){
                sbuffer1.append(txt + "\n");

            }
            textview.setText(sbuffer1);
            is.close();

        }catch(Exception e) {
            e.printStackTrace();
     }

.txt文件包含一个很长的文本,我希望该文本的特定单词可以单击,当单击特定单词时,我想显示一条敬酒消息。我怎样才能做到这一点?

这是spannablestring的示例代码,但是我不知道如何在我的代码案例中应用它:

    String text = " what do I put here??";
    SpannableString ss = new SpannableString(text);
    ClickableSpan clickableSpan1 = new ClickableSpan() {
           @Override
           public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "One", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void updateDrawState(TextPaint ds) {

                super.updateDrawState(ds);
                ds.setColor(Color.BLUE);
                ds.setUnderlineText(false);
            }
        };

        ClickableSpan clickableSpan2 = new ClickableSpan() {

            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "Two", Toast.LENGTH_SHORT).show();
            }
         };

        ss.setSpan(clickableSpan1, 7, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            ss.setSpan(clickableSpan2, 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        textView.setText(ss);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }

2 个答案:

答案 0 :(得分:0)

尝试一下:

    String txt = "";

    StringBuilder sbuffer1 = new StringBuilder();
    InputStream is = this.getResources().openRawResource(R.raw.file);
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));

    try {

        while ((txt = reader.readLine()) !=null){
            sbuffer1.append(txt).append("\n");
        }

        is.close();
    }catch(Exception e) {
        e.printStackTrace();
    }

    String text = sbuffer1.toString();
    SpannableStringBuilder builder = new SpannableStringBuilder(text);

    ClickableSpan clickable0 = new ClickableSpan() {
        @Override
        public void onClick(View textView) {
            Toast.makeText(MainActivity.this, "word0", Toast.LENGTH_LONG).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(Color.BLUE);
            ds.setUnderlineText(true);
        }
    };

    ClickableSpan clickable1 = new ClickableSpan() {
        @Override
        public void onClick(View textView) {
            Toast.makeText(MainActivity.this, "word1", Toast.LENGTH_LONG).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(Color.BLUE);
            ds.setUnderlineText(true);
        }
    };

    String word0 = "word0";
    String word1 = "word1";

    builder.setSpan(clickable0, text.indexOf(word0), text.indexOf(word0) + word0.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.setSpan(clickable1, text.indexOf(word1), text.indexOf(word1) + word1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textview.setText(builder);
    textview.setMovementMethod(LinkMovementMethod.getInstance());

上面的代码是2个单词,您可以根据需要更改它们。希望我没有错字

答案 1 :(得分:0)

局限性:每个句子中只有一个单词可以点击,并且应该唯一

要知道应该点击哪个单词,我们需要创建句子结构,例如在json文件中(R.raw.sentences-句子.json)。

{
  "sentences": [
    {
      "phrase": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
      "target": "consectetur",
      "action": "consectetur!"
    },
    {
      "phrase": "Maecenas dictum massa laoreet pellentesque auctor.",
      "target": "auctor",
      "action": "auctor!"
    },
    {
      "phrase": "Maecenas consequat, eros at finibus semper, neque sem euismod nisi, ac vulputate justo dui vitae urna.",
      "target": "vitae",
      "action": "vitae!"
    }
  ]
}

下一步是将json转换为字符串并进行解析。

private CharSequence rawToClickableSpanString(@RawRes int rawRes) {
    String str = streamToString(getResources().openRawResource(rawRes));
    return stringToSpannableString(str);
}

private CharSequence stringToSpannableString(String jsonString) {
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();

    Moshi moshi = new Moshi.Builder().build();
    JsonAdapter<Sentences> jsonAdapter = moshi.adapter(Sentences.class);
    Sentences sentences = null;

    try {
        sentences = jsonAdapter.fromJson(jsonString);
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (sentences != null) {
        for (SentencesItem sentencesItem : sentences.getSentences()) {
            final String target = sentencesItem.getTarget();
            final int start = sentencesItem.getPhrase().indexOf(target);
            final int end = start + target.length();

            SpannableString ss = new SpannableString(sentencesItem.getPhrase());
            ss.setSpan(new CustomClickableSpan(sentencesItem.getAction()) {

                @Override
                void onClick(View view, String action) {
                    Toast.makeText(view.getContext(), action, Toast.LENGTH_SHORT).show();
                }

            }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            spannableStringBuilder.append(ss);
            spannableStringBuilder.append("\n");
        }
    }

    CharSequence charSequence = null;

    if (spannableStringBuilder.length() > "\n".length()) {
        charSequence = spannableStringBuilder.subSequence(0, spannableStringBuilder.length() - "\n".length());
    }

    return charSequence;
}

public String streamToString(InputStream is) {
    StringBuilder sb = new StringBuilder();
    try {
        BufferedReader input = new BufferedReader(new InputStreamReader(is));
        String line;

        while ((line = input.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }

        if (sb.length() > "\n".length()) {
            sb.setLength(sb.length() - "\n".length());
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
    return sb.toString();
}

ClickableSpan应该存储要显示的文本,因此我们创建了自定义的ClickableSpan。

private abstract class CustomClickableSpan extends ClickableSpan {
    private String action;

    public CustomClickableSpan(String action) {
        this.action = action;
    }

    @Override
    public void onClick(View widget) {
        onClick(widget, action);
    }

    abstract void onClick(View widget, String action);
}

最后,我们将结果传递给textView并将其设置为可点击。

TextView textView = findViewById(R.id.textView1);
textView.setText(rawToClickableSpanString(R.raw.sentences));
textView.setMovementMethod(LinkMovementMethod.getInstance());

enter image description here


我已经使用Moshi库解析pojo json:

implementation 'com.squareup.retrofit2:converter-moshi:2.0.0'

和注释库

implementation 'org.glassfish:javax.annotation:10.0-b28'

来自json文件的pojo的类:

@Generated("com.robohorse.robopojogenerator")
public class Sentences{

    @Json(name = "sentences")
    private List<SentencesItem> sentences;

    public void setSentences(List<SentencesItem> sentences){
        this.sentences = sentences;
    }

    public List<SentencesItem> getSentences(){
        return sentences;
    }

    @Override
    public String toString(){
        return 
            "Sentences{" + 
            "sentences = '" + sentences + '\'' + 
            "}";
        }
}

@Generated("com.robohorse.robopojogenerator")
public class SentencesItem{

    @Json(name = "phrase")
    private String phrase;

    @Json(name = "action")
    private String action;

    @Json(name = "target")
    private String target;

    public void setPhrase(String phrase){
        this.phrase = phrase;
    }

    public String getPhrase(){
        return phrase;
    }

    public void setAction(String action){
        this.action = action;
    }

    public String getAction(){
        return action;
    }

    public void setTarget(String target){
        this.target = target;
    }

    public String getTarget(){
        return target;
    }

    @Override
    public String toString(){
        return 
            "SentencesItem{" + 
            "phrase = '" + phrase + '\'' + 
            ",action = '" + action + '\'' + 
            ",target = '" + target + '\'' + 
            "}";
        }
}