目录
需求:Android实现富文本编辑器,并实现Html解析和生成;
常见富文本编辑操作:
1.字体加粗,斜体,下划线,删除线;
2.字体设置大小 默认大(18px),中(16px),小(14px);
3.字体颜色设置;
4.换行插入图片;
5.编辑内容生成Html;
6.解析Html并且显示;
主要实现方式:
1.EditText+Span的实现方式;
2.WebView+JavaScript的实现方式;
EditText是一个输入框控件,Span控制输入框内容显示样式;
1.Span样式介绍
1.1Span类继承关系
CharacterStyle:是控制内容显示样式Span的基类;控制文字样式的类基本都是扩展CharacterStyle类,大多数样式继承自MetricAffectingSpan类,简单的样式只需要实现UpdateAppearance;
1.2StyleSpan
设置字体:粗体,斜体,正常,粗体+斜体,支持样式如下:
android.graphics.Typeface
// Style
public static final int NORMAL = 0;
public static final int BOLD = 1;
public static final int ITALIC = 2;
public static final int BOLD_ITALIC = 3;
创建字体样式示例:
//粗体
new StyleSpan(Typeface.BOLD);
//斜体
new StyleSpan(Typeface.ITALIC);
1.3AbsoluteSizeSpan
设置字体大小
/**
* Set the text size to <code>size</code> physical pixels,
* or to <code>size</code> device-independent pixels if
* <code>dip</code> is true.
*/
//设置物理像素(px)大小(dip:false)或者设置与设备像素无关的大小(dip:true)
public AbsoluteSizeSpan(int size, boolean dip) {
mSize = size;
mDip = dip;
}
使用示例:
new AbsoluteSizeSpan(16, true);
1.4ForegroundColorSpan
设置字体颜色
public ForegroundColorSpan(@ColorInt int color) {
mColor = color;
}
使用示例:
new ForegroundColorSpan(Color.parseColor("#00ff00"))
1.5UnderlineSpan
设置文字内容下划线
使用示例:
new UnderlineSpan()
1.6StrikethroughSpan
设置文字内容删除线
new StrikethroughSpan()
1.7Spanned
设置文字内容样式范围(主要开始和结束位置前面或者后面继续使用设置样式)
//包含start不包含end[start,end)
public static final int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK;
//包含start同时包含end[start,end]
public static final int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;
//不包含start同时不包含end(start,end)
public static final int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;
//不包含start包含end(start,end]
public static final int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;
2.实现富文本编辑
public class RichEditText extends AppCompatEditText {}
2.1定义富文本样式类
/**
* 字体样式
*/
public class FontStyle {
public final static int NORMAL = 16;
public final static int SMALL = 14;
public final static int BIG = 18;
public final static String BLACK="#FF212121";
public final static String GREY="#FF878787";
public final static String RED="#FFF64C4C";
public final static String BLUE="#FF007AFF";
public boolean isBold;
public boolean isItalic;
public boolean isUnderline;
public boolean isStreak;
public int fontSize;
public int color;
}
2.2生成选中文字要设置的Span(样式)
RichEditText
public CharacterStyle getInitSpan(FontStyle fontStyle){
//粗体
if(fontStyle.isBold){
return new StyleSpan(Typeface.BOLD);
//斜体
}else if(fontStyle.isItalic){
return new StyleSpan(Typeface.ITALIC);
//下划线
}else if(fontStyle.isUnderline){
return new UnderlineSpan();
//删除线
}else if(fontStyle.isStreak){
return new StrikethroughSpan();
//字体大小
}else if(fontStyle.fontSize>0){
return new AbsoluteSizeSpan(fontStyle.fontSize, true);
//字体颜色
}else if(fontStyle.color != 0){
return new ForegroundColorSpan(fontStyle.color);
}
return null;
}
2.3应用样式到选中文字上
setSpan是公用方法,fontStyle设置选中内容的样式,isSet设置或取消样式,tClass当前要设置Span样式class;
public <T> void setSpan(FontStyle fontStyle, boolean isSet, Class<T> tClass){
//获取选中文字的开始和结束位置
int start = getSelectionStart();
int end = getSelectionEnd();
//不包含start字符包含end字符,选中end位置以后继续使用设置样式
int mode = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
//获取文字tClass(例如:StyleSpan.class)类型样式数组(Span)
//tClass主要设置文字样式的class
T[] spans = getEditableText().getSpans(start,end,tClass);
//移除选中文字的样式,同时保存样式
List<SpanPart> spanStyles = getOldFontStyles(spans, fontStyle);
//重新设置样式
for (SpanPart spanPart : spanStyles){
if(spanPart.start<start){ //例如粗体设置abcdef,cde修改为非粗体,ab设置粗体
if(start == end){//光标位置,光标位置继续输入不在使用spanPart样式