基本上我有一个这样的段落
导带的较低能级 $ ec 之间的差异 价带的上能级 $ ev 称为能带 间隙。
现在我正在尝试解析文本,获取那些带前缀的符号,并将它们替换为数学公式的小PNG图像。它们只是单个/ dbl字母常量符号,如Ev和Ec。它们位于我的资产文件夹中。基本上这是代码
public SpannableStringBuilder getConstants(String desc, String constpath){
SpannableStringBuilder builder = new SpannableStringBuilder();
if (desc.contains("$")){
Matcher matcher = Pattern.compile("\\$\\w+").matcher(desc);
int lastEnding=0;
while (matcher.find()) {
String constName = matcher.group();
constName = constName.substring(1,constName.length());
int startIndex = matcher.start();
int endIndex = matcher.end();
String brokenDescFirstPart = desc.substring(lastEnding, startIndex - 1);
lastEnding = endIndex+1;
builder.append(brokenDescFirstPart).append(" ");
try{
InputStream imgStream = getContext().getAssets().open(constpath+constName+".png");
Drawable dconstImg = Drawable.createFromStream(imgStream, null);
imgStream.close();
builder.setSpan(new ImageSpan(dconstImg,ImageSpan.ALIGN_BOTTOM), builder.length() -3, builder.length() -1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(" ");
}catch (Exception e){
builder.append(" ");
}
}
String brokenDescLastPart = desc.substring(lastEnding, desc.length() - 1);
builder.append(brokenDescLastPart);
}else{
builder = SpannableStringBuilder.valueOf(desc);
}
return builder;
}
代码的快速摘要是 desc 是我要解析的字符串。然后我使用正则表达式获取$ word模式并使用 matcher.match 方法迭代文本。我使用一些int变量来跟踪这些符号之间的起点和终点,以仔细重建嵌入图像的原始字符串。现在代码
try{
InputStream imgStream = getContext().getAssets().open(constpath+constName+".png");
Drawable dconstImg = Drawable.createFromStream(imgStream, null);
imgStream.close();
builder.setSpan(new ImageSpan(dconstImg,ImageSpan.ALIGN_BOTTOM), builder.length() -3, builder.length() -1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(" ");
}catch (Exception e){
builder.append(" ");
}
是我的问题的关键。我从这个问题的其他问题得到了它。他们说它有效。但它不属于我的。我在整个代码中设置了断点并逐行执行。没有任何错误。仍然无法正常工作。
文本加载了textview中的额外空格,我故意用它来标识必须注入图像的位置。我的TextView是Android Studio中的小文本视图小部件。
答案 0 :(得分:2)
我终于弄明白了这个问题。事实证明所有drawables 必须用setBounds()方法初始化。这是我的最终代码
InputStream imgStream = getContext().getAssets().open(constpath + constName + ".png");
Drawable dconstImg = Drawable.createFromStream(imgStream, null);
imgStream.close();
float aspectRatio = (float) (1.00 * dconstImg.getIntrinsicWidth() / dconstImg.getIntrinsicHeight());
dconstImg.setBounds(0, 0, (int) Math.ceil(descTextSize * aspectRatio), (int) Math.ceil(descTextSize));
int alignment = s ? ImageSpan.ALIGN_BOTTOM : ImageSpan.ALIGN_BASELINE;
builder.setSpan(new ImageSpan(dconstImg,alignment), builder.length() -1, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(" ");
descTextSize是TextView.getTextSize()
的结果感谢大家帮助我解决这个问题。
答案 1 :(得分:0)
为什么可以使用setCompundDrawblesWithIntrinsicBounds时的spannable文本?拆分段落并附加一个唯一的ID。 以下示例;
InputStream imgStream = getContext().getAssets().open(constpath+constName+".png");
Drawable dconstImg = Drawable.createFromStream(imgStream, null);
if ( Build.VERSION.SDK_INT >= 21 )
{
text_you_want_to_add_drawable_to.setCompoundDrawablesWithIntrinsicBounds( dconstImg, null ), null, null, null );
} else
{
text_you_want_to_add_drawable_to.setCompoundDrawablesWithIntrinsicBounds( dconstImg, null, null, null );
}
答案 2 :(得分:0)
尝试以下,
ImageSpan is = new ImageSpan(context, R.id.icon);
text.setSpan(is, index, index + strLength, 0);
在此代码索引中=您的$ start位置。 和index + strLength =你的$ end position。