前言:程序猿真的是有个通病啊,电梯上就在研究电梯的逻辑代码,走路看到红绿灯也会去研究算法,今天心情不错,于是就发了一个说说,发现某q空间中显示了我发的说说,但是我发的笑脸跟哭脸表情由于网络慢,很久才加载出来,于是我惊讶了,原来表情发的时候存在本地,等发完显示确实网络上拿的,而且还支持gif,好吧,不得不说某q真是牛逼!!
网上textView显示网络图片的例子一大堆啊,但是都不靠谱,于是我弄出了一个靠谱点的思路。
简单介绍下思路吧:
主要就是利用text.setText(Html.fromHtml(“html”));把后台返回的html显示在textview中,后台返回的html可能是这样的:
String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";
那么如果img中包含的是一个网络的图片链接,我们的源码中有处理吗??我们接下来看看Html.fromHtml源码:
@Deprecated
public static Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler) {
return fromHtml(source, FROM_HTML_MODE_LEGACY, imageGetter, tagHandler);
}
接着往下看:
public static Spanned fromHtml(String source, int flags, ImageGetter imageGetter,
TagHandler tagHandler) {
.......省略代码
HtmlToSpannedConverter converter =
new HtmlToSpannedConverter(source, imageGetter, tagHandler, parser, flags);
return converter.convert();
}
然后重点看一下HtmlToSpannedConverter类,在这个类中我们又看到了这么一个方法:
private void handleStartTag(String tag, Attributes attributes) {
if (tag.equalsIgnoreCase("br")) {
// We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>
// so we can safely emit the linebreaks when we handle the close tag.
} else if (tag.equalsIgnoreCase("p")) {
startBlockElement(mSpannableStringBuilder, attributes, getMarginParagraph());
startCssStyle(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("ul")) {
startBlockElement(mSpannableStringBuilder, attributes, getMarginList());
} else if (tag.equalsIgnoreCase("li")) {
startLi(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("div")) {
startBlockElement(mSpannableStringBuilder, attributes, getMarginDiv());
} else if (tag.equalsIgnoreCase("span")) {
startCssStyle(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("strong")) {
start(mSpannableStringBuilder, new Bold());
} else if (tag.equalsIgnoreCase("b")) {
start(mSpannableStringBuilder, new Bold());
} else if (tag.equalsIgnoreCase("em")) {
start(mSpannableStringBuilder, new Italic());
} else if (tag.equalsIgnoreCase("cite")) {
start(mSpannableStringBuilder, new Italic());
} else if (tag.equalsIgnoreCase("dfn")) {
start(mSpannableStringBuilder, new Italic());
} else if (tag.equalsIgnoreCase("i")) {
start(mSpannableStringBuilder, new Italic());
} else if (tag.equalsIgnoreCase("big")) {
start(mSpannableStringBuilder, new Big());
} else if (tag.equalsIgnoreCase("small")) {
start(mSpannableStringBuilder, new Small());
} else if (tag.equalsIgnoreCase("font")) {
startFont(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("blockquote")) {
startBlockquote(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("tt")) {
start(mSpannableStringBuilder, new Monospace());
} else if (tag.equalsIgnoreCase("a")) {
startA(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("u")) {
start(mSpannableStringBuilder, new Underline());
} else if (tag.equalsIgnoreCase("del")) {
start(mSpannableStringBuilder, new Strikethrough());
} else if (tag.equalsIgnoreCase("s")) {
start(mSpannableStringBuilder, new Strikethrough());
} else if (tag.equalsIgnoreCase("strike")) {
start(mSpannableStringBuilder, new Strikethrough());
} else if (tag.equalsIgnoreCase("sup")) {
start(mSpannableStringBuilder, new Super());
} else if (tag.equalsIgnoreCase("sub")) {
start(mSpannableStringBuilder, new Sub());
} else if (tag.length() == 2 &&
Character.toLowerCase(tag.charAt(0)) == 'h' &&
tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
startHeading(mSpannableStringBuilder, attributes, tag.charAt(1) - '1');
} else if (tag.equalsIgnoreCase("img")) {
startImg(mSpannableStringBuilder, attributes, mImageGetter);
} else if (mTagHandler != null) {
mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
}
}
重点看一下这个判断:
else if (tag.equalsIgnoreCase("img")) {
startImg(mSpannableStringBuilder, attributes, mImageGetter);
}
我们看看startImg方法:
private static void startImg(Editable text, Attributes attributes, Html.ImageGetter img) {
String src = attributes.getValue("", "src");
Drawable d = null;
if (img != null) {
d = img.getDrawable(src);
}
if (d == null) {
d = Resources.getSystem().
getDrawable(com.android.internal.R.drawable.unknown_image);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
}
int len = text.length();
text.append("\uFFFC");
text.setSpan(new ImageSpan(d, src), len, text.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
看到这里了如果做过TextView的富文本的童鞋有没有一点熟悉了呢?直接创建了一个ImageSpan,然后传入了一个Drawable,那么这个Drawable是哪里来的呢?
是通过 Html.ImageGetter的getDrawable方法获取的!! 那么这个mImageGetter对象有没有初始化呢? 我们在代码中找找:
是在fromHtml方法中传进去的,也就是说,如果我们不传ImageGetter对象的话,当获取到img标签时,如果ImageGetter为null,那么会走下面判断:
if (img != null) {
d = img.getDrawable(src);
}
if (d == null) {
d = Resources.getSystem().
getDrawable(com.android.internal.R.drawable.unknown_image);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
}
而unknown_image就是android系统默认给的一张占位图。
有了前面的了解了,然后我们就开动了,首先得创建一个ImageGetter对象在Html.fromHtml中传给TextView.然后当判断html中有img标签的时候,我们就去网络加载图片,加载完毕后再次赋给TextView.
由于代码简单,我就直接上代码了:
public TextView text;
private static class MyHandler extends Handler {
private WeakReference<PropertyAnimActivity4_evaluator>activityWeakReference;
public MyHandler(PropertyAnimActivity4_evaluator activity){
activityWeakReference=new WeakReference<PropertyAnimActivity4_evaluator>(activity);
}
@Override
public void handleMessage(Message msg) {
final Drawable drawable= (Drawable) msg.obj;
PropertyAnimActivity4_evaluator activity=activityWeakReference.get();
if(activity!=null){
String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";
Spanned spanned = Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
return drawable;
}
}, null);
activity.text.setText(spanned);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property_anim_activity4_evaluator);
bt_anim_view= (Button) findViewById(R.id.bt_anim_view);
text= (TextView) findViewById(R.id.text);
String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";
Spanned spanned = Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
AsyncTask<String, Float, Drawable> task = new AsyncTask<String, Float, Drawable>() {
@Override
protected Drawable doInBackground(String... params) {
try {
URL url=new URL(params[0]);
URLConnection con = url.openConnection();
con.setConnectTimeout(50000);
Drawable d = Drawable.createFromStream(con.getInputStream(), "");
d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
return d;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Drawable drawable) {
Message msg=Message.obtain();
msg.obj=drawable;
new MyHandler(PropertyAnimActivity4_evaluator.this).sendMessage(msg);
}
}.execute(source);
BitmapDrawable bitmapDrawable = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
bitmapDrawable.setBounds(0,0,bitmapDrawable.getIntrinsicWidth(),bitmapDrawable.getIntrinsicHeight());
return bitmapDrawable;
}
}, null);
text.setText(spanned);
}
如果是像某Q一样,放在ListView中,并且显示的是gif图片,又咋搞呢????? 小伙伴们如果有好的思路,或者做过类型的,一起探讨一下哈!!!拜谢啦~~~~