android - 在 Android 的 EditText 中将 future 文本更改为粗体

标签 android android-edittext

我正在为 Android 制作一个基本的文本编辑器应用程序,目前正在处理文本格式。

我有一个名为 text_area 的 EditText,用户可以在其中键入文本,还有一个名为 bold 的 ToggleButton,用于将文本设置为粗体。最初,使用 EditText.setTypeface 方法,当按钮打开时,text_area 中的所有文本都会更改为粗体。使用 this question 中提供的答案,我只能将选定的文本更改为粗体。

我真正想做的是,当按下按钮时,所有先前输入的文本(正常和/或粗体)保持不变,并且用户接下来输入的任何内容都以粗体输入。

这是我的代码(有人也可以告诉我 else 语句下的代码的作用吗):

bold.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {

            if(bold.isChecked()==true) {
                Spannable str = textarea.getText();
                if(textarea.getSelectionEnd() > textarea.getSelectionStart())
                    str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
                            textarea.getSelectionStart(), textarea.getSelectionEnd(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                else
                    str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
                            textarea.getSelectionEnd(),
                            textarea.getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
    });

最佳答案

我遇到了同样的问题,经过几个小时的尝试,这就是我想到的。

首先,每当您选中粗体/斜体(无论您想要应用什么样式)复选框时,您都希望获取当前光标位置。

//if bold is checked
YourEditText.getSelectionStart(); 
YourEditText.getSelectionEnd(); 

如果没有突出显示文本,两者都会为您提供 EditText 的当前光标位置。

将此值存储到变量中。

int lastCursorPosition = YourEditText.getSelectionStart();

然后,我重写了 EditText 的 onTextChanged 函数。由于我们只想设置从最后一个光标位置到发生更改的末尾的跨度,因此我们将跨度设置为从lastCursorPosition到文本的末尾。

int endOfString = YourEditText.getText().toString().length();
StyleSpan ss = new StyleSpan(Typeface.BOLD);
str.setSpan(ss, lastCursorPosition, endOfString, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

在执行此操作时,我遇到了另一个问题。每当我将另一个跨度应用于文本的另一部分时,以前的样式就会消失。我通过在每次应用新样式时创建新的 StyleSpan 来解决此问题。需要理解的最少代码:

public static final int TYPEFACE_NORMAL = 0;
public static final int TYPEFACE_BOLD = 1;
public static final int TYPEFACE_ITALICS = 2;
public static final int TYPEFACE_BOLD_ITALICS = 3;

private int currentTypeface;
private int lastCursorPosition;

...

@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
    Spannable str = this.getText();
    StyleSpan ss;
    int endOfString = text.toString().length();

    //current typeface is determined by bold, italics, checkboxes, etc
    switch(currentTypeface) {
        case TYPEFACE_NORMAL:
            ss = new StyleSpan(Typeface.NORMAL);
            break;
        case TYPEFACE_BOLD:
            ss = new StyleSpan(Typeface.BOLD);
            break;
        case TYPEFACE_ITALICS:
            ss = new StyleSpan(Typeface.ITALIC);
            break;
        case TYPEFACE_BOLD_ITALICS:
            ss = new StyleSpan(Typeface.BOLD_ITALIC);
            break;
        default:
            ss = new StyleSpan(Typeface.NORMAL);
    }

    str.setSpan(ss, lastCursorPosition, endOfString, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

我编写的 Full TextArea 类:

public class TextArea extends EditText {

    public static final int TYPEFACE_NORMAL = 0;
    public static final int TYPEFACE_BOLD = 1;
    public static final int TYPEFACE_ITALICS = 2;
    public static final int TYPEFACE_BOLD_ITALICS = 3;

    private int currentTypeface;
    private int lastCursorPosition;
    private int tId;


    public TextArea(Context context) {
        super(context);
        lastCursorPosition = this.getSelectionStart();
    }

    public TextArea(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    public int gettId() {
        return tId;
    }

    public void settId(int tId) {
        this.tId = tId;
    }

    public void changeTypeface(int tfId) {
        currentTypeface = tfId;
        lastCursorPosition = this.getSelectionStart();
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        Spannable str = this.getText();
        StyleSpan ss;
        int endLength = text.toString().length();

        switch(currentTypeface) {
            case TYPEFACE_NORMAL:
                ss = new StyleSpan(Typeface.NORMAL);
                break;
            case TYPEFACE_BOLD:
                ss = new StyleSpan(Typeface.BOLD);
                break;
            case TYPEFACE_ITALICS:
                ss = new StyleSpan(Typeface.ITALIC);
                break;
            case TYPEFACE_BOLD_ITALICS:
                ss = new StyleSpan(Typeface.BOLD_ITALIC);
                break;
            default:
                ss = new StyleSpan(Typeface.NORMAL);
        }

        str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

来自MainActivity.java

TextArea t = new TextArea(context);
int typefaceStyle = TextArea.TYPEFACE_NORMAL;
CheckBox boldCheckbox = (CheckBox) findViewById(R.id.post_bold_checkbox);

boldCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            boldChecked = isChecked;
            if(italicsChecked && boldChecked) {
                typefaceStyle = TextArea.TYPEFACE_BOLD_ITALICS;
            } else if (boldChecked){
                typefaceStyle = TextArea.TYPEFACE_BOLD;
            } else if (italicsChecked) {
                typefaceStyle = TextArea.TYPEFACE_ITALICS;
            } else {
                typefaceStyle = TextArea.TYPEFACE_NORMAL;
            }
            t.changeTypeface(typefaceStyle);
        }
    });

我在 StackOverflow 上的第一个回复!希望这有帮助:-)

关于android - 在 Android 的 EditText 中将 future 文本更改为粗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41881373/

相关文章:

java - Google Play 服务 9.2.0 (Admob) 的 NoClassDefFoundError

android - 在 RecyclerView 中回收 View 后,EditText(或 android.support.v7.widget.AppCompatEditText)长按损坏

android - 从 RecyclerView 中的添加项聚焦 EditText

android - 知道编辑文本何时完成编辑

android - EditText textCapSentences 不起作用

android - 画圈 Android MapBox SDK

Android Eclipse 在 XML 文件的调试和发布之间切换

Android 自动链接以启动 WebView

android - 从提供错误 URI 路径的电子邮件中打开 ZIP 文件

java - 编辑文本。红色光标和下划线