MyBasketball 第三篇 下拉刷新上拉加载
2015-08-07 14:00
302 查看
下拉刷新上拉加载是完成XListView里的两个方法onRefresh()和onLoadMore():
在这两个方法中,分别去执行AsyncTask LoadDatasTask
Class LoadDataTask如下:
这里只用到了doInBackground()和onPostExecute()两个方法
造了两个标识符:private static final int LOAD_MORE = 0x110;和private static final int LOAD_REFREASH = 0x111;分别表示上拉加载和下拉刷新
当标识符为LOAD_MORE时,在后台执行loadMoreData()这个方法,当标识符为LOAD_REFREASH时,在后台执行refreashData()方法。
loadMoreData()方法:
Integer refreashData()方法要返回标识符,所以在Asyntask中是return refreashData();
供Asyntask onPostExecute()方法处理的两个标识符:
refreashData():首先检查网络连接情况,没有的话,则去数据库加载,并设置isLoadingDataFromNetWork=false,如果有的话从网络加载,并清空该类型新闻的数据,更新数据库缓存数据
完整的Fragment
数据库的实现:首先是SQLiteOpenHelper
提供了增加单条记录,多条记录,根据类型删除记录等方法的NewsItemDao
网络的辅助类:
设置时间辅助类
SharedPreferences储存
吐司显示辅助类:
最后别忘记加上需要的权限:
public void onRefresh() { // TODO Auto-generated method stub new LoadDatasTask().execute(LOAD_REFREASH); } @Override public void onLoadMore() { // TODO Auto-generated method stub new LoadDatasTask().execute(LOAD_MORE);
在这两个方法中,分别去执行AsyncTask LoadDatasTask
Class LoadDataTask如下:
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.addAll(mDatas); mAdapter.notifyDataSetChanged(); break; case TIP_ERROR_SERVER: ToastUtil.toast(getActivity(), "服务器错误!"); break; default: break; } mXListView.setRefreshTime(AppUtil.getRefreashTime(getActivity(), newsType)); mXListView.stopRefresh(); mXListView.stopLoadMore(); } }
LoadDatasTask的三个参数类型分别是Integet、void、Integet
1.Params 在执行 AsyncTask 时需要传入的参数,可用于在后台任务中使用。
2.Progress 后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为 进度单位
3.Result 当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值 类型。
AsyncTask常被复写的四个方法:
1.onPreExecute() 这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比 如显示一个进度条对话框等。 2. doInBackground(Params...) 这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任 务。任务一旦完成就可以通过 return 语句来将任务的执行结果返回,如果 AsyncTask 的 第三个泛型参数指定的是 Void,就可以不返回任务执行结果。注意,在这个方法中是不 可以进行 UI 操作的,如果需要更新 UI元素,比如说反馈当前任务的执行进度,可以调 用 publishProgress(Progress...)方法来完成。 3. onProgressUpdate(Progress...) 当在后台任务中调用了 publishProgress(Progress...)方法后,这个方法就会很快被调 用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对 UI 进行操 作,利用参数中的数值就可以对界面元素进行相应地更新。 4. onPostExecute(Result) 当后台任务执行完毕并通过 return 语句进行返回时,这个方法就很快会被调用。返 回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些 UI 操作,比如 说提醒任务执行的结果,以及关闭掉进度条对话框等。
这里只用到了doInBackground()和onPostExecute()两个方法
造了两个标识符:private static final int LOAD_MORE = 0x110;和private static final int LOAD_REFREASH = 0x111;分别表示上拉加载和下拉刷新
当标识符为LOAD_MORE时,在后台执行loadMoreData()这个方法,当标识符为LOAD_REFREASH时,在后台执行refreashData()方法。
loadMoreData()方法:
/** * 当前数据是否是从网络中获取的 */ private boolean isLoadingDataFromNetWork;
public void loadMoreData() { // 当前数据是从网络获取的 if (isLoadingDataFromNetWork) { //currentPage += 1; try { List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage); mNewsItemDao.add(newsItems); mAdapter.addAll(newsItems); mDatas = newsItems; } catch (CommonException e) { e.printStackTrace(); } } else // 从数据库加载的 { //currentPage += 1; List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage); mAdapter.addAll(newsItems); } }
Integer refreashData()方法要返回标识符,所以在Asyntask中是return refreashData();
供Asyntask onPostExecute()方法处理的两个标识符:
private static final int TIP_ERROR_NO_NETWORK = 0X112; private static final int TIP_ERROR_SERVER = 0X113;
refreashData():首先检查网络连接情况,没有的话,则去数据库加载,并设置isLoadingDataFromNetWork=false,如果有的话从网络加载,并清空该类型新闻的数据,更新数据库缓存数据
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; }
完整的Fragment
package com.example.mybasketball.fragment;
import java.util.ArrayList;
import java.util.List;
import org.junit.internal.matchers.IsCollectionContaining;
import me.maxwin.view.IXListViewLoadMore;
import me.maxwin.view.IXListViewRefreshListener;
import me.maxwin.view.XListView;
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 android.widget.Switch;
import android.widget.Toast;
import com.example.mybasketball.R;
import com.example.mybasketball.activity.CommonException;
import com.example.mybasketball.adpater.NewsItemAdapter;
import com.example.mybasketball.bean.NewsItem;
import com.example.mybasketball.constaint.cons;
import com.example.mybasketball.db.NewsItemDao;
import com.example.mybasketball.fragment.ChinaFragment.LoadDatasTask;
import com.example.mybasketball.util.AppUtil;
import com.example.mybasketball.util.NetUtil;
import com.example.mybasketball.util.NewsItemBiz;
import com.example.mybasketball.util.ToastUtil;
public class NbaFragment 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;
/**
* 与数据库交互
*/
private NewsItemDao mNewsItemDao;
/**
* 默认的newType
*/
private int newsType = cons.NEWS_TYPE_NBA;
/**
* 当前页面
*/
private int currentPage = 1;
/**
* 处理新闻的业务类
*/
private NewsItemBiz mNewsItemBiz;
/**
* 扩展的ListView
*/
private XListView mXListView;
/**
* 数据适配器
*/
private NewsItemAdapter mAdapter;
/**
* 数据
*/
private List<NewsItem> mDatas = new ArrayList<NewsItem>();
/**
* 获得newType
*
* @param newsType
*/
public NbaFragment(int newsType) {
this.newsType = newsType;
mNewsItemBiz = new NewsItemBiz();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.china, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
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() { // TODO Auto-generated method stub new LoadDatasTask().execute(LOAD_REFREASH); } @Override public void onLoadMore() { // TODO Auto-generated method stub new LoadDatasTask().execute(LOAD_MORE);
}
/**
* 记载数据的异步任务
*
* @author
*
*/
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.addAll(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 void loadMoreData() {
// 当前数据是从网络获取的
if (isLoadingDataFromNetWork) {
//currentPage += 1;
try {
List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType,
currentPage);
mNewsItemDao.add(newsItems);
mAdapter.addAll(newsItems);
mDatas = newsItems;
} catch (CommonException e) {
e.printStackTrace();
}
} else
// 从数据库加载的
{
//currentPage += 1;
List<NewsItem> newsItems = mNewsItemDao.list(newsType, currentPage);
mAdapter.addAll(newsItems);
}
}
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; }
}
数据库的实现:首先是SQLiteOpenHelper
package com.example.mybasketball.db; 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 = "MyBa_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 } }
提供了增加单条记录,多条记录,根据类型删除记录等方法的NewsItemDao
package com.example.mybasketball.db; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.example.mybasketball.bean.NewsItem; public class NewsItemDao { private DBHelper dbHelper; public NewsItemDao(Context context) { dbHelper = new DBHelper(context); } public void add(NewsItem newsItem) { 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) { // 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(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return newsItems; } }
网络的辅助类:
package com.example.mybasketball.util; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.v4.app.FragmentActivity; /** * 判断当前手机联网的渠道 * * @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; } }
设置时间辅助类
package com.example.mybasketball.util; import java.text.SimpleDateFormat; import java.util.Date; import android.annotation.SuppressLint; import android.content.Context; import android.text.TextUtils; @SuppressLint("SimpleDateFormat") public class AppUtil { /** * 根据新闻类型获取上次更新的时间 * * @param newType * @return */ public static String getRefreashTime(Context context, int newType) { String timeStr = PreferenceUtil.readString(context, "NEWS_" + newType); if (TextUtils.isEmpty(timeStr)) { return "我好笨,忘记了..."; } return timeStr; } /** * 根据新闻类型设置上次更新的时间 * * @param newType * @return */ public static void setRefreashTime(Context context, int newType) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); PreferenceUtil.write(context, "NEWS_" + newType,df.format(new Date())); } }
SharedPreferences储存
package com.example.mybasketball.util; import com.example.mybasketball.constaint.cons; import android.content.Context; import android.content.SharedPreferences; public class PreferenceUtil { public static void write(Context context, String key, String value) { SharedPreferences sharedPreferences = context.getSharedPreferences("NBA", Context.MODE_PRIVATE); sharedPreferences.edit().putString(key, value).commit(); } public static void write(Context context, String key, int value) { SharedPreferences sharedPreferences = context.getSharedPreferences("CHINA", Context.MODE_PRIVATE); sharedPreferences.edit().putInt(key, value).commit(); } public static String readString(Context context , String key ) { SharedPreferences sharedPreferences = context.getSharedPreferences("NBA", Context.MODE_PRIVATE); return sharedPreferences.getString(key, ""); } public static int readInt(Context context , String key ) { SharedPreferences sharedPreferences = context.getSharedPreferences("CHINA", Context.MODE_PRIVATE); return sharedPreferences.getInt(key, 0); } public static Boolean readBoolean(Context context , String key ) { SharedPreferences sharedPreferences = context.getSharedPreferences("NBA", Context.MODE_PRIVATE); return sharedPreferences.getBoolean(key, false); } public static void remove(Context context , String key) { SharedPreferences sharedPreferences = context.getSharedPreferences("CHINA", Context.MODE_PRIVATE); sharedPreferences.edit().remove(key).commit(); } }
吐司显示辅助类:
package com.example.mybasketball.util; import android.content.Context; import android.widget.Toast; public class ToastUtil { public static void toast(Context context,String msg){ Toast.makeText(context, msg, 1).show(); } }
最后别忘记加上需要的权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />