Diablo3 英雄榜-顯示用戶的裝備信息 html
-Volley讀取API的圖片資源 api
本章目標: 網絡
源起 框架
在以前咱們提到過使用Volley獲取Json數據。參看ide
在返回的數據不是馬上返回的。返回後的事件事實上是在onResponse()中來處理。如今咱們要實現多個資源同時來請求,每一個請求都有本身的Request,那麼在onResponse()中來處理就不合理了。咱們須要一個處理多個Request的方式來同時獲取多個圖片和Json數據。this
咱們在英雄裝備界面中,咱們看到的是這個樣子,咱們查看一下Json數據url
來源:http://tw.battle.net/api/d3/profile/kakyban-3879/hero/26135206spa
這個是頭盔的數據,從Json數據中咱們看到對這個界面有影響的是.net
class:barbarian這個是職業爲野蠻人,這個關係到背景的那個影子的圖片。3d
Icon: "unique_helm_set_05_x1_demonhunter_male" 這個是圖片的名稱。那麼它對應的圖片地址是:
http://media.blizzard.com/d3/icons/items/large/unique_helm_set_05_x1_demonhunter_male.png
displayColor: "green" 表明着這個裝備顯示位置的背景爲綠色。
而後?而後沒了,裝備的孔、寶石、賽季裝備圖標都沒有。很明顯,咱們須要再讀一段Json代碼。
到這裏咱們發現咱們如今在這個界面裏面全部的圖片都是延遲加載的,而且分爲2個階段。第一個階段是咱們傳遞過來的Hero數據,可是裏面的圖片都須要延遲加載。第2個階段咱們要想更深刻的讀取更多的圖片,咱們須要在加載完第一批圖片後,在一次加載裝備具體信息裏面的其餘圖片信息,好比寶石框、寶石、賽季圖標等。
繼續分析裝備的具體數據
這個頭盔對應的具體地址是根據參數tooltipParams來的,具體地址爲:
地址怎麼換算參看帖子:
Diablo3 API 分析 http://www.cnblogs.com/canglin/p/4396806.html
在這個Json 數據裏面咱們看到了除了class意外全部的裝備數據,這裏都有。那麼咱們能夠不能夠這樣。打個比方仍是頭盔。
咱們須要顯示3個東西。背景、頭盔圖片、寶石框、寶石。在Item的Json裏面。
"displaycolor": "gree" 表明了背景爲綠色。
"icon": "unique_helm_set_05_x1_demonhunter_male" 這個是圖片的文件名,後綴默認的爲PNG。
"gems": [] 這個表明了寶石。在這裏寶石的顯示可能略有不一樣,由於在沒有讀取到Json之前,是不能讓寶石框開始延遲讀取的。而Json數據獲得之後,在延遲讀取寶石框,明顯這個看起來很很差。可是寶石框不須要從網絡上獲取啊。因此我採起的解決辦法是,將這個圖片加入圖片資源。同理,我將背景顏色也加爲了圖片資源。
(注意圖片的名字裏面可能有職業的信息,可是例子中圖片描述的是demonhunter可是這件裝備確實是barbarian的。)
開始讀取數據的準備
由於這個界面是從英雄列表界面跳轉過來的,因此咱們能夠傳遞一個英雄的Json數據開始。在前面咱們分析道這個Json數據能夠獲得用戶的基本信息、技能列表、裝備信息列表、追隨者信息列表等等。
首先咱們須要獲得裝備的圖片。而在英雄信息裏面有裝備的圖片地址,還有圖片的Id,可是圖片的詳細信息,須要根據tooltipParams來得到。我建立了一個類來裝載這些數據。
public class Items {
private String type;
private String id;
private String name;
private String icon;
private String displayColor;
private String tooltipParams;
private List<String> slots;
private Bitmap largeImage;
private Bitmap smallImage;
private JSONObject itemInfo;
public JSONObject getItemInfo() {
return itemInfo;
}
public void setItemInfo(JSONObject itemInfo) {
this.itemInfo = itemInfo;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getDisplayColor() {
return displayColor;
}
public void setDisplayColor(String displayColor) {
this.displayColor = displayColor;
}
public String getTooltipParams() {
return tooltipParams;
}
public void setTooltipParams(String tooltipParams) {
this.tooltipParams = tooltipParams;
}
public List<String> getSlots() {
return slots;
}
public void setSlots(List<String> slots) {
this.slots = slots;
}
public Bitmap getLargeImage() {
return largeImage;
}
public void setLargeImage(Bitmap largeImage) {
this.largeImage = largeImage;
}
public Bitmap getSmallImage() {
return smallImage;
}
public void setSmallImage(Bitmap smallImage) {
this.smallImage = smallImage;
}
}
在這個類中咱們包含了裝備的大圖片還有縮略圖(有關這個圖的獲取方法上面有介紹)。
咱們首先從Fragment的Arguments()中獲得某些信息從這些信息裏面咱們獲得英雄的信息。而後咱們經過一個Request獲得英雄的信息,在獲得英雄的信息以後咱們在給Items填充數據。首先填充裏面的圖片字段,每一個英雄對應13個Items,每一個Items對應其相關的信息和一個圖片,圖片又分爲大圖片和小圖片(咱們有限獲取大圖片)。
圖片和物品的信息是分開的,得分2次讀取。因此咱們在讀取圖片或者讀取物品信息的時候就順便把另外的也讀取了。
那麼咱們能夠分爲以下階段:
階段一:
讀取英雄信息的Request
階段二
發出13個圖片的Request,而且填充給相應的Items
發出13個裝備詳細信息的Request,而且填充給相應的Items
咱們要處理27個Request。對於這種多個Request的請求,在官方的文檔中給出了一個類
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
在後面咱們將使用此類來處理RequestQueue。
咱們首先要讀取英雄的信息
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
if( mHero == null)
mHero = new Hero();
JSONObject list = new JSONObject();
try {
mHero.setId(response.getInt("id"));
mHero.setName(response.getString("name"));
mHero.setClass1(response.getString("class"));
mHero.setGender(response.getInt("gender"));
mHero.setLevel(response.getInt("level"));
mHero.setParagonLevel(response.getInt("paragonLevel"));
list = response.getJSONObject("items");
itemsCount = list.names().length();
itemsInfoCount = itemsCount;
iniItems(list);
}catch (JSONException ex) {
Log.d("用戶信息讀取錯誤",ex.toString());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
MySingleton.getInstance(getActivity()).addToRequestQueue(jsObjRequest);
由於這裏是階段一,必須等這些數據處理完後才能繼續下面的處理。當處理完成後onRespone()裏面咱們調用了ioiItems()
private void iniItems(JSONObject list) {
try {
//JSONObject head = list.getJSONObject("head");
//setItems(head);
Iterator mKeys = list.keys();
String key;
JSONObject value;
while(mKeys.hasNext()) {
key = (String)mKeys.next();
value = list.getJSONObject(key);
setItems(value,key);
try {
setItemsInfo(value.getString("tooltipParams"));
setImages(value.getString("id"));
} catch (JSONException ex) {}
}
} catch (JSONException ex) {}
}
在這裏咱們遍歷了13個裝備信息,而後根據裝備信息,發出了13讀取圖片的請求和13個讀取裝備詳細信息的請求。
setItemsInfo()方法就是讀取了裝備的詳細信息,裝備的詳細信息咱們在Items類中我直接用一個JSONObject來存儲。
private void setItemsInfo(String tooltipParams) {
String server_url = (String)getArguments().getString(SERVER_URL);
String itemsInfoUrl = Diablo3Api.getITEM_API(server_url,tooltipParams);
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, itemsInfoUrl, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
String id = "";
try {
id = response.getString("id");
} catch (JSONException ex) {}
Items items = mHero.getItemsById(id);
items.setItemInfo(response);
++itemsInfoIndex;
if(canGo()) {
goNextFragment();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(getActivity()).addToRequestQueue(jsObjRequest);
}
setImages()是用來將圖片信息存入largeimage字段。在這裏我有限存儲了large圖片。
private void setImages(String obj) {
final String id = obj;
String largeUrl = Diablo3Api.getICON_API("large", mHero.getItemsById(id).getIcon());
//Log.d("圖片",itemsIndex+"圖片開始"+largeUrl);
ImageRequest request = new ImageRequest(largeUrl,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
mHero.getItemsById(id).setLargeImage(bitmap);
++itemsIndex;
Log.d("圖片","圖片讀取完成"+itemsIndex);
if(canGo()) {
Log.d("圖片","圖片讀取完成");
goNextFragment();
}
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(getActivity()).addToRequestQueue(request);
在每一個onResponse()裏面都有一個canGo()方法,該方法用來判斷是否是26個數據都讀取完成。
private boolean canGo() {
boolean result = false;
if(itemsInfoIndex>=itemsInfoCount && itemsIndex >= itemsCount) {
result = true;
}
return result;
}
若是讀取完成,就能夠跳轉到裝備的顯示界面了。而這個條狀的過程,大概是這個樣子的。
小結:
到這裏,咱們沒有讀取裝備的孔、賽季裝備等數據,排版也難看,可是起碼作到了讀取裝備的顏色,以及裝備的圖片。而讀取的信息我也只是簡單的解析,不少字段我並無解析。而用戶數據,以及傳遞過來的參數等都是簡化的。可是咱們已經離咱們的目標已經很是的接近了,如今咱們須要加入最後一個界面,就是點擊裝備後,顯示裝備的詳細信息。
當完成裝備詳細信息的初始框架後,咱們將會慢慢完善每個界面的信息,美化界面進一步的提升用戶體驗。