why underline is removed by changing the style of

2019-08-19 13:55发布

问题:

I'm a beginner in android ,so please do excuse me if my question is foolish.Basically I'm trying to make a text editor so after a lot of try I'm able to add the bold,italic,bold-italic styles to text without any problem. But now when I'm trying to add underline to text underline is added without any error but when I'm changing the style for ex-bold to bold-italic then the underline is removed from last underlined charecters[][See here underline is there below boldtext]

[][Now underline is shifted to next charecters by removing last underline]

My Code:

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;
public static final boolean underline=false;

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;UnderlineSpan tt = new UnderlineSpan();
    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);
    }
    if(underline){
    str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    str.setSpan(tt, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}   
    else{
 str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}

From MainActivity.java

bold=findViewById(R.id.bold);
italic=findViewById(R.id.italic);
boldItalic=findViewById(R.id.boldItalic);
editText=findViewById(R.id.editText);
normal=findViewById(R.id.normal);
underline=findViewById(R.id.underline);
typefaceStyle = TextArea.TYPEFACE_NORMAL;
editText.changeTypeface(typefaceStyle);
normal.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
     typefaceStyle = TextArea.TYPEFACE_NORMAL;
     editText.changeTypeface(typefaceStyle);
 }
});
  bold.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
              typefaceStyle = TextArea.TYPEFACE_BOLD;
     editText.changeTypeface(typefaceStyle);
    }
  });
 italic.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
              typefaceStyle = TextArea.TYPEFACE_ITALICS;
     editText.changeTypeface(typefaceStyle);
 }
 });
  boldItalic.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
              typefaceStyle = TextArea.TYPEFACE_BOLD_ITALICS;

     editText.changeTypeface(typefaceStyle);

             }}
 }
 });

  underline.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
     if(under_it) {
         under_it = false;
         TextArea.underline=false;
         editText.changeTypeface(typefaceStyle);
         underline.setBackgroundColor(Color.parseColor("#001919"));
     }
     else {
         under_it = true;
         TextArea.underline=true;
         editText.changeTypeface(typefaceStyle);
         underline.setBackgroundColor(Color.parseColor("#fc0505"));

             }}
     }
          }
 });

回答1:

Ok buddy here is your solution.

Check it and let me know if this works ...

TextArea.java

public class TextArea extends android.support.v7.widget.AppCompatEditText {

    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 boolean underline = false;

    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;
        UnderlineSpan tt = new UnderlineSpan();
        int endLength = text.toString().length();
        underline = false;

        Log.d("onTextChanged ", text.toString());

        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_UNDERLINE:
                underline = true;
                ss = new StyleSpan(Typeface.NORMAL);
                tt = new UnderlineSpan();
                break;
            case TYPEFACE_BOLD_ITALICS:
                ss = new StyleSpan(Typeface.BOLD_ITALIC);
                break;
            default:
                ss = new StyleSpan(Typeface.NORMAL);
        }
        if (underline) {
//            str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            str.setSpan(tt, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            // Runtime Error Fix!
            if (endLength > lastCursorPosition)
                str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
}

Activity

    bold = findViewById(R.id.bold);
    italic = findViewById(R.id.italic);
    boldItalic = findViewById(R.id.boldItalic);
    editText = findViewById(R.id.editText);
    normal = findViewById(R.id.normal);
    underline = findViewById(R.id.underline);
    typefaceStyle = TextArea.TYPEFACE_NORMAL;
    editText.changeTypeface(typefaceStyle);

    normal.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            typefaceStyle = TextArea.TYPEFACE_NORMAL;
            editText.changeTypeface(typefaceStyle);
        }
    });


    bold.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            typefaceStyle = TextArea.TYPEFACE_BOLD;
            editText.changeTypeface(typefaceStyle);
        }
    });

    italic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            typefaceStyle = TextArea.TYPEFACE_ITALICS;
            editText.changeTypeface(typefaceStyle);
        }
    });

    boldItalic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            typefaceStyle = TextArea.TYPEFACE_BOLD_ITALICS;
            editText.changeTypeface(typefaceStyle);

        }
    });


    underline.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            typefaceStyle = TextArea.TYPEFACE_UNDERLINE;
                editText.changeTypeface(typefaceStyle);

        }
    });