今天继续对我们的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;
- }
- }
今天到此结束,现在基本就剩下,文章的详细信息的展示,和对页面上的图片进行保存了。
如果这篇文章对你有用,可以顶一个~