Java 我的自定义编辑文本无法正常工作

Java 我的自定义编辑文本无法正常工作,java,android,android-edittext,Java,Android,Android Edittext,我正在编写一个EditText,它可以使用本文中提到的粗体、斜体和下划线字符 我扩展了EditText并重写了onTextChanged()方法。 我的代码在第一次出现任何粗体、斜体、带下划线的输入时运行良好,但在第二次出现后,第一次出现的内容将更改为普通文本 以下是主要活动。java package com.example.syed.andtexteditor; import android.os.Bundle; import android.support.v4.content.

我正在编写一个EditText,它可以使用本文中提到的粗体、斜体和下划线字符

我扩展了EditText并重写了onTextChanged()方法。 我的代码在第一次出现任何粗体、斜体、带下划线的输入时运行良好,但在第二次出现后,第一次出现的内容将更改为普通文本

以下是主要活动。java

    package com.example.syed.andtexteditor;

import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    int helperCounterB = 0;
    int helperCounterI = 0;
    int helperCounterU = 0;

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

        Button boldButton = (Button) findViewById(R.id.bold_button);
        boldButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Button boldButton = (Button) findViewById(R.id.bold_button);
                helperCounterB++;

                if (helperCounterB % 2 != 0)
                //The EditText is in Bold mode when the Bold button is pressed odd-th time
                    boldButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else

                    boldButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }

        });

        Button italicsButton = (Button) findViewById(R.id.italics_button);
        italicsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Button italicsButton = (Button) findViewById(R.id.italics_button);
                helperCounterI++;
                if (helperCounterI % 2 != 0) //The EditText is in Italics mode when the Italics button is pressed odd-th time
                    italicsButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else
                    italicsButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }

        });

        Button underlineButton = (Button) findViewById(R.id.underline_button);
        underlineButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Button underlineButton = (Button) findViewById(R.id.underline_button);
                helperCounterU++;
                if (helperCounterU % 2 != 0)//The EditText is in Underline mode when the Underline button is pressed odd-th time

                    underlineButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else

                    underlineButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }
        });

    }
}
package com.example.syed.andtexteditor;


import android.content.Context;
import android.graphics.Typeface;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;


/**
 * Created by Syed on 29-05-2017.
 */

public class TextArea extends AppCompatEditText {
    Context c;
    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;
    public static final int TYPEFACE_UNDERLINE = 4;
    public static final int TYPEFACE_BOLD_UNDERLINE = 5;
    public static final int TYPEFACE_ITALICS_UNDERLINE = 6;
    public static final int TYPEFACE_BOLD_ITALICS_UNDERLINE = 7;

    private int currentTypeface;
    private int lastCursorPosition;

    private StyleSpan normalspan = new StyleSpan(Typeface.NORMAL);
    private StyleSpan boldspan = new StyleSpan(Typeface.BOLD);
    private StyleSpan italicspan = new StyleSpan(Typeface.ITALIC);
    private StyleSpan boldItalicspan = new StyleSpan(Typeface.BOLD_ITALIC);
    private UnderlineSpan underlinespan = new UnderlineSpan();

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

    }

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

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

    public void applyTypeface(int helperCounterI, int helperCounterB, int helperCounterU) {
        int min = 0;
        int max = this.getText().length();
        if (this.isFocused()) {
            final int selStart = this.getSelectionStart();
            final int selEnd = this.getSelectionEnd();

            min = Math.max(0, Math.min(selStart, selEnd));
            max = Math.max(0, Math.max(selStart, selEnd));
        }
        Spannable s = this.getText();
        Editable selectedText = new SpannableStringBuilder(s, min, max);

        SpannableStringBuilder s1 = new SpannableStringBuilder(s, 0, min);

        String selectedTextString = selectedText.toString();
        SpannableStringBuilder selectedSpannedString = new SpannableStringBuilder(selectedTextString);
        Log.d(VIEW_LOG_TAG, "Helper Counter I: " + helperCounterI + " Helper Counter B: " + helperCounterB);
        if (helperCounterI % 2 != 0 && helperCounterB % 2 != 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TextArea.TYPEFACE_BOLD_ITALICS);

            }
            //ignore this part as there are no issues with this
            else {

                StyleSpan styleSpan = new StyleSpan(Typeface.BOLD_ITALIC);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }

        } else if (helperCounterI % 2 != 0 && helperCounterB % 2 == 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TextArea.TYPEFACE_ITALICS);

            }
            //ignore this part as there are no issues with this
            else {
                StyleSpan styleSpan = new StyleSpan(Typeface.ITALIC);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterI % 2 == 0 && helperCounterB % 2 != 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {

                this.changeTypeface(TextArea.TYPEFACE_BOLD);

            }
            //ignore this part as there are no issues with this
            else {
                StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterB % 2 == 0 && helperCounterI % 2 == 0 && helperCounterU % 2 == 0) {

            this.changeTypeface(TextArea.TYPEFACE_NORMAL);

        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 == 0 && helperCounterB % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 == 0 && helperCounterB % 2 != 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_BOLD_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.BOLD), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 != 0 && helperCounterB % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {

                this.changeTypeface(TYPEFACE_ITALICS_UNDERLINE);

            } else
            //ignore this part as there are no issues with this
            {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.ITALIC), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 != 0 && helperCounterB % 2 != 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_BOLD_ITALICS_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        }
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {


        Log.d(VIEW_LOG_TAG, "Start: " + start + " Length before: " + lengthBefore + " Length After: " + lengthAfter + " TextLength: " + text.length());

        CharacterStyle ss = null;
        UnderlineSpan ss1 = null;
        int endLength = text.toString().length();


        switch (currentTypeface) {
            case TYPEFACE_NORMAL:
                ss = normalspan;
                break;
            case TYPEFACE_BOLD:
                ss = boldspan;
                break;
            case TYPEFACE_ITALICS:
                ss = italicspan;
                break;
            case TYPEFACE_BOLD_ITALICS:
                ss = boldItalicspan;
                break;
            case TYPEFACE_UNDERLINE:
                ss = underlinespan;
                break;
            case TYPEFACE_BOLD_UNDERLINE:
                ss = boldspan;
                ss1 = underlinespan;
                break;
            case TYPEFACE_ITALICS_UNDERLINE:
                ss = italicspan;
                ss1 = underlinespan;
                break;
            case TYPEFACE_BOLD_ITALICS_UNDERLINE:
                ss = boldItalicspan;
                ss1 = underlinespan;
                break;
        }
        if (lastCursorPosition > endLength)
            return;
        Log.d(TextArea.class.getSimpleName(), new Integer(lastCursorPosition).toString() + new Integer(endLength).toString());
        this.getText().setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        this.getText().setSpan(ss1, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    }
}
这里是扩展的EditText类,即TextArea.java

    package com.example.syed.andtexteditor;

import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    int helperCounterB = 0;
    int helperCounterI = 0;
    int helperCounterU = 0;

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

        Button boldButton = (Button) findViewById(R.id.bold_button);
        boldButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Button boldButton = (Button) findViewById(R.id.bold_button);
                helperCounterB++;

                if (helperCounterB % 2 != 0)
                //The EditText is in Bold mode when the Bold button is pressed odd-th time
                    boldButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else

                    boldButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }

        });

        Button italicsButton = (Button) findViewById(R.id.italics_button);
        italicsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Button italicsButton = (Button) findViewById(R.id.italics_button);
                helperCounterI++;
                if (helperCounterI % 2 != 0) //The EditText is in Italics mode when the Italics button is pressed odd-th time
                    italicsButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else
                    italicsButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }

        });

        Button underlineButton = (Button) findViewById(R.id.underline_button);
        underlineButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Button underlineButton = (Button) findViewById(R.id.underline_button);
                helperCounterU++;
                if (helperCounterU % 2 != 0)//The EditText is in Underline mode when the Underline button is pressed odd-th time

                    underlineButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.black));
                else

                    underlineButton.setTextColor(ContextCompat.getColor(MainActivity.this, R.color.grey));

                TextArea t = (TextArea) findViewById(R.id.textInput);
                t.applyTypeface(helperCounterI, helperCounterB, helperCounterU);

            }
        });

    }
}
package com.example.syed.andtexteditor;


import android.content.Context;
import android.graphics.Typeface;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;


/**
 * Created by Syed on 29-05-2017.
 */

public class TextArea extends AppCompatEditText {
    Context c;
    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;
    public static final int TYPEFACE_UNDERLINE = 4;
    public static final int TYPEFACE_BOLD_UNDERLINE = 5;
    public static final int TYPEFACE_ITALICS_UNDERLINE = 6;
    public static final int TYPEFACE_BOLD_ITALICS_UNDERLINE = 7;

    private int currentTypeface;
    private int lastCursorPosition;

    private StyleSpan normalspan = new StyleSpan(Typeface.NORMAL);
    private StyleSpan boldspan = new StyleSpan(Typeface.BOLD);
    private StyleSpan italicspan = new StyleSpan(Typeface.ITALIC);
    private StyleSpan boldItalicspan = new StyleSpan(Typeface.BOLD_ITALIC);
    private UnderlineSpan underlinespan = new UnderlineSpan();

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

    }

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

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

    public void applyTypeface(int helperCounterI, int helperCounterB, int helperCounterU) {
        int min = 0;
        int max = this.getText().length();
        if (this.isFocused()) {
            final int selStart = this.getSelectionStart();
            final int selEnd = this.getSelectionEnd();

            min = Math.max(0, Math.min(selStart, selEnd));
            max = Math.max(0, Math.max(selStart, selEnd));
        }
        Spannable s = this.getText();
        Editable selectedText = new SpannableStringBuilder(s, min, max);

        SpannableStringBuilder s1 = new SpannableStringBuilder(s, 0, min);

        String selectedTextString = selectedText.toString();
        SpannableStringBuilder selectedSpannedString = new SpannableStringBuilder(selectedTextString);
        Log.d(VIEW_LOG_TAG, "Helper Counter I: " + helperCounterI + " Helper Counter B: " + helperCounterB);
        if (helperCounterI % 2 != 0 && helperCounterB % 2 != 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TextArea.TYPEFACE_BOLD_ITALICS);

            }
            //ignore this part as there are no issues with this
            else {

                StyleSpan styleSpan = new StyleSpan(Typeface.BOLD_ITALIC);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }

        } else if (helperCounterI % 2 != 0 && helperCounterB % 2 == 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TextArea.TYPEFACE_ITALICS);

            }
            //ignore this part as there are no issues with this
            else {
                StyleSpan styleSpan = new StyleSpan(Typeface.ITALIC);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterI % 2 == 0 && helperCounterB % 2 != 0 && helperCounterU % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {

                this.changeTypeface(TextArea.TYPEFACE_BOLD);

            }
            //ignore this part as there are no issues with this
            else {
                StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
                selectedSpannedString.setSpan(styleSpan, min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterB % 2 == 0 && helperCounterI % 2 == 0 && helperCounterU % 2 == 0) {

            this.changeTypeface(TextArea.TYPEFACE_NORMAL);

        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 == 0 && helperCounterB % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 == 0 && helperCounterB % 2 != 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_BOLD_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.BOLD), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 != 0 && helperCounterB % 2 == 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {

                this.changeTypeface(TYPEFACE_ITALICS_UNDERLINE);

            } else
            //ignore this part as there are no issues with this
            {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.ITALIC), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        } else if (helperCounterU % 2 != 0 && helperCounterI % 2 != 0 && helperCounterB % 2 != 0) {
            if (this.getSelectionEnd() == this.getSelectionStart()) {
                this.changeTypeface(TYPEFACE_BOLD_ITALICS_UNDERLINE);

            }
            //ignore this part as there are no issues with this
            else {
                selectedSpannedString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                selectedSpannedString.setSpan(new UnderlineSpan(), min, max, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                SpannableStringBuilder s3 = new SpannableStringBuilder(s, max, s.length());
                CharSequence finalSpannable = TextUtils.concat(s1, selectedSpannedString, s3);
                this.setText(finalSpannable);
            }
        }
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {


        Log.d(VIEW_LOG_TAG, "Start: " + start + " Length before: " + lengthBefore + " Length After: " + lengthAfter + " TextLength: " + text.length());

        CharacterStyle ss = null;
        UnderlineSpan ss1 = null;
        int endLength = text.toString().length();


        switch (currentTypeface) {
            case TYPEFACE_NORMAL:
                ss = normalspan;
                break;
            case TYPEFACE_BOLD:
                ss = boldspan;
                break;
            case TYPEFACE_ITALICS:
                ss = italicspan;
                break;
            case TYPEFACE_BOLD_ITALICS:
                ss = boldItalicspan;
                break;
            case TYPEFACE_UNDERLINE:
                ss = underlinespan;
                break;
            case TYPEFACE_BOLD_UNDERLINE:
                ss = boldspan;
                ss1 = underlinespan;
                break;
            case TYPEFACE_ITALICS_UNDERLINE:
                ss = italicspan;
                ss1 = underlinespan;
                break;
            case TYPEFACE_BOLD_ITALICS_UNDERLINE:
                ss = boldItalicspan;
                ss1 = underlinespan;
                break;
        }
        if (lastCursorPosition > endLength)
            return;
        Log.d(TextArea.class.getSimpleName(), new Integer(lastCursorPosition).toString() + new Integer(endLength).toString());
        this.getText().setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        this.getText().setSpan(ss1, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    }
}

您的问题是您正在使用跨度的实例。根据(矿山)的文件:

将指定的标记对象附加到文本的开始…结束范围,或将对象移动到该范围(如果该对象已附加到其他位置)

因此,每次要为文本添加属性时,只需创建新的跨距


希望有帮助

这解决了问题,但以前的问题再次出现。昨天我问了这个问题,解决这个问题的方法是重新使用跨距。当然,如果每次文本更改时都重新分配每个跨距,事情会变得很慢。你的逻辑需要做的是确定你是否在一个跨度的中间,然后重新使用现有的一个活跃的。如果您要开始一个新的范围,请仅为该用例创建一个新的范围,然后重复使用它,直到使用完毕。然后,当删除字符时,可以回收不再使用的跨距。这很复杂,超出了问题的范围。这对我来说有点超出范围。这行得通吗?对不起,我一点也不知道。试试看!