Android自訂群組件ListView
下面代碼設計了非同步任務、JSon解析、自訂群組件、IO流、檔案下載、適配器原理等知識點。
代碼實現從伺服器上讀取Json字串。
Json字串如下。
{object:{persons:[{name:'呵呵',image:'http://10.0.159.12:8080/Web/s1.png'},{name:'哈哈',image:'http://10.0.159.12:8080/Web/s1.png'},{name:'嘿嘿',image:'http://10.0.159.12:8080/Web/s2.jpg'}]}}
利用ListView控制項將name和image圖片顯示出來。效果
思路(解析json字串,然後再次讀取伺服器上的圖片解析成byte[]格式。)
建立ImageInfo類儲存ListView顯示的資料:一個是顯示名字name屬性,一個圖片資料。
package com.example.day22_domain;import java.util.Arrays;public class ImageInfo {private String name;private byte[] imagebit;public ImageInfo() {super();// TODO Auto-generated constructor stub}public ImageInfo(String name, byte[] imagebit) {super();this.name = name;this.imagebit = imagebit;}public String getName() {return name;}public void setName(String name) {this.name = name;}public byte[] getImagebit() {return imagebit;}public void setImagebit(byte[] imagebit) {this.imagebit = imagebit;}@Overridepublic String toString() {return ImageInfo [name= + name + , imagebit=+ Arrays.toString(imagebit) + ];}}
寫了一個工具類用來解析Json資料和圖片:
package com.example.day22_tools;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import com.example.day22_domain.ImageInfo;public class HttpUtils {public HttpUtils() {}public static String getJsonString(String path){try {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setRequestMethod(GET);conn.setConnectTimeout(5000);conn.setDoInput(true);if(conn.getResponseCode()==200){InputStream inputStream = conn.getInputStream();return changetToString(inputStream);}}catch(Exception e){ e.printStackTrace();}return null;}private static String changetToString(InputStream inputStream) {ByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] arr = new byte[1024];int len = 0;try {while((len = inputStream.read(arr))!=-1){bos.write(arr,0,len);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}byte[] b = bos.toByteArray();String ss = new String(b,0,b.length);return ss;}public static List getImageInfo(String jsonString){List list = new ArrayList();try {JSONObject obj = new JSONObject(jsonString);JSONObject jsonObj = obj.getJSONObject(object);JSONArray array = jsonObj.getJSONArray(persons);for(int i=0;i主介面:通過非同步任務進行後台下載圖片解析Json資料,然後顯示在自訂的ListView組件中。
package com.example.day22_all;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.example.day22_domain.ImageInfo;import com.example.day22_tools.HttpUtils;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity {private ListView listView;private String path=http://10.0.159.12:8080/Web/servlet/JsonServlet;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView = (ListView) findViewById(R.id.listView);new DownText().execute(path);}class DownText extends AsyncTask>>{@Overrideprotected List> doInBackground(String... params) {String jsonStr=HttpUtils.getJsonString(params[0]);System.out.println(jsonStr+jsonStr);List list=HttpUtils.getImageInfo(jsonStr);System.out.println(ImageInfo);List> imageinfo=new ArrayList>();for(int i=0;i map=new HashMap();String name=list.get(i).getName();byte[] arr=list.get(i).getImagebit();Bitmap bitMap = BitmapFactory.decodeByteArray(arr, 0, arr.length);map.put(name, name);map.put(bitmap, bitMap);imageinfo.add(map);}return imageinfo;}@Overrideprotected void onPostExecute(List> result) {super.onPostExecute(result);MyAdapter adapter = new MyAdapter(MainActivity.this,result);listView.setAdapter(adapter);}class MyAdapter extends BaseAdapter{private Context context;private List> list;public MyAdapter(Context context, List> list) {this.context = context;this.list = list;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn list.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if(convertView==null){convertView = LayoutInflater.from(context).inflate(R.layout.other_image, nuviewHolder = new ViewHolder();viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image);viewHolder.textView = (TextView) convertView.findViewById(R.id.text);convertView.setTag(viewHolder);}elseviewHolder = (ViewHolder) convertView.getTag();//viewHolder.imageView.setImageResource(Integer.parseInt(list.get(position).get(bitmap).toString()));viewHolder.textView.setText(list.get(position).get(name).toString());viewHolder.imageView.setImageBitmap((Bitmap)list.get(position).get(bitmap));return convertView;} class ViewHolder { ImageView imageView; TextView textView; }}}}注釋:
/*
在實際開發中LayoutInflater這個類還是非常有用的,它的作用類似於findViewById()。不同點是LayoutInflater是用來找res/layout/下的xml布局檔案,並且執行個體化;而findViewById()是找xml布局檔案下的具體widget控制項(如Button、TextView等)。
具體作用:
1、對於一個沒有被載入或者想要動態載入的介面,都需要使用LayoutInflater.inflate()來載入;
2、對於一個已經載入的介面,就可以使用Activiyt.findViewById()方法來獲得其中的介面元素。
LayoutInflater 是一個抽象類別,在文檔中如下聲明:
public abstract class LayoutInflater extends Object
獲得 LayoutInflater 執行個體的三種方式
1. LayoutInflater inflater = getLayoutInflater();//調用Activity的getLayoutInflater()
2. LayoutInflater inflater = LayoutInflater.from(context);
3. LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
其實,這三種方式本質是相同的,從源碼中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是調用 PhoneWindow 的getLayoutInflater()方法,看一下該原始碼:
public PhoneWindow(Context context)
{
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
可以看出它其實是調用 LayoutInflater.from(context)。
LayoutInflater.from(context):
public static LayoutInflater from(Context context)
{
LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null)
{
throw new AssertionError(LayoutInflater not found.);
}
return LayoutInflater;
}
可以看出它其實調用 context.getSystemService()。
結論:所以這三種方式最終本質是都是調用的Context.getSystemService()。
注意:
·inflate 方法與 findViewById 方法不同;
·inflater 是用來找 res/layout 下的 xml 布局檔案,並且執行個體化;
·findViewById() 是找具體 xml 布局檔案中的具體 widget 控制項(如:Button、TextView 等)。
*/
寫一下布局檔案和伺服器就好了:
activity_main.xml