实现app上对csdn的文章列表上拉刷新下拉加载以及加入缓存文章列表的功能 (制作csdn app 四)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23698511
今天继续对我们的csdn客户端未完成的功能进行实现,本篇博客接着客户端上显示csdn上的各类别下的的文章列表
(制作csdn app 三)继续完善我们的app。
今天的目标是:
1、对文章列表的下拉刷新,上拉加载。
2、没有网络的情况下,依然可以看到缓存在手机上的文章列表,以及上拉加载等。
大概效果图:
1、首先是对MainFragment.java编写,真对XListView实现下拉刷新和上拉加载。
@Override
public void onRefresh()
{
new LoadDatasTask().execute(LOAD_REFREASH);
} @Override
public void onLoadMore()
{
new LoadDatasTask().execute(LOAD_MORE);
}
我们对下拉刷新和上拉加载调用了一个异步任务,传入了操作的标识符,下面具体看个类:
/**
* 记载数据的异步任务
*
* @author zhy
*
*/
class LoadDatasTask extends AsyncTask<Integer, Void, Integer>
{ @Override
protected Integer doInBackground(Integer... params)
{
switch (params[0])
{
case LOAD_MORE:
loadMoreData();
break;
case LOAD_REFREASH:
return refreashData();
}
return -1;
} @Override
protected void onPostExecute(Integer result)
{
switch (result)
{
case TIP_ERROR_NO_NETWORK:
ToastUtil.toast(getActivity(), "没有网络连接!");
mAdapter.setDatas(mDatas);
mAdapter.notifyDataSetChanged();
break;
case TIP_ERROR_SERVER:
ToastUtil.toast(getActivity(), "服务器错误!");
break; default:
break; } mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));
mXListView.stopRefresh();
mXListView.stopLoadMore();
} }
可以看到,这个类中又使用了 loadMoreData();和 refreashData();
先看loadMoreData:
/**
* 会根据当前网络情况,判断是从数据库加载还是从网络继续获取
*/
public void loadMoreData()
{
// 当前数据是从网络获取的
if (isLoadingDataFromNetWork)
{
currentPage += 1;
try
{
List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);
mNewsItemDao.add(newsItems);
mAdapter.addAll(newsItems);
} catch (CommonException e)
{
e.printStackTrace();
}
} else
// 从数据库加载的
{
currentPage += 1;
List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);
mAdapter.addAll(newsItems);
} }
可以看到,如果当前app上的数据是从网络更新的即最新数据,我们会继续去网络加载下一页的数据,并且使用mNewsItemDao.add方法,插入我们的app的数据库中,供没有网络时使用。如果当前数据是缓存数据,我们则继续去数据库加载。
接下来看refreashData方法:
/**
* 下拉刷新数据
*/
public Integer refreashData()
{ if (NetUtil.checkNet(getActivity()))
{
isConnNet = true;
// 获取最新数据
try
{
List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);
mAdapter.setDatas(newsItems); isLoadingDataFromNetWork = true;
// 设置刷新时间
AppUtil.setRefreashTime(getActivity(), newsType);
// 清除数据库数据
mNewsItemDao.deleteAll(newsType);
// 存入数据库
mNewsItemDao.add(newsItems); } catch (CommonException e)
{
e.printStackTrace();
isLoadingDataFromNetWork = false;
return TIP_ERROR_SERVER;
}
} else
{
isConnNet = false;
isLoadingDataFromNetWork = false;
// TODO从数据库中加载
List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);
mDatas = newsItems;
//mAdapter.setDatas(newsItems);
return TIP_ERROR_NO_NETWORK;
} return -1; }
首先检查网络连接情况,没有的话,则去数据库加载,并设置isLoadingDataFromNetWork=false,如果有的话从网络加载,并清空该类型新闻的数据,更新数据库缓存数据。
下面是完整MainFragment.java:
package com.zhy.csdndemo; import java.util.ArrayList;
import java.util.List; import me.maxwin.view.IXListViewLoadMore;
import me.maxwin.view.IXListViewRefreshListener;
import me.maxwin.view.XListView;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import com.zhy.bean.CommonException;
import com.zhy.bean.NewsItem;
import com.zhy.biz.NewsItemBiz;
import com.zhy.csdn.Constaint;
import com.zhy.csdndemo.adapter.NewsItemAdapter;
import com.zhy.csdndemo.dao.NewsItemDao;
import com.zhy.csdndemo.util.AppUtil;
import com.zhy.csdndemo.util.Logger;
import com.zhy.csdndemo.util.NetUtil;
import com.zhy.csdndemo.util.ToastUtil; @SuppressLint("ValidFragment")
public class MainFragment extends Fragment implements IXListViewRefreshListener, IXListViewLoadMore
{
private static final int LOAD_MORE = 0x110;
private static final int LOAD_REFREASH = 0x111; private static final int TIP_ERROR_NO_NETWORK = 0X112;
private static final int TIP_ERROR_SERVER = 0X113; /**
* 是否是第一次进入
*/
private boolean isFirstIn = true; /**
* 是否连接网络
*/
private boolean isConnNet = false; /**
* 当前数据是否是从网络中获取的
*/
private boolean isLoadingDataFromNetWork; /**
* 默认的newType
*/
private int newsType = Constaint.NEWS_TYPE_YEJIE;
/**
* 当前页面
*/
private int currentPage = 1;
/**
* 处理新闻的业务类
*/
private NewsItemBiz mNewsItemBiz; /**
* 与数据库交互
*/
private NewsItemDao mNewsItemDao; /**
* 扩展的ListView
*/
private XListView mXListView;
/**
* 数据适配器
*/
private NewsItemAdapter mAdapter; /**
* 数据
*/
private List<NewsItem> mDatas = new ArrayList<NewsItem>(); /**
* 获得newType
*
* @param newsType
*/
public MainFragment(int newsType)
{
this.newsType = newsType;
Logger.e(newsType + "newsType");
mNewsItemBiz = new NewsItemBiz();
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.tab_item_fragment_main, null);
} @Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
mNewsItemDao = new NewsItemDao(getActivity());
mAdapter = new NewsItemAdapter(getActivity(), mDatas);
/**
* 初始化
*/
mXListView = (XListView) getView().findViewById(R.id.id_xlistView);
mXListView.setAdapter(mAdapter);
mXListView.setPullRefreshEnable(this);
mXListView.setPullLoadEnable(this);
mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));
// mXListView.NotRefreshAtBegin(); if (isFirstIn)
{
/**
* 进来时直接刷新
*/
mXListView.startRefresh();
isFirstIn = false;
}else
{
mXListView.NotRefreshAtBegin();
}
} @Override
public void onRefresh()
{
new LoadDatasTask().execute(LOAD_REFREASH);
} @Override
public void onLoadMore()
{
new LoadDatasTask().execute(LOAD_MORE);
} /**
* 记载数据的异步任务
*
* @author zhy
*
*/
class LoadDatasTask extends AsyncTask<Integer, Void, Integer>
{ @Override
protected Integer doInBackground(Integer... params)
{
switch (params[0])
{
case LOAD_MORE:
loadMoreData();
break;
case LOAD_REFREASH:
return refreashData();
}
return -1;
} @Override
protected void onPostExecute(Integer result)
{
switch (result)
{
case TIP_ERROR_NO_NETWORK:
ToastUtil.toast(getActivity(), "没有网络连接!");
mAdapter.setDatas(mDatas);
mAdapter.notifyDataSetChanged();
break;
case TIP_ERROR_SERVER:
ToastUtil.toast(getActivity(), "服务器错误!");
break; default:
break; } mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType));
mXListView.stopRefresh();
mXListView.stopLoadMore();
} } /**
* 下拉刷新数据
*/
public Integer refreashData()
{ if (NetUtil.checkNet(getActivity()))
{
isConnNet = true;
// 获取最新数据
try
{
List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);
mAdapter.setDatas(newsItems); isLoadingDataFromNetWork = true;
// 设置刷新时间
AppUtil.setRefreashTime(getActivity(), newsType);
// 清除数据库数据
mNewsItemDao.deleteAll(newsType);
// 存入数据库
mNewsItemDao.add(newsItems); } catch (CommonException e)
{
e.printStackTrace();
isLoadingDataFromNetWork = false;
return TIP_ERROR_SERVER;
}
} else
{
isConnNet = false;
isLoadingDataFromNetWork = false;
// TODO从数据库中加载
List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);
mDatas = newsItems;
//mAdapter.setDatas(newsItems);
return TIP_ERROR_NO_NETWORK;
} return -1; } /**
* 会根据当前网络情况,判断是从数据库加载还是从网络继续获取
*/
public void loadMoreData()
{
// 当前数据是从网络获取的
if (isLoadingDataFromNetWork)
{
currentPage += 1;
try
{
List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage);
mNewsItemDao.add(newsItems);
mAdapter.addAll(newsItems);
} catch (CommonException e)
{
e.printStackTrace();
}
} else
// 从数据库加载的
{
currentPage += 1;
List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);
mAdapter.addAll(newsItems);
} } }
接下来看看数据库的实现:
首先肯定是个Helper,没什么好说的。
package com.zhy.csdndemo.dao; import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper
{
private static final String DB_NAME = "csdn_app_demo"; public DBHelper(Context context)
{
super(context, DB_NAME, null, 1);
} @Override
public void onCreate(SQLiteDatabase db)
{
/**
* id,title,link,date,imgLink,content,newstype
*/
String sql = "create table tb_newsItem( _id integer primary key autoincrement , "
+ " title text , link text , date text , imgLink text , content text , newstype integer );";
db.execSQL(sql);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub } }
然后是我们的Dao:
package com.zhy.csdndemo.dao; import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import com.zhy.bean.NewsItem;
import com.zhy.csdndemo.util.Logger; public class NewsItemDao
{ private DBHelper dbHelper; public NewsItemDao(Context context)
{
dbHelper = new DBHelper(context);
} public void add(NewsItem newsItem)
{
Logger.e("add news newstype " + newsItem.getNewsType());
String sql = "insert into tb_newsItem (title,link,date,imgLink,content,newstype) values(?,?,?,?,?,?) ;";
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL(sql,
new Object[] { newsItem.getTitle(), newsItem.getLink(), newsItem.getDate(), newsItem.getImgLink(),
newsItem.getContent(), newsItem.getNewsType() });
db.close();
} public void deleteAll(int newsType)
{
String sql = "delete from tb_newsItem where newstype = ?";
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL(sql, new Object[] { newsType });
db.close();
} public void add(List<NewsItem> newsItems)
{
for (NewsItem newsItem : newsItems)
{
add(newsItem);
}
} /**
* 根据newsType和currentPage从数据库中取数据
*
* @param newsType
* @param currentPage
* @return
*/
public List<NewsItem> list(int newsType, int currentPage)
{ Logger.e(newsType + " newsType");
Logger.e(currentPage + " currentPage");
// 0 -9 , 10 - 19 ,
List<NewsItem> newsItems = new ArrayList<NewsItem>();
try
{
int offset = 10 * (currentPage - 1);
String sql = "select title,link,date,imgLink,content,newstype from tb_newsItem where newstype = ? limit ?,? ";
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.rawQuery(sql, new String[] { newsType + "", offset + "", "" + (offset + 10) }); NewsItem newsItem = null; while (c.moveToNext())
{
newsItem = new NewsItem(); String title = c.getString(0);
String link = c.getString(1);
String date = c.getString(2);
String imgLink = c.getString(3);
String content = c.getString(4);
Integer newstype = c.getInt(5); newsItem.setTitle(title);
newsItem.setLink(link);
newsItem.setImgLink(imgLink);
newsItem.setDate(date);
newsItem.setNewsType(newstype);
newsItem.setContent(content); newsItems.add(newsItem); }
c.close();
db.close();
Logger.e(newsItems.size() + " newsItems.size()");
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return newsItems; } }
提供了增加单条记录,多条记录,根据类型删除记录等方法。
最后把网络的辅助类也贴出来:
package com.zhy.csdndemo.util; import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo; /**
* 判断当前手机联网的渠道
*
* @author Administrator
*
*/
public class NetUtil
{
/**
* 检查当前手机网络
*
* @param context
* @return
*/
public static boolean checkNet(Context context)
{
// 判断连接方式
boolean wifiConnected = isWIFIConnected(context);
boolean mobileConnected = isMOBILEConnected(context);
if (wifiConnected == false && mobileConnected == false)
{
// 如果都没有连接返回false,提示用户当前没有网络
return false;
}
return true;
} // 判断手机使用是wifi还是mobile
/**
* 判断手机是否采用wifi连接
*/
public static boolean isWIFIConnected(Context context)
{
// Context.CONNECTIVITY_SERVICE). ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo != null && networkInfo.isConnected())
{
return true;
}
return false;
} public static boolean isMOBILEConnected(Context context)
{
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (networkInfo != null && networkInfo.isConnected())
{
return true;
}
return false;
}
}
今天到此结束,现在基本就剩下,文章的详细信息的展示,和对页面上的图片进行保存了。
如果这篇文章对你有用,可以顶一个~
源码点击此处下载
实现app上对csdn的文章列表上拉刷新下拉加载以及加入缓存文章列表的功能 (制作csdn app 四)的更多相关文章
- jQuery模拟原生态App上拉刷新下拉加载
jQuery模拟原生态App上拉刷新下拉加载效果代码,鼠标上拉时会显示loading字样,并且会模拟加载一条静态数据,支持触屏设备使用. <!doctype html> <html ...
- Flutter学习笔记(25)--ListView实现上拉刷新下拉加载
如需转载,请注明出处:Flutter学习笔记(25)--ListView实现上拉刷新下拉加载 前面我们有写过ListView的使用:Flutter学习笔记(12)--列表组件,当列表的数据非常多时,需 ...
- 微信小程序 上拉刷新/下拉加载
小程序项目中上拉刷新下拉加载是比较常见的需求,官方文档也提供了相当友好的API,但是因为API隐藏的比较深,文档描述也比较模糊所以也折腾了一番(官方文档),在此记录一下使用方式 onPullDownR ...
- ListView上拉刷新和分页加载完整的Dome
很多人工作的过程中都会碰到ListView下拉刷新和分页加载,然后大多数公司都已经把框架写好了,大家直接用就可以了,有些人一直对这个事情处于迷茫状态,为了让大家对上拉刷新和分页加载有一个比较全面的认识 ...
- Android之 RecyclerView,CardView 详解和相对应的上拉刷新下拉加载
随着 Google 推出了全新的设计语言 Material Design,还迎来了新的 Android 支持库 v7,其中就包含了 Material Design 设计语言中关于 Card 卡片概念的 ...
- Volley图片加载并加入缓存处理(转自http://blog.csdn.net/viewhandkownhealth/article/details/50957024)
直接上代码 两种方式 ImageView 和NetworkImageView 如有问题或者好的建议.意见 欢迎大家加入技术群(群号: 387648673 ) 先自定义全局Application 获取 ...
- XRecyclerView上拉刷新下拉加载
效果图: 首先要添加依赖: //xrecyclerviewimplementation 'com.jcodecraeer:xrecyclerview:1.3.2'//Gsonimplementatio ...
- MUI - 上拉刷新/下拉加载
新闻信息列表必备的功能,支持Table,Ul等列表. 以下是DIV版本,在安卓端或者ios端必须使用双webview模式,传送门:http://dev.dcloud.net.cn/mui/pulldo ...
- 第三方 XListview 上拉加载、下拉刷新、分页加载和Gson解析
注意:此Demo用的是第三方的Xlistview.jar,需要复制me文件夹到项目中,两个XML布局文件和一张图片 把下面的复制到String中 <string name="xlist ...
随机推荐
- [Cocos2d-x]CCSpriteBatchNode的使用
文档: http://cocos2d.cocoachina.com/document/index/class?url=dd/d95/classcocos2d_1_1_c_c_sprite_batch_ ...
- Datatables 在asp.net mvc
Datatables 在asp.net mvc中的使用 前言 最近使用ABP(ASP.NET Boilerplate)做新项目,以前都是自己扩展一个HtmlHelper来完成同步/异步分页,但是有个地 ...
- hdu1281+hdu2819(最大匹配数)
分析:将行和列缩点,即行对应二分图的X部,列对应二分图的Y部,然后交点为连接该行和该列的一条边.匹配时每点都会把整行整列占了,因此就不会出现冲突了. 传送门:hdu1281 棋盘游戏 #include ...
- uva796(求桥数目)
传送门:Critical Links 题意:给出一个无向图,按顺序输出桥. 分析:模板题,求出桥后排个序输出. #include <cstdio> #include <cstring ...
- WPF案例 (四) 模拟Windows7桌面任务栏
原文:WPF案例 (四) 模拟Windows7桌面任务栏 这个程序模彷了Windows7的桌面任务栏,当在桌面上双击某个快捷方式时,将打开一个新的子界面,并且在任务栏里创建一个链接到此界面的任务栏图标 ...
- C库函数标准编程之fscanf()函数解读及其实验
函数功能 fscanf()函数用于从参数stream的文件流中读取format格式的内容,然后存放到...所指定的变量中去.字符串以空格或换行符结束(实验1中会对它进一步说明) 函数格式 字符格式说明 ...
- HighChart学习-更新数据data Series与重绘
一:HighChart介绍 基于JQuery的纯JavaScript的图标库,支持各种图表显示,同时还支持Mootools 与Prototype详细版本支持在这里: JQuery 1.3.2 - 1. ...
- Java与C/C++有什么区别
JDK包含JRE, 1-08: Helloworld: 01-08:classpath配置: 运行其它目录下的class文件: classpath一般不加分号,只找classpath下的文件: 后面加 ...
- Hadoop-2.4.0安装和wordcount执行验证
Hadoop-2.4.0安装和wordcount执行验证 下面描写叙述了64位centos6.5机器下,安装32位hadoop-2.4.0,并通过执行 系统自带的WordCount样例来验证服务正确性 ...
- ps、top 、free查看用户资源信息
查看root用户的进程信息. 运行命令: ps -u root 查看oracle用户的进程信息. 运行命令: ps -u oracle 若查看现在的资源占用情况,如何呢? 运行命令: top 可以 ...