在前一篇文章《优酷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;}
}

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

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

  1. iOS高仿微信、仪表盘、图片标注图片滤镜、高斯模糊、上拉加载、下拉刷新等源码

    iOS精选源码 Swift-图片画框标注 Swift版的上拉加载, 下拉刷新控件(一句话集成, 超级易用) iOS tabbar上的提示框 Swift图片浏览器,经过一年多维护,已基本稳定 图片滤镜 ...

  2. iOS高仿微信、仪表盘、图片标注图片滤镜、高斯模糊、上拉加载、下拉刷新等源码...

    iOS精选源码 Swift-图片画框标注 Swift版的上拉加载, 下拉刷新控件(一句话集成, 超级易用) iOS tabbar上的提示框 Swift图片浏览器,经过一年多维护,已基本稳定 图片滤镜 ...

  3. vue项目中vue-scroller实现上拉加载和下拉刷新

    vue目前是众所周知的流行框架大家都知道的,vue全家桶的成员是:vue-cli,vuex,vue-router,vue-axios(vue2.0).然后它的第三方插件也有很多,比如:vue-scro ...

  4. 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多

    原文地址: http://blog.csdn.net/leoleohan/article/details/50989549/ 一.概述 我们公司目前开发的所有Android APP都是遵循iOS风格设 ...

  5. ASP.NET仿新浪微博下拉加载更多数据瀑布流效果

    闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值.       ...

  6. Android自定义控件(四)仿网易客户端上拉加载更多

    上一篇仿得网页客户端的抽屉模式,这一篇继续,来写一写加载更多这个功能,通过自定义实现加载更多,先上图: 今天实现的就是如图中最下面的20条载入中...这个功能啦! 先来说一下思路: 1.在listvi ...

  7. Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向...

    很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性.查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷 ...

  8. android 加载更多动画效果,Android实践之带加载效果的下拉刷新上拉加载更多

    前言 之前写的一个LoadingBar,这次把LoadingBar加到下拉刷新的头部.从头写一个下拉刷新,附赠上拉加载更多.下面话不多说了,来一起看看详细的介绍吧. 效果图: 实现过程 首先是自定义属 ...

  9. Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout

    下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...

最新文章

  1. 微软分享史上最大基于Transformer架构的语言生成模型
  2. docker挂载目录原理
  3. linux下C语言套接字编程sockaddr和sockaddr_in的区别
  4. 记录:C#编程中的字符串
  5. 非线性方程组求解Matlab实现 (多元牛顿方法、Broyden方法、Broyden方法2)
  6. CSS hack浏览器兼容一览表
  7. java map套arraylist,在Java中的HashMap和ArrayList的区别?
  8. [转]总结:Apache/Tomcat/JBOSS/Jetty/Nginx区别 .
  9. 上午写了一段代码,下午就被开除了~
  10. {dede:global.cfg_templets_skin/}路径出错
  11. java编程xml_XML Java编程
  12. 4.3 现在可用的客体类有哪些呢
  13. (1)简单工厂模式C++实现
  14. 解决 sql server 2005 2000 导出 script 脚本 附近有语法错误
  15. 宋宝华Linux培训笔记-Linux内存管理
  16. ARP表 MAC表 路由表
  17. 使用Coverity进行代码检测,构建C#报错,The Web-app security checkers are fully suppored only on Windwds.
  18. EAN13商品条码数据如何居中显示
  19. 三国论(16-20章)
  20. python3实现base64编码

热门文章

  1. Linux常用开发命令
  2. IGBT结温估算(算法+模型)
  3. 2020研究生考试总结(哈工程软件)
  4. 阿里巴巴架构再迎大调整:左手接招腾讯,右手瞄准百度
  5. C# RichTextBox 滚动条 滚动到最后一行
  6. 安能“狂奔”、德邦“卖身”,万亿零担进入下半场
  7. N-Case 律师事务所管理系统功能介绍
  8. 数理基础之轨道力学的三体问题,了解如何推导轨道力学中研究最多的问题(用于设计 James Webb 太空望远镜轨道)
  9. VS019下的VSColorOutput插件,可以改变vs输出窗口的颜色
  10. 早该被淘汰的中国移动游戏基地