实现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 ...
随机推荐
- g++优化选项
g++优化选项 g++优化选项 对于下面的这段代码: 1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std; ...
- ArcSDE当关系查询ArcMap与REST查询结果不一致问题的解决
首先描述来形容什么问题: 周边环境:ArcGIS10.x.Oracle 11g R2,这个问题无关与环境 假设用户使用关联查询(比方一个空间数据与一个属性数据进行关联),在ArcGIS for Des ...
- 怎样处理iOS 5与iOS 6的 low-memory
移动设备终端的内存极为有限,应用程序必须做好low-memory处理工作,才能避免程序因内存使用过大而崩溃. low-memory 处理思路 通常一个应用程序会包含多个view controllers ...
- sqlit使用要点之引入libsqlite3.dylib
怎样引入libsqlite3.dylib? 在.h 或 .cpp文件里包括相应的头文件
- Unix Domain Socket 域套接字实现
主要注意流程: STREAM SOCKET: Server : socket() ---> bind() ---> listen() ---> accept() Client: ...
- bash学习之环境变量
1.查看系统存在的环境变量env 和 export env命令:查看环境变量 [CJP@CJP ~]$ env HOSTNAME=CJP SHELL=/bin/bash HISTSIZE=1000 U ...
- hdu2062(递推)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2062 详细分析:http://mamicode.com/info-detail-95273.html ...
- 使用COM提供SafeArray数据
在前一篇博文<读取SafeArray数据>我们介绍了C#读取安全数组.那么我们的COM怎么编写呢? 1. 定义SAFEARRAY变量 SAFEARRAY *pSArray = NULL; ...
- android 图片水平反复平铺(repeat x)
<=用来反复显示的图 1.最简单方式 创建wave_repeat.xml <?xml version="1.0" encoding="utf-8"? ...
- 什么是gulp?
gulp初涉 1.什么是gulp? gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器:它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用 ...