android中自定义textView自动区分SpannableStringBuilder中的不同样式字体
我在网上搜索了很多有关SpannableStringBuilder以及SpannableString的帖子,发现都是教学怎么使用,或者是api讲解.并不是我所需要的结果.我在论坛中搜索了一下SpannableString,找到的也是类似于教学的问答.
问题描述:需要实现一个类似于TextView的功能.
问题演示:在android中,通过系统的TextView,直接就进行setText所显示的效果是这样的:
String str1 = "11111111";
SpannableString spannableString1 = new SpannableString(str1);
spannableString1.setSpan(new AbsoluteSizeSpan(20, true), 0, str1.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str2 = "22222222";
SpannableString spannableString2 = new SpannableString(str2);
spannableString2.setSpan(new AbsoluteSizeSpan(50, true), 0, str2.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append(spannableString1).append(spannableString2);
TextView textView = new TextView(this);
textView.setText(ssb);
setContentView(textView);
需求描述:现在我需要自己重新继承View,自己用Canvas以及paint来绘制文字.也需要实现这样的效果.这个时候,自定义的View就需要实现类似系统TextView的功能,能够自动识别所设置的SpannableString中的字体样式.
查阅过程:我翻阅了google,baidu,stackoverflow,android dev上面大部分文档以及提问帖,还有android TextView的源码.都没有找到相关的资料.
在csdn上又看到过一个,在EditText上实现不同文字显示,但这个是通过选择文字进行对应的样式添加.首先,这样是能够知道是某一段到某一段之间的文字需要变成某一种样式.
而我现在的情况是,不知道某一段到某一段,应该变成一个什么样的预设值的样式(预设值:指之前在生成SpannableString时候添加的字体样式).
所以在这里求教,想要理解一下这个思路或实现方式等.
在帖子上或通过Gmail或QQ都能够联系我.
Gmail:[email protected]
QQ:272119494
谢谢!
Android spannablestring textview 自定义view spananblestringbuilder
Answers
..好尴尬,没有人回答..
最后这个我问题,我这样解决的.(我翻看了TextView的源码,可惜看不太懂)
重写了SpannableString,在里面定义了一个tag字段,用来区分这段文字是什么类型.
然后自定义了一个SpannableStringBuilder,里面维护了一个ArrayList,用来区分每一段append进去的文字.
public class MySpannableString extends SpannableString {
private String tag;
public MySpannableString(CharSequence source, String tag) {
super(source);
this.tag = tag;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}
public class MySpannableStringBuilder {
private static MySpannableStringBuilder mySpannableStringBuilder;
private static ArrayList<MySpannableString> spannableStringArrayList;
private MySpannableStringBuilder() {
}
public static synchronized MySpannableStringBuilder getMySpannableStringBuilderInstance() {
if (mySpannableStringBuilder == null) {
mySpannableStringBuilder = new MySpannableStringBuilder();
}
return mySpannableStringBuilder;
}
public static synchronized ArrayList<MySpannableString> getSpannableStringArrayListInstance() {
if (spannableStringArrayList == null) {
spannableStringArrayList = new ArrayList<MySpannableString>();
}
return spannableStringArrayList;
}
public MySpannableStringBuilder append(MySpannableString text) {
getSpannableStringArrayListInstance().add(text);
return getMySpannableStringBuilderInstance();
}
}
//在Activity中
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myTextView = new MyTextView(this);
String str1 = "11111111";
MySpannableString spannableString1 = new MySpannableString(str1, "p");
spannableString1.setSpan(new AbsoluteSizeSpan(20, true), 0, str1.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str2 = "2222222";
MySpannableString spannableString2 = new MySpannableString(str2, "h1");
spannableString2.setSpan(new AbsoluteSizeSpan(50, true), 0, str2.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str3 = "44444444";
MySpannableString spannableString3 = new MySpannableString(str3, "h2");
spannableString3.setSpan(new AbsoluteSizeSpan(50, true), 0, str3.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str4 = "555";
MySpannableString spannableString4 = new MySpannableString(str4, "h3");
spannableString4.setSpan(new AbsoluteSizeSpan(50, true), 0, str4.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str5 = "666666";
MySpannableString spannableString5 = new MySpannableString(str5, "h4");
spannableString5.setSpan(new AbsoluteSizeSpan(50, true), 0, str5.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
String str6 = "777777";
MySpannableString spannableString6 = new MySpannableString(str6, "p");
spannableString6.setSpan(new AbsoluteSizeSpan(50, true), 0, str6.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
MySpannableStringBuilder ssb = MySpannableStringBuilder.getMySpannableStringBuilderInstance();
MySpannableStringBuilder mySpannableStringBuilder = ssb.append(spannableString1).
append(spannableString1).
append(spannableString1).
append(spannableString1).
append(spannableString1).
append(spannableString2);
myTextView.setText(mySpannableStringBuilder);
setContentView(myTextView);
}
如果有大牛觉得这样写不好,或者是有其他方案,欢迎共同讨论交流.
//----------------------------
又发现了一种方法
String str2 = "2222222";
MySpannableString spannableString2 = new MySpannableString(str2, "h1");
spannableString2.setSpan(new AbsoluteSizeSpan(50, true), 0, str2.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
//直接通过 spannableString2.getSpan();
// 三个参数:起始位置,结束位置,Span类型
AbsoluteSizeSpan[] spans = spannableString2.getSpans(0, spannableString2.length(), AbsoluteSizeSpan.class);
System.out.println(spans[0].getSize());
// 如果无法确定里面到底都是用了什么样式可以通过这种方法获取.
Object[] spans = spannableString.getSpans(0,spannableString.length(), Object.class);
for (Object object : spans) {
if (object instanceof AbsoluteSizeSpan) {
} else if(...){
...
}
}
如果设置了其他的Span,那就通过类似的方法拿出来.
不过如果把多个SpannableString放到SpannableStringBuilder里面去.还是没有办法区分他的起始位置和结束为止,这里就还是需要用到上面自定义的MySpannableStringBuilder来进行存储.