实现app上对csdn的文章列表上拉刷新下拉加载以及加入缓存文章列表的功能 (制作csdn app 四)

今天继续对我们的csdn客户端未完成的功能进行实现,本篇博客接着客户端上显示csdn上的各类别下的的文章列表 (制作csdn app 三)继续完善我们的app。

今天的目标是:

1、对文章列表的下拉刷新,上拉加载。

2、没有网络的情况下,依然可以看到缓存在手机上的文章列表,以及上拉加载等。

大概效果图:


1、首先是对MainFragment.Java编写,真对XListView实现下拉刷新和上拉加载。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public void onRefresh()  
  3. {  
  4.     new LoadDatasTask().execute(LOAD_REFREASH);  
  5. }  
  6.   
  7. @Override  
  8. public void onLoadMore()  
  9. {  
  10.     new LoadDatasTask().execute(LOAD_MORE);  
  11. }  

我们对下拉刷新和上拉加载调用了一个异步任务,传入了操作的标识符,下面具体看个类:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 记载数据的异步任务 
  3.      *  
  4.      * @author zhy 
  5.      *  
  6.      */  
  7.     class LoadDatasTask extends AsyncTask<Integer, Void, Integer>  
  8.     {  
  9.   
  10.         @Override  
  11.         protected Integer doInBackground(Integer... params)  
  12.         {  
  13.             switch (params[0])  
  14.             {  
  15.             case LOAD_MORE:  
  16.                 loadMoreData();  
  17.                 break;  
  18.             case LOAD_REFREASH:  
  19.                 return refreashData();  
  20.             }  
  21.             return -1;  
  22.         }  
  23.   
  24.         @Override  
  25.         protected void onPostExecute(Integer result)  
  26.         {  
  27.             switch (result)  
  28.             {  
  29.             case TIP_ERROR_NO_NETWORK:  
  30.                 ToastUtil.toast(getActivity(), "没有网络连接!");  
  31.                 mAdapter.setDatas(mDatas);  
  32.                 mAdapter.notifyDataSetChanged();  
  33.                 break;  
  34.             case TIP_ERROR_SERVER:  
  35.                 ToastUtil.toast(getActivity(), "服务器错误!");  
  36.                 break;  
  37.   
  38.             default:  
  39.                 break;  
  40.   
  41.             }  
  42.               
  43.             mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));  
  44.             mXListView.stopRefresh();  
  45.             mXListView.stopLoadMore();  
  46.         }  
  47.   
  48.     }  

可以看到,这个类中又使用了 loadMoreData();和 refreashData();

先看loadMoreData:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 会根据当前网络情况,判断是从数据库加载还是从网络继续获取 
  3.      */  
  4.     public void loadMoreData()  
  5.     {  
  6.         // 当前数据是从网络获取的  
  7.         if (isLoadingDataFromNetWork)  
  8.         {  
  9.             currentPage += 1;  
  10.             try  
  11.             {  
  12.                 List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);  
  13.                 mNewsItemDao.add(newsItems);  
  14.                 mAdapter.addAll(newsItems);  
  15.             } catch (CommonException e)  
  16.             {  
  17.                 e.printStackTrace();  
  18.             }  
  19.         } else  
  20.         // 从数据库加载的  
  21.         {  
  22.             currentPage += 1;  
  23.             List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);  
  24.             mAdapter.addAll(newsItems);  
  25.         }  
  26.   
  27.     }  

可以看到,如果当前app上的数据是从网络更新的即最新数据,我们会继续去网络加载下一页的数据,并且使用mNewsItemDao.add方法,插入我们的app的数据库中,供没有网络时使用。如果当前数据是缓存数据,我们则继续去数据库加载。

接下来看refreashData方法:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 下拉刷新数据 
  3.  */  
  4. public Integer refreashData()  
  5. {  
  6.       
  7.     if (NetUtil.checkNet(getActivity()))  
  8.     {  
  9.         isConnNet = true;  
  10.         // 获取最新数据  
  11.         try  
  12.         {  
  13.             List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);  
  14.             mAdapter.setDatas(newsItems);  
  15.               
  16.             isLoadingDataFromNetWork = true;  
  17.             // 设置刷新时间  
  18.             AppUtil.setRefreashTime(getActivity(), newsType);  
  19.             // 清除数据库数据  
  20.             mNewsItemDao.deleteAll(newsType);  
  21.             // 存入数据库  
  22.             mNewsItemDao.add(newsItems);  
  23.   
  24.         } catch (CommonException e)  
  25.         {  
  26.             e.printStackTrace();  
  27.             isLoadingDataFromNetWork = false;  
  28.             return TIP_ERROR_SERVER;  
  29.         }  
  30.     } else  
  31.     {  
  32.         isConnNet = false;  
  33.         isLoadingDataFromNetWork = false;  
  34.         // TODO从数据库中加载  
  35.         List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);  
  36.         mDatas = newsItems;  
  37.         //mAdapter.setDatas(newsItems);  
  38.         return TIP_ERROR_NO_NETWORK;  
  39.     }  
  40.   
  41.     return -1;  
  42.   
  43. }  

首先检查网络连接情况,没有的话,则去数据库加载,并设置isLoadingDataFromNetWork=false,如果有的话从网络加载,并清空该类型新闻的数据,更新数据库缓存数据。

下面是完整MainFragment.java:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.csdndemo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import me.maxwin.view.IXListViewLoadMore;  
  7. import me.maxwin.view.IXListViewRefreshListener;  
  8. import me.maxwin.view.XListView;  
  9. import android.annotation.SuppressLint;  
  10. import android.os.AsyncTask;  
  11. import android.os.Bundle;  
  12. import android.support.v4.app.Fragment;  
  13. import android.view.LayoutInflater;  
  14. import android.view.View;  
  15. import android.view.ViewGroup;  
  16.   
  17. import com.zhy.bean.CommonException;  
  18. import com.zhy.bean.NewsItem;  
  19. import com.zhy.biz.NewsItemBiz;  
  20. import com.zhy.csdn.Constaint;  
  21. import com.zhy.csdndemo.adapter.NewsItemAdapter;  
  22. import com.zhy.csdndemo.dao.NewsItemDao;  
  23. import com.zhy.csdndemo.util.AppUtil;  
  24. import com.zhy.csdndemo.util.Logger;  
  25. import com.zhy.csdndemo.util.NetUtil;  
  26. import com.zhy.csdndemo.util.ToastUtil;  
  27.   
  28. @SuppressLint("ValidFragment")  
  29. public class MainFragment extends Fragment implements IXListViewRefreshListener, IXListViewLoadMore  
  30. {  
  31.     private static final int LOAD_MORE = 0x110;  
  32.     private static final int LOAD_REFREASH = 0x111;  
  33.   
  34.     private static final int TIP_ERROR_NO_NETWORK = 0X112;  
  35.     private static final int TIP_ERROR_SERVER = 0X113;  
  36.   
  37.     /** 
  38.      * 是否是第一次进入 
  39.      */  
  40.     private boolean isFirstIn = true;  
  41.   
  42.     /** 
  43.      * 是否连接网络 
  44.      */  
  45.     private boolean isConnNet = false;  
  46.   
  47.     /** 
  48.      * 当前数据是否是从网络中获取的 
  49.      */  
  50.     private boolean isLoadingDataFromNetWork;  
  51.   
  52.     /** 
  53.      * 默认的newType 
  54.      */  
  55.     private int newsType = Constaint.NEWS_TYPE_YEJIE;  
  56.     /** 
  57.      * 当前页面 
  58.      */  
  59.     private int currentPage = 1;  
  60.     /** 
  61.      * 处理新闻的业务类 
  62.      */  
  63.     private NewsItemBiz mNewsItemBiz;  
  64.   
  65.     /** 
  66.      * 与数据库交互 
  67.      */  
  68.     private NewsItemDao mNewsItemDao;  
  69.   
  70.     /** 
  71.      * 扩展的ListView 
  72.      */  
  73.     private XListView mXListView;  
  74.     /** 
  75.      * 数据适配器 
  76.      */  
  77.     private NewsItemAdapter mAdapter;  
  78.   
  79.     /** 
  80.      * 数据 
  81.      */  
  82.     private List<NewsItem> mDatas = new ArrayList<NewsItem>();  
  83.   
  84.     /** 
  85.      * 获得newType 
  86.      *  
  87.      * @param newsType 
  88.      */  
  89.     public MainFragment(int newsType)  
  90.     {  
  91.         this.newsType = newsType;  
  92.         Logger.e(newsType + "newsType");  
  93.         mNewsItemBiz = new NewsItemBiz();  
  94.     }  
  95.   
  96.     @Override  
  97.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
  98.     {  
  99.         return inflater.inflate(R.layout.tab_item_fragment_main, null);  
  100.     }  
  101.   
  102.     @Override  
  103.     public void onActivityCreated(Bundle savedInstanceState)  
  104.     {  
  105.         super.onActivityCreated(savedInstanceState);  
  106.         mNewsItemDao = new NewsItemDao(getActivity());  
  107.         mAdapter = new NewsItemAdapter(getActivity(), mDatas);  
  108.         /** 
  109.          * 初始化 
  110.          */  
  111.         mXListView = (XListView) getView().findViewById(R.id.id_xlistView);  
  112.         mXListView.setAdapter(mAdapter);  
  113.         mXListView.setPullRefreshEnable(this);  
  114.         mXListView.setPullLoadEnable(this);  
  115.         mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));  
  116.         // mXListView.NotRefreshAtBegin();  
  117.   
  118.         if (isFirstIn)  
  119.         {  
  120.             /** 
  121.              * 进来时直接刷新 
  122.              */  
  123.             mXListView.startRefresh();  
  124.             isFirstIn = false;  
  125.         }else  
  126.         {  
  127.             mXListView.NotRefreshAtBegin();  
  128.         }  
  129.     }  
  130.   
  131.     @Override  
  132.     public void onRefresh()  
  133.     {  
  134.         new LoadDatasTask().execute(LOAD_REFREASH);  
  135.     }  
  136.   
  137.     @Override  
  138.     public void onLoadMore()  
  139.     {  
  140.         new LoadDatasTask().execute(LOAD_MORE);  
  141.     }  
  142.   
  143.     /** 
  144.      * 记载数据的异步任务 
  145.      *  
  146.      * @author zhy 
  147.      *  
  148.      */  
  149.     class LoadDatasTask extends AsyncTask<Integer, Void, Integer>  
  150.     {  
  151.   
  152.         @Override  
  153.         protected Integer doInBackground(Integer... params)  
  154.         {  
  155.             switch (params[0])  
  156.             {  
  157.             case LOAD_MORE:  
  158.                 loadMoreData();  
  159.                 break;  
  160.             case LOAD_REFREASH:  
  161.                 return refreashData();  
  162.             }  
  163.             return -1;  
  164.         }  
  165.   
  166.         @Override  
  167.         protected void onPostExecute(Integer result)  
  168.         {  
  169.             switch (result)  
  170.             {  
  171.             case TIP_ERROR_NO_NETWORK:  
  172.                 ToastUtil.toast(getActivity(), "没有网络连接!");  
  173.                 mAdapter.setDatas(mDatas);  
  174.                 mAdapter.notifyDataSetChanged();  
  175.                 break;  
  176.             case TIP_ERROR_SERVER:  
  177.                 ToastUtil.toast(getActivity(), "服务器错误!");  
  178.                 break;  
  179.   
  180.             default:  
  181.                 break;  
  182.   
  183.             }  
  184.               
  185.             mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));  
  186.             mXListView.stopRefresh();  
  187.             mXListView.stopLoadMore();  
  188.         }  
  189.   
  190.     }  
  191.   
  192.     /** 
  193.      * 下拉刷新数据 
  194.      */  
  195.     public Integer refreashData()  
  196.     {  
  197.           
  198.         if (NetUtil.checkNet(getActivity()))  
  199.         {  
  200.             isConnNet = true;  
  201.             // 获取最新数据  
  202.             try  
  203.             {  
  204.                 List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);  
  205.                 mAdapter.setDatas(newsItems);  
  206.                   
  207.                 isLoadingDataFromNetWork = true;  
  208.                 // 设置刷新时间  
  209.                 AppUtil.setRefreashTime(getActivity(), newsType);  
  210.                 // 清除数据库数据  
  211.                 mNewsItemDao.deleteAll(newsType);  
  212.                 // 存入数据库  
  213.                 mNewsItemDao.add(newsItems);  
  214.   
  215.             } catch (CommonException e)  
  216.             {  
  217.                 e.printStackTrace();  
  218.                 isLoadingDataFromNetWork = false;  
  219.                 return TIP_ERROR_SERVER;  
  220.             }  
  221.         } else  
  222.         {  
  223.             isConnNet = false;  
  224.             isLoadingDataFromNetWork = false;  
  225.             // TODO从数据库中加载  
  226.             List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);  
  227.             mDatas = newsItems;  
  228.             //mAdapter.setDatas(newsItems);  
  229.             return TIP_ERROR_NO_NETWORK;  
  230.         }  
  231.   
  232.         return -1;  
  233.   
  234.     }  
  235.   
  236.     /** 
  237.      * 会根据当前网络情况,判断是从数据库加载还是从网络继续获取 
  238.      */  
  239.     public void loadMoreData()  
  240.     {  
  241.         // 当前数据是从网络获取的  
  242.         if (isLoadingDataFromNetWork)  
  243.         {  
  244.             currentPage += 1;  
  245.             try  
  246.             {  
  247.                 List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);  
  248.                 mNewsItemDao.add(newsItems);  
  249.                 mAdapter.addAll(newsItems);  
  250.             } catch (CommonException e)  
  251.             {  
  252.                 e.printStackTrace();  
  253.             }  
  254.         } else  
  255.         // 从数据库加载的  
  256.         {  
  257.             currentPage += 1;  
  258.             List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);  
  259.             mAdapter.addAll(newsItems);  
  260.         }  
  261.   
  262.     }  
  263.   
  264. }  

接下来看看数据库的实现:

首先肯定是个Helper,没什么好说的。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.csdndemo.dao;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6.   
  7. public class DBHelper extends SQLiteOpenHelper  
  8. {  
  9.     private static final String DB_NAME = "csdn_app_demo";  
  10.   
  11.     public DBHelper(Context context)  
  12.     {  
  13.         super(context, DB_NAME, null1);  
  14.     }  
  15.   
  16.     @Override  
  17.     public void onCreate(SQLiteDatabase db)  
  18.     {  
  19.         /** 
  20.          * id,title,link,date,imgLink,content,newstype 
  21.          */  
  22.         String sql = "create table tb_newsItem( _id integer primary key autoincrement , "  
  23.                 + " title text , link text , date text , imgLink text , content text , newstype integer  );";  
  24.         db.execSQL(sql);  
  25.     }  
  26.   
  27.     @Override  
  28.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  
  29.     {  
  30.         // TODO Auto-generated method stub  
  31.   
  32.     }  
  33.   
  34. }  

然后是我们的Dao:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.csdndemo.dao;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.content.Context;  
  7. import android.database.Cursor;  
  8. import android.database.sqlite.SQLiteDatabase;  
  9.   
  10. import com.zhy.bean.NewsItem;  
  11. import com.zhy.csdndemo.util.Logger;  
  12.   
  13. public class NewsItemDao  
  14. {  
  15.   
  16.     private DBHelper dbHelper;  
  17.   
  18.     public NewsItemDao(Context context)  
  19.     {  
  20.         dbHelper = new DBHelper(context);  
  21.     }  
  22.   
  23.     public void add(NewsItem newsItem)  
  24.     {  
  25.         Logger.e("add news newstype " + newsItem.getNewsType());  
  26.         String sql = "insert into tb_newsItem (title,link,date,imgLink,content,newstype) values(?,?,?,?,?,?) ;";  
  27.         SQLiteDatabase db = dbHelper.getWritableDatabase();  
  28.         db.execSQL(sql,  
  29.                 new Object[] { newsItem.getTitle(), newsItem.getLink(), newsItem.getDate(), newsItem.getImgLink(),  
  30.                         newsItem.getContent(), newsItem.getNewsType() });  
  31.         db.close();  
  32.     }  
  33.   
  34.     public void deleteAll(int newsType)  
  35.     {  
  36.         String sql = "delete from tb_newsItem where newstype = ?";  
  37.         SQLiteDatabase db = dbHelper.getWritableDatabase();  
  38.         db.execSQL(sql, new Object[] { newsType });  
  39.         db.close();  
  40.     }  
  41.   
  42.     public void add(List<NewsItem> newsItems)  
  43.     {  
  44.         for (NewsItem newsItem : newsItems)  
  45.         {  
  46.             add(newsItem);  
  47.         }  
  48.     }  
  49.   
  50.     /** 
  51.      * 根据newsType和currentPage从数据库中取数据 
  52.      *  
  53.      * @param newsType 
  54.      * @param currentPage 
  55.      * @return 
  56.      */  
  57.     public List<NewsItem> list(int newsType, int currentPage)  
  58.     {  
  59.   
  60.         Logger.e(newsType + "  newsType");  
  61.         Logger.e(currentPage + "  currentPage");  
  62.         // 0 -9 , 10 - 19 ,  
  63.         List<NewsItem> newsItems = new ArrayList<NewsItem>();  
  64.         try  
  65.         {  
  66.             int offset = 10 * (currentPage - 1);  
  67.             String sql = "select title,link,date,imgLink,content,newstype from tb_newsItem where newstype = ? limit ?,? ";  
  68.             SQLiteDatabase db = dbHelper.getReadableDatabase();  
  69.             Cursor c = db.rawQuery(sql, new String[] { newsType + "", offset + """" + (offset + 10) });  
  70.   
  71.             NewsItem newsItem = null;  
  72.   
  73.             while (c.moveToNext())  
  74.             {  
  75.                 newsItem = new NewsItem();  
  76.   
  77.                 String title = c.getString(0);  
  78.                 String link = c.getString(1);  
  79.                 String date = c.getString(2);  
  80.                 String imgLink = c.getString(3);  
  81.                 String content = c.getString(4);  
  82.                 Integer newstype = c.getInt(5);  
  83.   
  84.                 newsItem.setTitle(title);  
  85.                 newsItem.setLink(link);  
  86.                 newsItem.setImgLink(imgLink);  
  87.                 newsItem.setDate(date);  
  88.                 newsItem.setNewsType(newstype);  
  89.                 newsItem.setContent(content);  
  90.   
  91.                 newsItems.add(newsItem);  
  92.   
  93.             }  
  94.             c.close();  
  95.             db.close();  
  96.             Logger.e(newsItems.size() + "  newsItems.size()");  
  97.         } catch (Exception e)  
  98.         {  
  99.             // TODO Auto-generated catch block  
  100.             e.printStackTrace();  
  101.         }  
  102.         return newsItems;  
  103.   
  104.     }  
  105.   
  106. }  

提供了增加单条记录,多条记录,根据类型删除记录等方法。

最后把网络的辅助类也贴出来:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.csdndemo.util;  
  2.   
  3. import android.content.Context;  
  4. import android.net.ConnectivityManager;  
  5. import android.net.NetworkInfo;  
  6.   
  7. /** 
  8.  * 判断当前手机联网的渠道 
  9.  *  
  10.  * @author Administrator 
  11.  *  
  12.  */  
  13. public class NetUtil  
  14. {  
  15.     /** 
  16.      * 检查当前手机网络 
  17.      *  
  18.      * @param context 
  19.      * @return 
  20.      */  
  21.     public static boolean checkNet(Context context)  
  22.     {  
  23.         // 判断连接方式  
  24.         boolean wifiConnected = isWIFIConnected(context);  
  25.         boolean mobileConnected = isMOBILEConnected(context);  
  26.         if (wifiConnected == false && mobileConnected == false)  
  27.         {  
  28.             // 如果都没有连接返回false,提示用户当前没有网络  
  29.             return false;  
  30.         }  
  31.         return true;  
  32.     }  
  33.   
  34.     // 判断手机使用是wifi还是mobile  
  35.     /** 
  36.      * 判断手机是否采用wifi连接 
  37.      */  
  38.     public static boolean isWIFIConnected(Context context)  
  39.     {  
  40.         // Context.CONNECTIVITY_SERVICE).  
  41.   
  42.         ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
  43.         NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);  
  44.         if (networkInfo != null && networkInfo.isConnected())  
  45.         {  
  46.             return true;  
  47.         }  
  48.         return false;  
  49.     }  
  50.   
  51.     public static boolean isMOBILEConnected(Context context)  
  52.     {  
  53.         ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
  54.         NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);  
  55.         if (networkInfo != null && networkInfo.isConnected())  
  56.         {  
  57.             return true;  
  58.         }  
  59.         return false;  
  60.     }  
  61. }  

今天到此结束,现在基本就剩下,文章的详细信息的展示,和对页面上的图片进行保存了。


如果这篇文章对你有用,可以顶一个~


源码点击此处下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值