ListView优化的模型示意图
实例代码:
业务逻辑代码:
package com.hsj.example.asyncloadxmldatademo08; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.hsj.example.asyncloadxmldatademo08.hsj.domain.Person; import com.hsj.example.asyncloadxmldatademo08.hsj.utils.NetUtils; import java.io.InputStream; import java.util.List; public class MainActivity extends AppCompatActivity { private ListView listView_persons; private MyAdapter adapter; private List<Person> personList; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.progressDialog=new ProgressDialog(this); this.progressDialog.setMessage("正在加载网络数据,请稍等......"); this.progressDialog.setCancelable(true); this.listView_persons= (ListView) this.findViewById(R.id.listView_persons); String path = "http://10.211.55.4:8080/persons.xml"; new LoadNetDataAsyncTask().execute(path); } private final class LoadNetDataAsyncTask extends AsyncTask<String,Void,List<Person>> { @Override protected void onPreExecute() { progressDialog.show(); } @Override protected List<Person> doInBackground(String... params) { try { InputStream inputStream= NetUtils.getInputStreamByPath(params[0]); if(inputStream!=null){ String json= NetUtils.getStringByInputStream(inputStream); if(json!=null){ return NetUtils.getPersonsByXmlString(json); } } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(List<Person> persons) { adapter=new MyAdapter(persons); listView_persons.setAdapter(adapter); progressDialog.dismiss(); } } private final class MyAdapter extends BaseAdapter { private List<Person> personList; private ViewHolder viewHolder; public MyAdapter(List<Person> personList) { this.personList=personList; } @Override public int getCount() { return personList.size(); } @Override public Object getItem(int position) { return personList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //1.得到数据 Person person=personList.get(position); if(convertView==null){ viewHolder=new ViewHolder(); convertView=View.inflate(MainActivity.this,R.layout.person_item,null); viewHolder.imageView_header= (ImageView) convertView.findViewById(R.id.imageView_header); viewHolder.textView_name= (TextView) convertView.findViewById(R.id.textView_name); viewHolder.textView_age= (TextView) convertView.findViewById(R.id.textView_age); convertView.setTag(viewHolder); }else{ viewHolder= (ViewHolder) convertView.getTag(); } //解决图片错位问题 final String cover=person.getHeader(); viewHolder.imageView_header.setTag(cover); //viewHolder.imageView_header.setImageBitmap(person.getHeader()); class LoadImageAsyncTask extends AsyncTask<String,Void,Bitmap>{ @Override protected Bitmap doInBackground(String... params) { try { InputStream inputStream=NetUtils.getInputStreamByPath(params[0]); if(inputStream!=null){ return BitmapFactory.decodeStream(inputStream); } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap bitmap) { if(bitmap!=null && viewHolder.imageView_header.getTag()!=null && cover.equals(viewHolder.imageView_header.getTag())){ viewHolder.imageView_header.setImageBitmap(bitmap); } } } new LoadImageAsyncTask().execute(person.getHeader()); viewHolder.textView_name.setText(person.getName()); viewHolder.textView_age.setText(String.valueOf(person.getAge())); return convertView; } } class ViewHolder{ ImageView imageView_header; TextView textView_name; TextView textView_age; } }
工具类代码:
package com.hsj.example.asyncloadxmldatademo08.hsj.utils; import android.util.Xml; import com.hsj.example.asyncloadxmldatademo08.hsj.domain.Person; import org.xmlpull.v1.XmlPullParser; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Created by hsjwcf on 2018/6/1. */ public class NetUtils { /** * 根据网址得到输入流对象 * @param path * @return */ public static InputStream getInputStreamByPath(String path) throws Exception { URL url=new URL(path); HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(3000); int responseCode=httpURLConnection.getResponseCode(); if(responseCode==HttpURLConnection.HTTP_OK){ return httpURLConnection.getInputStream(); } return null; } /** * 通过 InputStream 得到字节数组 * @param inputStream * @return */ public static byte[] getByteArrayByInputStream(InputStream inputStream) throws IOException { ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); byte[] buffer=new byte[1024]; int len=0; while ((len=inputStream.read(buffer))!=-1){ byteArrayOutputStream.write(buffer,0,len); } return byteArrayOutputStream.toByteArray(); } /** * 将输入流转换成字符串 * @param inputStream * @return * @throws IOException */ public static String getStringByInputStream(InputStream inputStream) throws IOException { return new String(getByteArrayByInputStream(inputStream)); } /** * 面试题:市面上常用的解析XML的技术有哪些? * DOM * SAX * JDOM * DOM4J * PULL(android 自带的解析Xml的技术) * * @param xml * @return * @throws Exception */ public static List<Person> getPersonsByXmlString(String xml) throws Exception { List<Person> persons=null; /* PULL 基于事件驱动的解析方式 */ //1.得到Pull解析器对象 XmlPullParser xmlPullParser= Xml.newPullParser(); //2.设置需要解析的Xml 数据 xmlPullParser.setInput(new StringReader(xml)); //3.得到事件对象 int eventType= xmlPullParser.getEventType(); System.out.println("eventType="+eventType); Person person=null; //XmlPullParser.END_DOCUMENT=1 while (eventType!=XmlPullParser.END_DOCUMENT){ switch (eventType){ //XmlPullParser.START_DOCUMENT=0:开始解析Xml时执行,而且只执行一次 case XmlPullParser.START_DOCUMENT: persons=new ArrayList<>(); System.out.println("==START_DOCUMENT==="); break; //XmlPullParser.START_TAG=2:遇到开始标签时执行 case XmlPullParser.START_TAG: //xmlPullParser.getName():得到标签名 String startTag=xmlPullParser.getName(); if("person".equals(startTag)){ person=new Person(); //根据索引值得到属性值,索引值从0开始 //String id=xmlPullParser.getAttributeValue(0); //根据属性名得到属性值 String id=xmlPullParser.getAttributeValue(null,"id"); System.out.println("id="+id); }else if("name".equals(startTag)){ //得到当前标签后面的文本内容,同时事件值向后推动了一下 String name=xmlPullParser.nextText(); person.setName(name); System.out.println("name="+name); }else if("age".equals(startTag)){ String age=xmlPullParser.nextText(); person.setAge(Integer.parseInt(age)); System.out.println("age="+age); }else if("header".equals(startTag)){ String header=xmlPullParser.nextText(); person.setHeader(header); persons.add(person); System.out.println("header="+header); } System.out.println("===START_TAG="+startTag+"=="); break; } //修改事件值 eventType=xmlPullParser.next(); } System.out.println("persons="+persons); return persons; } }