/**
* Returns displayable styled text from the provided HTML string.
* Any tags in the HTML will display as a generic
* replacement image which your program can then go through and
* replace with real images.
*
* This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
*/
public static Spanned fromHtml(String source) {
return fromHtml(source, null, null);
}
大概意思就是说此方法根据提供的Html返回一个带样式的字符串,然而所有的标签将被显示成一个通用的图形,你可以在你的程序中替换为真正的图片,这不是扯呢吗?那是难倒服务器还单独把图片传过来?这显然不行啊,而且这个方法的实现是在
fromHtml(source, null, null);
中,进去接着看
/**
* Returns displayable styled text from the provided HTML string.
* Any tags in the HTML will use the specified ImageGetter
* to request a representation of the image (use null if you don't
* want this) and the specified TagHandler to handle unknown tags
* (specify null if you don't want this).
*
* This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
*/
public static Spanned fromHtml(String source, ImageGetter imageGetter,
TagHandler tagHandler) {
Parser parser = new Parser();
try {
parser.setProperty(Parser.schemaProperty, HtmlParser.schema);
} catch (org.xml.sax.SAXNotRecognizedException e) {
// Should not happen.
throw new RuntimeException(e);
} catch (org.xml.sax.SAXNotSupportedException e) {
// Should not happen.
throw new RuntimeException(e);
}
HtmlToSpannedConverter converter =
new HtmlToSpannedConverter(source, imageGetter, tagHandler,
parser);
return converter.convert();
}
跟上边一个参数的方法差不多,重点是这一句Returns displayable styled text from the provided HTML string. Any tags in the HTML will use the specified ImageGetter to request a representation of the image (use null if you don't want this) and the specified TagHandler to handle unknown tags (specify null if you don't want this).大概意思是说任何标签将使用指定的ImageGetter请求图像的表示,看完这个就感觉有点意思了,接着看
/**
* Retrieves images for HTML tags.
*/
public static interface ImageGetter {
/**
* This methos is called when the HTML parser encounters an
* tag. The source
argument is the
* string from the "src" attribute; the return value should be
* a Drawable representation of the image or null
* for a generic replacement image. Make sure you call
* setBounds() on your Drawable if it doesn't already have
* its bounds set.
*/
public Drawable getDrawable(String source);
}
这是一个接口,需要我们自己实现,接口里边的方法是当HTML解释遇到 标签时候会调用,参数source就是中的src,也就是图片的路径了,好了到这里已经有点眉目了,前边不是说让用真实图片替换那个通用的图形嘛,这下有路径了,再看返回参数Drawable,好说啊,从一个网络地址获取Drawable没有直接方法,不过从一个流有啊,
/**
* Create a drawable from an inputstream
*/
public static Drawable createFromStream(InputStream is, String srcName) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
try {
return createFromResourceStream(null, null, is, srcName);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
}
封装个方法以便以后使用(封装真的很重要)
Drawable getImageFromNetwork(String imageUrl) {
URL myFileUrl = null;
Drawable drawable = null;
try {
myFileUrl = new URL(imageUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
drawable = Drawable.createFromStream(is, null);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return drawable;
}
好了,既然是读取网络上的图片就要考虑异步加载了,
Android API > 9 (Honeycomb及之后)版本里,对UI线程/主线程里是不允许联网操作的,如果有网络操作,会抛出NetworkOnMainThreadException的异常,解决办法很简单,另起一个线程就可以了
new Thread(new Runnable() {
Message msg = Message.obtain();
@Override
public void run() {
Html.ImageGetter imageGetter=new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable =getImageFromNetwork(source);
drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
return drawable;
}
};
CharSequence charSequence = Html.fromHtml(html, imageGetter, null);
msg.what = 0x101;
msg.obj = charSequence;
mHandler.sendMessage(msg);
}
}).start();
在线程里边加载html并通过imageGetter把解析出来的src转成Drawable,并把CharSequence传出去,写到这基本上功能就实现了,运行一下,图片也出来了
刚才实现的ImageGetter里边不是有setBounds嘛,改一下宽高就行了,
int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px)
int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,
Log.e("getDefaultDisplay", "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);
int w=screenWidth/2;
int h=w/(drawable.getIntrinsicWidth()/drawable.getIntrinsicHeight());
drawable.setBounds(0,0,w,h);
宽取屏幕一半,高按原图比例缩放,到次才算大功告成,有什么不对的地方还请路过大神指导~
源码下载