删除跨度上的样式 [英] Remove style on spans
问题描述
我已经使用此 StyleSpanRemover
从中删除了样式选择文本,但我有问题.
我想要一个bold
按钮,用于切换所选文本的粗体样式.这意味着如果选定的文本(或部分文本)不是粗体,则将所有文本全部加粗;如果所有选定的文本均为粗体,则从中删除粗体样式.
但是,当我使用此代码时,在删除文本上的粗体样式并再次将其粗体化之后,getStyle()
始终返回Typeface.NORMAL
I have used this StyleSpanRemover
to remove style from selected text, but i have a problem.
I want to have a bold
button that toggle bold style of selected text. it means if the selected text (or part of that) is not bold, bold all of them; and if all of selected text is bold, remove bold style from it.
But when i use this code, after one removing bold style on a text and again bolding it, getStyle()
always returns Typeface.NORMAL
这是我使用的代码:
boolean isAllSpansBold = true;
/**
* Bold selected text
*/
Spannable spannable = new SpannableString(mEditTextContent.getText());
StyleSpan[] styleSpans = mEditTextContent.getText().getSpans(
mEditTextContent.getSelectionStart(),
mEditTextContent.getSelectionEnd(),
StyleSpan.class
);
if(styleSpans.length == 0)
{
spannable.setSpan(
new StyleSpan(Typeface.BOLD),
mEditTextContent.getSelectionStart(),
mEditTextContent.getSelectionEnd(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
Log.d("Ramansoft", "styleSpans.length = 0");
}
else
{
for(int i=0; i<styleSpans.length; i++) {
Log.d("Ramansoft", "The style is: " + String.valueOf(styleSpans[i].getStyle()));
if (styleSpans[i].getStyle() != Typeface.BOLD && styleSpans[i].getStyle() != Typeface.BOLD_ITALIC) {
isAllSpansBold = false;
break;
}
}
if(isAllSpansBold)
{
StyleSpanRemover styleSpanRemover = new StyleSpanRemover();
styleSpanRemover.RemoveStyle(
spannable,
mEditTextContent.getSelectionStart(),
mEditTextContent.getSelectionEnd(),
Typeface.BOLD
);
Log.d("Ramansoft", "isAllSpansBold = true");
}
else
{
spannable.setSpan(
new StyleSpan(Typeface.BOLD),
mEditTextContent.getSelectionStart(),
mEditTextContent.getSelectionEnd(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
Log.d("Ramansoft", "isAllSpansBold = false");
}
推荐答案
经过多次尝试,我可以做到这一点. 此处是解决方案.
After many tries, i can do that. Here is the solution.
public class SpanStyleHelper
{
protected EditText mEditText;
protected Spannable mSpannable;
protected int mSelectedTextStart;
protected int mSelectedTextEnd;
public SpanStyleHelper(EditText editText)
{
mEditText = editText;
mSpannable = mEditText.getText();
mSelectedTextStart = mEditText.getSelectionStart();
mSelectedTextEnd = mEditText.getSelectionEnd();
}
public Spannable boldSelectedText()
{
Log.d("Ramansoft", "Try to bold selected text..");
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
if(styleSpans.length > 0) {
int lastSpanEnd = 0;
for (StyleSpan styleSpan : styleSpans) {
/**
* Save old style
*/
int oldStyle = styleSpan.getStyle();
/**
* Get start and end of span
*/
int spanStart = mSpannable.getSpanStart(styleSpan);
int spanEnd = mSpannable.getSpanEnd(styleSpan);
/**
* Before bold this span, we check if any unspanned
* text between this span and last span remains. if any
* unspanned text exist, we should bold it
*/
if(spanStart > lastSpanEnd)
{
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD),
lastSpanEnd,
spanStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* Update last span end
*/
lastSpanEnd = spanEnd;
/**
* Remove the span
*/
mSpannable.removeSpan(styleSpan);
/**
* Because we just need change selected text,
* if span start is lower than selected text start or
* if span end is higher than selected text end start
* we should restore span for unselected part of span
*/
if (spanStart < mEditText.getSelectionStart()) {
mSpannable.setSpan(
new StyleSpan(oldStyle),
spanStart,
mSelectedTextStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
if (spanEnd > mEditText.getSelectionEnd()) {
mSpannable.setSpan(
new StyleSpan(oldStyle),
mSelectedTextEnd,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* We want to add bold style to current style
* so we most detect current style and change
* the style depend on current style
*/
if (oldStyle == Typeface.ITALIC) {
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD_ITALIC),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
} else {
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
/**
* Now we should check if any
* unspanned selected text remains
*/
if(mSelectedTextEnd != lastSpanEnd)
{
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD),
lastSpanEnd,
mSelectedTextEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
else
{
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD),
mSelectedTextStart,
mSelectedTextEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
return mSpannable;
}
public Spannable unBoldSelectedText()
{
Log.d("Ramansoft", "Try to unbold selected text..");
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
for(StyleSpan styleSpan:styleSpans)
{
/**
* Save old style
*/
int oldStyle = styleSpan.getStyle();
/**
* Get start and end of span
*/
int spanStart = mSpannable.getSpanStart(styleSpan);
int spanEnd = mSpannable.getSpanEnd(styleSpan);
/**
* Remove the span
*/
mSpannable.removeSpan(styleSpan);
/**
* Because we just need change selected text,
* if span start is lower than selected text start or
* if span end is higher than selected text end start
* we should restore span for unselected part of span
*/
if(spanStart < mEditText.getSelectionStart())
{
mSpannable.setSpan(
new StyleSpan(oldStyle),
spanStart,
mSelectedTextStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
if(spanEnd > mEditText.getSelectionEnd())
{
mSpannable.setSpan(
new StyleSpan(oldStyle),
mSelectedTextEnd,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* Because we just want to remove bold style,
* if the span has another style, we should restore it
*/
if(oldStyle == Typeface.BOLD_ITALIC)
{
mSpannable.setSpan(
new StyleSpan(Typeface.ITALIC),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
return mSpannable;
}
public Spannable toggleBoldSelectedText()
{
Log.d("Ramansoft", "Try to toggle bold selected text..");
boolean isAllSpansBold = true;
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
if(styleSpans.length == 0)
{
return boldSelectedText();
}
else
{
for(StyleSpan styleSpan:styleSpans)
{
Log.d("Ramansoft", "styleSpan.getStyle() = " + styleSpan.getStyle());
if (styleSpan.getStyle() != Typeface.BOLD && styleSpan.getStyle() != Typeface.BOLD_ITALIC) {
isAllSpansBold = false;
break;
}
}
Log.d("Ramansoft", "isAllSpansBold = " + isAllSpansBold);
if(isAllSpansBold)
return unBoldSelectedText();
else
return boldSelectedText();
}
}
public Spannable italicSelectedText()
{
Log.d("Ramansoft", "Try to italic selected text..");
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
if(styleSpans.length > 0)
{
int lastSpanEnd = 0;
for (StyleSpan styleSpan : styleSpans) {
/**
* Save old style
*/
int oldStyle = styleSpan.getStyle();
/**
* Get start and end of span
*/
int spanStart = mSpannable.getSpanStart(styleSpan);
int spanEnd = mSpannable.getSpanEnd(styleSpan);
/**
* Before italic this span, we check if any unspanned
* text between this span and last span remains. if any
* unspanned text exist, we should italic it
*/
if(spanStart > lastSpanEnd)
{
mSpannable.setSpan(
new StyleSpan(Typeface.ITALIC),
lastSpanEnd,
spanStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* Update last span end
*/
lastSpanEnd = spanEnd;
/**
* Remove the span
*/
mSpannable.removeSpan(styleSpan);
/**
* Because we just need change selected text,
* if span start is lower than selected text start or
* if span end is higher than selected text end start
* we should restore span for unselected part of span
*/
if (spanStart < mEditText.getSelectionStart()) {
mSpannable.setSpan(
new StyleSpan(oldStyle),
spanStart,
mSelectedTextStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
if (spanEnd > mEditText.getSelectionEnd()) {
mSpannable.setSpan(
new StyleSpan(oldStyle),
mSelectedTextEnd,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* We want to add bold style to current style
* so we most detect current style and change
* the style depend on current style
*/
if (oldStyle == Typeface.BOLD) {
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD_ITALIC),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
} else {
mSpannable.setSpan(
new StyleSpan(Typeface.ITALIC),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
/**
* Now we should check if any
* unspanned selected text remains
*/
if(mSelectedTextEnd != lastSpanEnd)
{
mSpannable.setSpan(
new StyleSpan(Typeface.ITALIC),
lastSpanEnd,
mSelectedTextEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
else
{
mSpannable.setSpan(
new StyleSpan(Typeface.ITALIC),
mSelectedTextStart,
mSelectedTextEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
return mSpannable;
}
public Spannable unItalicSelectedText()
{
Log.d("Ramansoft", "Try to un-italic selected text..");
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
for(StyleSpan styleSpan:styleSpans)
{
/**
* Save old style
*/
int oldStyle = styleSpan.getStyle();
/**
* Get start and end of span
*/
int spanStart = mSpannable.getSpanStart(styleSpan);
int spanEnd = mSpannable.getSpanEnd(styleSpan);
/**
* Remove the span
*/
mSpannable.removeSpan(styleSpan);
/**
* Because we just need change selected text,
* if span start is lower than selected text start or
* if span end is higher than selected text end start
* we should restore span for unselected part of span
*/
if(spanStart < mEditText.getSelectionStart())
{
mSpannable.setSpan(
new StyleSpan(oldStyle),
spanStart,
mSelectedTextStart,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
if(spanEnd > mEditText.getSelectionEnd())
{
mSpannable.setSpan(
new StyleSpan(oldStyle),
mSelectedTextEnd,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
/**
* Because we just want to remove bold style,
* if the span has another style, we should restore it
*/
if(oldStyle == Typeface.BOLD_ITALIC)
{
mSpannable.setSpan(
new StyleSpan(Typeface.BOLD),
spanStart,
spanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
return mSpannable;
}
public Spannable toggleItalicSelectedText()
{
Log.d("Ramansoft", "Try to toggle italic selected text..");
boolean isAllSpansItalic = true;
StyleSpan[] styleSpans = mEditText.getText().getSpans(
mSelectedTextStart,
mSelectedTextEnd,
StyleSpan.class
);
if(styleSpans.length == 0)
{
return italicSelectedText();
}
else
{
for(StyleSpan styleSpan:styleSpans)
{
Log.d("Ramansoft", "styleSpan.getStyle() = " + styleSpan.getStyle());
if (styleSpan.getStyle() != Typeface.ITALIC && styleSpan.getStyle() != Typeface.BOLD_ITALIC) {
isAllSpansItalic = false;
break;
}
}
Log.d("Ramansoft", "isAllSpansItalic = " + isAllSpansItalic);
if(isAllSpansItalic)
return unItalicSelectedText();
else
return italicSelectedText();
}
}
}
这篇关于删除跨度上的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!