这里有一点新的知识,就是通过链接,直接获得图片信息。
使用到了一个开源软件,android-smart-image-view-master 实现这个功能很容易。
只需要把原来layout文件夹下配置文件的ImageView 改为 com.loopj.android.image.SmartImageView ,然后使用时,把整个com.loopj.android.image包拷贝到使用的项目src目录下,然后把ImageView 改为SmartImageView 然后调用 setImageUrl,传入图片的url 即可。
注:有的人导入包时会报错,run方法上的@Override需要移除,这是因为Android默认使用的编译器对注解支持不太好,直接移除注解即可。
核心代码:
public class MainActivity extends Activity {
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
//有一个空消息,当发送过来,表示子线程已经获得了信息,可以展示数据
lv_list.setAdapter(new MyAdapter());
}
};
private ListView lv_list;
private ArrayList<NewsItem>newsList=new ArrayList<NewsItem>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv_list=(ListView) findViewById(R.id.lv_list);
initData(); //不能在这个方法后直展示数据,因为在调用子线程执行数据初始化,主线程执行到展示数据时,数据不一定初始化完成。
}
private void initData() {
new Thread(){
@Override
public void run() {
try{
URL url =new URL("http://10.0.2.2:8080/newsclient/news.xml");
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
int code = connection.getResponseCode();
if(code==200){
InputStream is=connection.getInputStream();
XmlPullParser pullParser=Xml.newPullParser();
pullParser.setInput(is,"UTF-8");
int eventType=pullParser.getEventType();
NewsItem item=null;
while(eventType!=XmlPullParser.END_DOCUMENT)
{
switch(eventType)
{
case XmlPullParser.START_TAG:
if("news".equals(pullParser.getName()))
{
item=new NewsItem();
}
else if("title".equals(pullParser.getName()))
{
item.title=pullParser.nextText();
}
else if("detail".equals(pullParser.getName()))
{
item.content=pullParser.nextText();
}
else if("comment".equals(pullParser.getName()))
{
item.comment=pullParser.nextText()+"条评论";
}
else if("image".equals(pullParser.getName()))
{
item.img=pullParser.nextText();
}
break;
case XmlPullParser.END_TAG:
if("news".equals(pullParser.getName()))
{
newsList.add(item);
}
break;
}
eventType=pullParser.next();
}
handler.sendEmptyMessage(1);//给主线程发送可以展示数据的消息。
}
}catch(Exception e){
e.printStackTrace();
}
}
}.start();
}
private class MyAdapter extends BaseAdapter
{
public int getCount() {
return newsList.size();
}
public Object getItem(int position) {
return newsList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v=null;
if(convertView !=null)
{
v=convertView;
}
else{
v=View.inflate(MainActivity.this, R.layout.items, null);
}
SmartImageView iv_pic=(SmartImageView) v.findViewById(R.id.iv_pic);
TextView tv_comment=(TextView) v.findViewById(R.id.tv_comment);
TextView tv_content=(TextView) v.findViewById(R.id.tv_content);
TextView tv_title=(TextView) v.findViewById(R.id.tv_title);
NewsItem item=newsList.get(position);
tv_title.setText(item.title);
tv_content.setText(item.content);
tv_comment.setText(item.comment);
// System.out.println(item.img);
iv_pic.setImageUrl(item.img);
return v;
}
}
}
注意,要展示的图片,不能太大,不然会报很多奇怪的错误。
然后对SmartImageView 进行简单模拟,但是没有把加载好的图片进行缓存(源代码进行了缓存,及优化):(其实和图片查看器代码十分相似)
public class MyImageView extends ImageView {
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
Bitmap bitmap=(Bitmap) msg.obj;
MyImageView.this.setImageBitmap(bitmap);
}
};
//如果xml中有style属性,则解析后会转化为dafStype传进来。
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
//多了一个属性集合,通过解析Xml获取属性,封装在attrs中
//系统在解析xml时,就会调用这个构造器。
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public MyImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public void setImageUrl(final String path)
{
new Thread(){
@Override
public void run() {
try {
URL url=new URL(path);
HttpURLConnection connect=(HttpURLConnection) url.openConnection();
connect.setRequestMethod("GET");
connect.setConnectTimeout(10000);
int code=connect.getResponseCode();
if(code==200)
{
InputStream is =connect.getInputStream();
Bitmap bit=BitmapFactory.decodeStream(is);
Message msg=new Message();
msg.obj=bit;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
更完善些的话:
判断当返回码不为200,或者中途捕获异常,则应当给原来图片的位置防止一个默认图,而不是空着。
把图片放在本地,等到异常时,便可以把图片取出来。
更完善点的代码:
public class MyImageView extends ImageView {
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.arg1==1)
{
Bitmap bitmap=(Bitmap) msg.obj;
MyImageView.this.setImageBitmap(bitmap);
}
else
{
MyImageView.this.setImageResource(msg.arg2);
}
}
};
//如果xml中有style属性,则解析后会转化为dafStype传进来。
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
//多了一个属性集合,通过解析Xml获取属性,封装在attrs中
//系统在解析xml时,就会调用这个构造器。
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public MyImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public void setImageUrl(final String path,final int resId)
{
new Thread(){
@Override
public void run() {
try {
URL url=new URL(path);
HttpURLConnection connect=(HttpURLConnection) url.openConnection();
connect.setRequestMethod("GET");
connect.setConnectTimeout(10000);
int code=connect.getResponseCode();
if(code==200)
{
InputStream is =connect.getInputStream();
Bitmap bit=BitmapFactory.decodeStream(is);
Message msg=new Message();
msg.arg1=1;
msg.obj=bit;
handler.sendMessage(msg);
}
else{
Message msg=new Message();
msg.arg1=0;
msg.arg2=resId;
handler.sendMessage(msg);
}
} catch (Exception e) {
Message msg=new Message();
msg.arg1=0;
msg.arg2=resId;
handler.sendMessage(msg);
e.printStackTrace();
}
}
}.start();
}
}
调用时这样写:
MyImageView miv=(MyImageView) findViewById(R.id.iv_pic);
miv.setImageUrl("http://10.0.2.2:8080/newsclient/a.jpg",R.drawable.ic_launcher);