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

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23698511

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

今天的目标是:

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

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

大概效果图:

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

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;
}
}

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

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

源码点击此处下载

上一篇:MUI - 上拉刷新/下拉加载


下一篇:mui上拉刷新+下拉加载