先下載資訊,在下滑ListView時,才進行網路讀取圖片。
1.先下載
android-support-v4.jar與
volley.jar,並在專案下建立libs資料夾,放入libs此資料夾
2.先建立一個
list.json檔案,要存成UTF-8格式,並放入圖片url
[{
"title": "鐵刀",
"image": "http://terryyamg.3eeweb.com/test/pic/b01.JPG",
"attack": 480,
"attributes": "無",
"material": ["燕雀石x3", "鐵礦石x8","大地的結晶x7", "砥石x12"]
},
{
"title": "鐵刀【禊】",
"image": "http://terryyamg.3eeweb.com/test/pic/b02.JPG",
"attack": 528,
"attributes": "無",
"material": ["鐵礦石x10", "燕雀石x6", "大地的結晶x10"]
},
{
"title": "鐵刀【神樂】",
"image": "http://terryyamg.3eeweb.com/test/pic/b03.JPG",
"attack": 576,
"attributes": "無",
"material": ["鐵礦石x15", "燕雀石x12", "大地的結晶x15"]
},
{
"title": "斬破刀",
"image": "http://terryyamg.3eeweb.com/test/pic/b04.JPG",
"attack": 624,
"attributes": "雷:250",
"material": ["燕雀石x18", "大地的結晶x30", "電氣袋x3"]
},
{
"title": "鬼斬破",
"image": "http://terryyamg.3eeweb.com/test/pic/b05.JPG",
"attack": 672,
"attributes": "雷:380",
"material": ["輝龍石x5", "燕雀石x20", "電氣袋x5"]
},
{
"title": "鬼神斬破刀",
"image": "http://terryyamg.3eeweb.com/test/pic/b06.JPG",
"attack": 768,
"attributes": "雷:490",
"material": ["輝龍石x8", "靈鶴石x24", "電龍帶肉肋骨x2"]
},
{
"title": "鬼神斬破刀【極】",
"image": "http://terryyamg.3eeweb.com/test/pic/b07.JPG",
"attack": 912,
"attributes": "雷:620",
"material": ["白鳩石x14", "電龍霜降肉x4", "祖龍角x1"]
},
{
"title": "鐵刀【冰刃】",
"image": "http://terryyamg.3eeweb.com/test/pic/b08.JPG",
"attack": 528,
"attributes": "冰:100",
"material": ["鐵礦石x20", "冰結晶x12", "燕雀石x2"]
},
{
"title": "白猿薙",
"image": "http://terryyamg.3eeweb.com/test/pic/b09.JPG",
"attack": 576,
"attributes": "冰:150",
"material": ["雪獅子的毛x6","鐵礦石x5","冰結晶x8"]
},
{
"title": "白猿薙【中級】",
"image": "http://terryyamg.3eeweb.com/test/pic/b10.JPG",
"attack": 672,
"attributes": "冰:250",
"material": ["雪獅子王牙x3","雪獅子王的鬍鬚x5","冰結晶x20"]
},
{
"title": "白猿薙【高級】",
"image": "http://terryyamg.3eeweb.com/test/pic/b11.JPG",
"attack": 864,
"attributes": "冰:350",
"material": ["雪獅子王的利牙x5","雪獅子的剛毛x8","雪獅子王尾x6"]
},
{
"title": "白猿薙【驚嘆】",
"image": "http://terryyamg.3eeweb.com/test/pic/b12.JPG",
"attack": 1008,
"attributes": "冰:560",
"material": ["牙獸種的重牙x5","草食種的上皮x18","冰冷袋x3"]
}]
3.
AndroidManifest.xml先加入
uses-permission android:name="android.permission.INTERNET"
與
android:name=".AppController"
4./res/layout/
activity_main.xml 主頁面放入ListView
5./res/layout/
list.xml 建立客製化ListView項目
先建立
AppController、
JsonArrayPostRequest與
LruBitmapCache三個檔案,此三個檔案不需要進行修改
6.
AppController.java
package tw.android;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import android.app.Application;
import android.text.TextUtils;
import android.util.Log;
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static AppController mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
Log.i("mInstance.this", mInstance+"");
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache());
}
return this.mImageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
7.
JsonArrayPostRequest.java 編碼
package tw.android;
import java.io.UnsupportedEncodingException;
import org.json.JSONArray;
import org.json.JSONException;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
public class JsonArrayPostRequest extends Request<JSONArray> {
private Response.Listener<JSONArray> mListener;
public JsonArrayPostRequest(String url, Response.Listener<JSONArray> listener,
Response.ErrorListener errorListener){
super(Method.GET, url, errorListener);
mListener = listener;
}
@Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
try {
/*utf-8 編碼 否則中文會出現亂碼*/
String jsonString = new String(response.data, "UTF-8");
return Response.success(new JSONArray(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e){
return Response.error(new ParseError(e));
} catch (JSONException je){
return Response.error(new ParseError(je));
}
}
@Override
protected void deliverResponse(JSONArray response) {
mListener.onResponse(response);
}
}
8.
LruBitmapCache.java 緩衝
package tw.android;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.toolbox.ImageLoader.ImageCache;
/*緩衝*/
public class LruBitmapCache extends LruCache<String, Bitmap> implements
ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
public Bitmap getBitmap(String url) {
return get(url);
}
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
再建立符合自己需要的清單
9.
ListItem.java 清單資訊
package tw.android;
import java.util.ArrayList;
public class ListItem {
private String title, thumbnailUrl,attributes;
private int attack;
private ArrayList material;
public ListItem() {
}
public ListItem(String name, String thumbnailUrl, int attack, String attributes,
ArrayList material) {
this.title = name;
this.thumbnailUrl = thumbnailUrl;
this.attack = attack;
this.attributes = attributes;
this.material = material;
}
/* 名稱 */
public String getTitle() {
return title;
}
public void setTitle(String name) {
this.title = name;
}
/* 縮圖 */
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
/* 攻擊力 */
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
/* 屬性 */
public String getAttributes() {
return attributes;
}
public void setAttributes(String attributes) {
this.attributes = attributes;
}
/* 材料 */
public ArrayList getMaterial() {
return material;
}
public void setMaterial(ArrayList material) {
this.material = material;
}
}
10.
CustomListAdapter.java 建立listview項目清單
package tw.android;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List items;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List items) {
this.activity = activity;
this.items = items;
}
public int getCount() {
return items.size();
}
public Object getItem(int location) {
return items.get(location);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView attack = (TextView) convertView.findViewById(R.id.attack);
TextView attributes = (TextView) convertView
.findViewById(R.id.attributes);
TextView material = (TextView) convertView.findViewById(R.id.material);
// getting movie data for the row
ListItem m = items.get(position);
// 縮圖
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// 名稱
title.setText(m.getTitle());
// 攻擊力
attack.setText("攻擊力: " + String.valueOf(m.getAttack()));
// 屬性
attributes.setText("屬性: " + m.getAttributes());
// 材料
String materialStr = "";
for (String str : m.getMaterial()) {
materialStr += str + ", ";
}
materialStr = materialStr.length() > 0 ? materialStr.substring(0,
materialStr.length() - 2) : materialStr;
material.setText(materialStr);
return convertView;
}
}
11.
MainActivity.java 主頁面
package tw.android;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
public class MainActivity extends Activity {// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// json檔案位置
private static final String url = "http://terryyamg.3eeweb.com/test/list.json";
private List listItem = new ArrayList();
private ListView listView;
private CustomListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, listItem);
listView.setAdapter(adapter);
// 取得資料並編碼
JsonArrayPostRequest itemReq = new JsonArrayPostRequest(url,
new Response.Listener() {
public void onResponse(JSONArray response) {
// 解析json
for (int i = 0; i < response.length(); i++) {
try {
//取得回應物件
JSONObject obj = response.getJSONObject(i);
//取得對定標題並放入item內
ListItem item = new ListItem();
item.setTitle(obj.getString("title"));
item.setThumbnailUrl(obj.getString("image"));
item.setAttack(obj.getInt("attack"));
item.setAttributes(obj.getString("attributes"));
//多項目處理
JSONArray materialArry = obj
.getJSONArray("material");
ArrayList material = new ArrayList();
for (int j = 0; j < materialArry.length(); j++) {
material.add((String) materialArry.get(j));
}
item.setMaterial(material);
// 將所有項目item放入listItem陣列
listItem.add(item);
} catch (JSONException e) {
e.printStackTrace();
}
}
// 更新adapter數據
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// 使用AppController內的排序
AppController.getInstance().addToRequestQueue(itemReq);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
1.檔案下載:
https://github.com/terryyamg/CacheImageTest
2.參考連結:
http://www.androidhive.info/2014/07/android-custom-listview-with-image-and-text-using-volley/
http://dnakreatif.com/programming/android-volley-jsonarray-post-with-params/
http://stackoverflow.com/questions/19267616/why-does-volleys-response-string-use-an-encoding-different-from-that-in-the-res