Leo仿【DOTA视频站】项目实践【三】---- 获取DOTA2视频已经XListView实现上拉加载更多、下拉刷新

来源:互联网 发布:股票交易软件 手机版 编辑:程序博客网 时间:2024/05/16 11:41

        在前一篇文章《优酷SDK学习》中使用优酷API根据视频种类进行搜索,可是优酷设置的视频种类中只有游戏,没有我想要搜索的DOTA2视频。于是为了弄懂怎么去搜索DOTA2视频,专门在优酷网页上打开了一个DOTA2视频,把他的网址记下来,然后解析出该视频的id,再运用id将该视频所用的具体信息打印出来。我发现在该视频的信息中有一个tag属性,记录了该视频是一个DOTA2视频。于是我就在想能不能根据这个tag去进行搜索。查看优酷API之后,果真发现有根据tag搜索视频的。多个tag之间用逗号分开。

public static final String TAG_URL = "https://openapi.youku.com/v2/searches/video/by_tag.json";

        在解决了这个问题之后,然后就是listview显示的问题了。对于ListView的上下拉刷新加载问题,我直接引用了开源框架XListView。下面直接上主界面显示DOTA2视频列表的代码。

package com.jgh.watchdota;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import com.jgh.cache.FileService;import com.jgh.util.DotaItemAdapter;import com.jgh.util.ItemDate;import com.jgh.util.StaticsUtil;import me.maxwin.view.XListView;import me.maxwin.view.XListView.IXListViewListener;import android.app.Activity;import android.app.Fragment;import android.content.Context;import android.content.Intent;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.Toast;public class HomeFragment extends Fragment implements IXListViewListener,OnItemClickListener {public static final String TAG_URL = "https://openapi.youku.com/v2/searches/video/by_tag.json";// 优酷API搜索urlpublic Activity mActivity;private XListView mListView;// ListViewprivate DotaItemAdapter mAdapter;// 自定义适配器private static List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();// ListView中的Item集合private Map<String, String> params;// 搜索的参数private Handler mHandler;private Handler handler;private int page = 1;// 搜索的当前页数private static int pageCount = 20;// 每页搜索的item条数private boolean isOnRefresh = false;// 标记是否正处于下拉刷新状态@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubView view = inflater.inflate(R.layout.layout_home, container, false);params = new HashMap<String, String>();// 初始化搜索参数params.put("client_id", StaticsUtil.CLIENT_ID);// APK申请的client_idparams.put("category", "游戏");params.put("tag", "DOTA2");params.put("orderby", "published");params.put("page", page+"");params.put("count", pageCount+"");mActivity = getActivity();initList(view);// 初始化ListViewreturn view;}private void initList(View view) {// TODO Auto-generated method stubgetItems();// 开启异步线程获取itemmListView = (XListView) view.findViewById(R.id.xListView);mListView.setPullLoadEnable(true);// 上拉加载更多mListView.setPullRefreshEnable(false);// 下拉刷新,这里暂时关闭该功能mListView.setXListViewListener(this);mListView.setOnItemClickListener(this);handler = new Handler();mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubswitch (msg.what) {case 0:// 加载失败page --;onLoad();Toast.makeText(mActivity, "网络异常,加载失败!", Toast.LENGTH_SHORT).show();break;case 1:mAdapter = new DotaItemAdapter(mActivity, items);mListView.setAdapter(mAdapter);break;case 2:Log.i("jiangguohu","handler case 2");mAdapter.notifyDataSetChanged();onLoad();break;default:break;}}};}private void getItems() {// TODO Auto-generated method stubthread.start();}@Overridepublic void onRefresh() {// 下拉刷新时会调用的方法// TODO Auto-generated method stubhandler.postDelayed(new Runnable() {@Overridepublic void run() {mListView.setAdapter(mAdapter);onLoad();}}, 2000);}@Overridepublic void onLoadMore() {// 上拉加载更多的方法// TODO Auto-generated method stubhandler.postDelayed(new Runnable() {@Overridepublic void run() {Log.i("jiangguohu","isOnRefresh = "+isOnRefresh);if (checkNetWork(mActivity)) {// 检查网络,没有联网时停止加载if (!isOnRefresh) {isOnRefresh = true;page ++;// 加载下一页数据final Map<String, String> params2 = new HashMap<String, String>();params2.put("client_id", StaticsUtil.CLIENT_ID);params2.put("category", "游戏");params2.put("tag", "DOTA2");params2.put("orderby", "published");params2.put("page", page+"");params2.put("count", pageCount+"");new Thread(new Runnable() {public void run() {boolean b = false;try {b = sendGETRequest(TAG_URL, params2, mActivity);Log.i("jiangguohu", "b2 = " + b);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}if (b) {// 运用handler返回处理结果,刷新界面mHandler.sendEmptyMessage(2);} else {mHandler.sendEmptyMessage(0);}}}).start();}} else {Toast.makeText(mActivity, "请检查网络设置!", Toast.LENGTH_SHORT).show();onLoad();}}}, 2000);}private void onLoad() {// 下拉刷新或者上拉加载结束时候手动调用该方法,结束刷新mListView.stopRefresh();mListView.stopLoadMore();mListView.setRefreshTime("刚刚");isOnRefresh = false;}@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {// ListView的点击事件,在这里我直接跳转到优酷Demo中的播放界面// TODO Auto-generated method stubif (!checkNetWork(mActivity)) {Toast.makeText(mActivity, "请检查网络设置!", Toast.LENGTH_SHORT).show();return;}Intent i = new Intent(mActivity, PlayerActivity.class);String id = (String) items.get(arg2-1).get("id");i.putExtra("vid", id.trim());startActivity(i);}Thread thread = new Thread(new Runnable() {public void run() {boolean b = false;try {b = sendGETRequest(TAG_URL, params, mActivity);Log.i("jiangguohu", "b = " + b);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}if (b) {mHandler.sendEmptyMessage(1);} else {mHandler.sendEmptyMessage(0);}}});private static boolean sendGETRequest(String path,Map<String, String> params, Context context) throws Exception {// GET方式访问网络获取数据StringBuilder sb = new StringBuilder();sb.append(path).append("?");if (params != null && params.size() != 0) {for (Map.Entry<String, String> entry : params.entrySet()) {sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8"));sb.append("&");}sb.deleteCharAt(sb.length() - 1);}if (checkNetWork(context)) {URL url = new URL(sb.toString());HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");Log.i("jiangguohu","sendGETRequest conn.getResponseCode() = "+conn.getResponseCode());if (conn.getResponseCode() == 200) {InputStream is = conn.getInputStream();byte[] data = readStream(is);String json = new String(data);loadDate(json);FileService fileService = new FileService(context);// 文件缓存,保存当前页面从网络获取的json数据fileService.clear();fileService.save(json);return true;}return false;} else {// 没有网络时,加载本地缓存数据items.clear();loadDate(new FileService(context).read());if (items.size() != 0) {return true;} else {return false;}}}public static byte[] readStream(InputStream inputStream) throws Exception {ByteArrayOutputStream bout = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inputStream.read(buffer)) != -1) {bout.write(buffer, 0, len);}bout.close();inputStream.close();return bout.toByteArray();}/** * 将json数据存入list * @param string */public static void loadDate(String string) {JSONObject jsonObject;try {jsonObject = new JSONObject(string);JSONArray jsonArray = (JSONArray) jsonObject.opt("videos");Map<String, Object> map = null;for (int i = 0; i < jsonArray.length(); i++) {JSONObject item = jsonArray.getJSONObject(i);ItemDate itemDate = new ItemDate();// 自己写的ItemDate类,用于封装item信息map = itemDate.getHashMap(item);if (map != null) {items.add(map);}}} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 检查网络连接 * @param mContext * @return */public static boolean checkNetWork(Context mContext) {        ConnectivityManager connectivityManager = (ConnectivityManager) mContext                .getSystemService(Context.CONNECTIVITY_SERVICE);        NetworkInfo info = connectivityManager.getActiveNetworkInfo();        if (info == null || !info.isAvailable()) {            return false;        } else {            return true;        }    }}

下面再让我们来看看ItemDate这个类吧:

package com.jgh.util;import java.util.HashMap;import java.util.Map;import org.json.JSONException;import org.json.JSONObject;import android.util.Log;/** * 查询网页,返回结果进行处理的包装类 *  * @author jiangguohu *  */public class ItemDate {private String id;// 视频的idprivate String title;// 视频的标题private String link;// 视频的链接地址private String duration;// 视频的总shichangprivate String thumbnail;// 视频截图private String published;// 视频发布的时间public ItemDate() {super();}public ItemDate(String id, String title, String link, String duration,String thumbnail, String published) {super();this.id = id;this.title = title;this.link = link;this.duration = duration;this.thumbnail = thumbnail;this.published = published;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getLink() {return link;}public void setLink(String link) {this.link = link;}public String getDuration() {return duration;}public void setDuration(String duration) {this.duration = duration;}public String getThumbnail() {return thumbnail;}public void setThumbnail(String thumbnail) {this.thumbnail = thumbnail;}public String getPublished() {return published;}public void setPublished(String published) {this.published = published;}public Map<String, Object> getHashMap(JSONObject item) {// 将从网络中获取的json信息处理为Map对象,然后存放在List中// TODO Auto-generated method stubMap<String, Object> map = new HashMap<String, Object>();try {if (10*60 > item.getInt("duration")) {// 排除十分钟一下的视频Log.i("jiangguohu","时间太短,排除!");return null;}title = item.getString("title");id = item.getString("id");link = item.getString("link");duration = String.valueOf(item.getInt("duration"));thumbnail = item.getString("thumbnail");published = item.getString("published");} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}map.put("id", id);map.put("title", title);map.put("link", link);map.put("thumbnail", thumbnail);map.put("published", published);map.put("duration", changeTimeFormat(duration + ""));// 更改视频总时长显示的格式return map;}/** * 将从网络中获取的时间进行转化 * @param time * @return */public static String changeTimeFormat(String time) {if (time != null) {int timeInt = Integer.parseInt(time);int second = timeInt % 60;int minute = (timeInt / 60) % 60;int hour = (timeInt / 60) / 60;return "" + (hour < 10 ? ("0" + hour) : hour + "") + ":"+ (minute < 10 ? ("0" + minute) : minute + "") + ":"+ (second < 10 ? ("0" + second) : second);}return time;}public static ItemDate getItemDate(Map<String, Object> map) {// 将一个Map对象处理为一个ItemDate类对象return new ItemDate((String) map.get("id"), (String) map.get("title"),(String) map.get("link"), (String) map.get("duration"),(String) map.get("thumbnail"), (String) map.get("published"));}}

再来看看我们自定义的Adapter吧:

package com.jgh.util;import java.io.IOException;import java.net.URL;import java.util.List;import java.util.Map;import com.jgh.cache.ImageLoader;import com.jgh.watchdota.R;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class DotaItemAdapter extends BaseAdapter {private Activity mActivity;private List<Map<String, Object>> items;ImageLoader imageLoader;public DotaItemAdapter(Activity mActivity, List<Map<String, Object>> items) {// TODO Auto-generated constructor stubthis.mActivity = mActivity;this.items = items;imageLoader = new ImageLoader(mActivity);// 图片缓存处理类}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn items.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn items.get(arg0);}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0;}@Overridepublic View getView(int arg0, View arg1, ViewGroup arg2) {// TODO Auto-generated method stubItemDate itemMap = ItemDate.getItemDate(items.get(arg0));// 将List中获取Map然后转化为ItemDateLayoutInflater inflater = mActivity.getLayoutInflater();View itemView = inflater.inflate(R.layout.list_item, null);TextView title = (TextView) itemView.findViewById(R.id.title);TextView published = (TextView) itemView.findViewById(R.id.published);TextView duration = (TextView) itemView.findViewById(R.id.duration);ImageView imageView = (ImageView) itemView.findViewById(R.id.image);title.setText(itemMap.getTitle());published.setText(itemMap.getPublished());duration.setText(itemMap.getDuration()+"");//Log.i("jiangguohu","itemMap.get(thumbnail) = "+itemMap.get("thumbnail"));//imageView.setImageURI(Uri.parse(itemMap.get("thumbnail")));//imageView.setImageBitmap((Bitmap) itemMap.get("thumbnail"));imageLoader.displayImage(itemMap.getThumbnail(), imageView);// 加载缓存图片,如若没有缓存,从网络获取return itemView;}}

好啦,以上就是现阶段的分享啦。下一章将会讲解缓存部分。等到做的差不多的时候再发布源码。欢迎大家留言讨论,共同进步。

0 0