标签:
Diablo3 英雄榜-显示用户的装备信息
-Volley读取API的图片资源
本章目标:
源起
在之前我们提到过使用Volley获取Json数据。参看
在返回的数据不是立刻返回的。返回后的事件事实上是在onResponse()中来处理。现在我们要实现多个资源同时来请求,每个请求都有自己的Request,那么在onResponse()中来处理就不合理了。我们需要一个处理多个Request的方式来同时获取多个图片和Json数据。
我们在英雄装备界面中,我们看到的是这个样子,我们查看一下Json数据
来源:http://tw.battle.net/api/d3/profile/kakyban-3879/hero/26135206
这个是头盔的数据,从Json数据中我们看到对这个界面有影响的是
class:barbarian这个是职业为野蛮人,这个关系到背景的那个影子的图片。
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;
}
如果读取完成,就可以跳转到装备的显示界面了。而这个条状的过程,大概是这个样子的。
小结:
到这里,我们没有读取装备的孔、赛季装备等数据,排版也难看,但是起码做到了读取装备的颜色,以及装备的图片。而读取的信息我也只是简单的解析,很多字段我并没有解析。而用户数据,以及传递过来的参数等都是简化的。但是我们已经离我们的目标已经非常的接近了,现在我们需要加入最后一个界面,就是点击装备后,显示装备的详细信息。
当完成装备详细信息的初始框架后,我们将会慢慢完善每一个界面的信息,美化界面进一步的提高用户体验。
Diablo3 英雄榜-显示用户的装备信息-Volley读取API的图片资源,使用MySingleton管理RequestQueue
标签:
原文地址:http://www.cnblogs.com/canglin/p/4438123.html