在Android中将EditText中的将来文本更改为粗体 [英] Change future text to bold in EditText in Android

查看:134
本文介绍了在Android中将EditText中的将来文本更改为粗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Android开发一个基本的文本编辑器应用程序,目前正在格式化文本.

I am making a basic text editor app for Android and currently working on formatting the text.

我有一个名为text_area的EditText,用户在其中键入他的文本,还有一个名为bold的ToggleButton,该按钮将文本设置为粗体.最初,使用EditText.setTypeface方法,当按钮处于打开状态时,text_area中的所有文本都将变为粗体.使用此问题,我只能将选定的文本更改为粗体.

I have an EditText named text_area where the user types his text and a ToggleButton called bold that sets the text to bold. Initially, using the EditText.setTypeface method, all of the text in text_area would change to bold when the button is on. Using the answer provided in this question, I was able to change only the selected text to bold.

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

What I really want to do though is that when the button is pressed, all the previously typed text (normal and/or bold) remain unchanged, and whatever the user types next is typed in bold.

这是我的代码(有人可以告诉我else语句下的代码做什么):

Here's my code (Could someone also tell me what the code under the else statement does):

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

推荐答案

我被困在同一问题上,经过数小时的尝试,这才是我的构想.

I was stuck on the same issue, and after hours of trying, this is what I came up with.

首先,每当您勾选要应用的粗体/斜体样式复选框时,您都希望获得当前的光标位置.

First, whenever you check the bold/italics whatever styled checkbox you want to apply, you want to get the current cursor position.

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

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

both gives you the current cursor position of the EditText if no text is highlighted.

将此值存储到变量中.

int lastCursorPosition = YourEditText.getSelectionStart();

然后,我覆盖了EditText的onTextChanged函数.由于我们只想设置从最后一个光标位置到更改发生位置的结尾之间的跨度,因此我们设置从lastCursorPosition到文本结尾的跨度.

Then, I overrode the onTextChanged function of the EditText. Since we only want to set span from the last cursor position to the end of wherever change is made, we set the span from lastCursorPosition to the end of the text.

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

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

While doing this, I ran into another problem. Whenever I applied another span to another part of the text, previous styles disappeared. I fixed this by creating new StyleSpan for each time a new style was applied. Minimal code to understand:

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

我编写的完整TextArea类:

Full TextArea class I've written:

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

From 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的第一个答复!希望这对您有所帮助:-)

My very first reply on StackOverflow! Hope this helped :-)

这篇关于在Android中将EditText中的将来文本更改为粗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆