您的位置:首页 > 数据库

ListView的分批加载和分页加载

2015-08-30 02:57 489 查看
1、分批加载的原理:

其实分批加载是有DAO控制数据库返回固定条数的数据并显示在ListView的页面中。

public class CallSafeActivity2 extends BaseActivity implements OnClickListener{

private TextView tv_title;
private ImageView iv_left;
private ImageView iv_right;
private ListView list_view;
private List<BlackNumber> mBlackNumbers;
//表示每页多少条数据
private int pageSize=20;
//表示当前页面
private int mCurrentPage=0;
//表示总页数
private int totalPage;
private EditText et_page;
private TextView current_count_page;
private BlackNumberDao dao;

/**
* 初始化UI
*/
@Override
protected void initUI() {
setContentView(R.layout.activity_call_safe2);
list_view = (ListView) findViewById(R.id.list_view);
et_page = (EditText) findViewById(R.id.et_page);
current_count_page = (TextView) findViewById(R.id.current_count_page);

}

/**
* 初始化标题栏
*/
@Override
protected void initTiltBar() {
tv_title = (TextView) findViewById(R.id.tv_title);
iv_left = (ImageView) findViewById(R.id.iv_left);
iv_right = (ImageView) findViewById(R.id.iv_right);
tv_title.setText("黑名单管理");
iv_left.setVisibility(View.INVISIBLE);
iv_right.setVisibility(View.VISIBLE);
iv_right.setOnClickListener(this);
}

/**
* 初始化数据
*/
@Override
protected void initData() {
dao = new BlackNumberDao(this);
//以下为普通的listView全部加载的方法
//mBlackNumbers = dao.findAll();
//CallSafeAdapter adapter = new CallSafeAdapter(mBlackNumbers, this);
//list_view.setAdapter(adapter);

//分页加载,totalPage代表总页数,mCurrentPage代表起始坐标
totalPage = dao.getTotalNumber()/pageSize;
current_count_page.setText(mCurrentPage+"/"+(totalPage-1));
new Thread(){
public void run(){
//将查询到的数据添加到集合中
mBlackNumbers= dao.findPar(pageSize, mCurrentPage);
handler.sendEmptyMessage(0);
}
}.start();
}
Handler handler=new Handler(){
public void handleMessage(Message msg) {
CallSafeAdapter adapter=new CallSafeAdapter(mBlackNumbers, CallSafeActivity2.this);
list_view.setAdapter(adapter);
};
};
/**
* listView适配器的定义
* @author dell
*
*/
private class CallSafeAdapter extends MyBaseAdapter<BlackNumber>{
//MyBaseAdapter的构造方法
public CallSafeAdapter(List<BlackNumber> mLists, Context mContext) {
super(mLists, mContext);
}

private TextView tv_number;
private TextView tv_mode;
private ImageView iv_delete;
private View view;
private ViewHolder holder;

//listView实现的核心方法
public View getView(int position, View convertView, ViewGroup parent) {

//用convertView可以把效率提高200%,但是每次复用的时候需要findViewById,pull逐行解析的时候比较费时间
if (convertView==null) {
view = View.inflate(CallSafeActivity2.this, R.layout.item_call_safe, null);

//viewHold为静态类,效率可再提高50%,因为它的实现不再需要复用的时候再去findViewById,而是直接复用
holder = new ViewHolder();

holder.tv_number = (TextView) view.findViewById(R.id.tv_number);
holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);
holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);

view.setTag(holder);
}else {
view=convertView;
holder = (ViewHolder) view.getTag();
}

holder.tv_number.setText(mLists.get(position).getNumber());
String mode = mLists.get(position).getMode();
if (mode.equals("1")) {
holder.tv_mode.setText("全部拦截");
} else if (mode.equals("2")) {
holder.tv_mode.setText("电话拦截");
} else if (mode.equals("3")) {
holder.tv_mode.setText("短信拦截");
}
return view;
}

}
/**
* listView的优化,可以把效率提高50%。省去findViewById的过程,只需要获取一次对象
* @author dell
*
*/
static class ViewHolder{
TextView tv_number;
TextView tv_mode;
ImageView iv_delete;
}

public void onClick(View v) {

}
/**
* 上一页
*/
public void pre(View view){
if (mCurrentPage<=0) {
ToastUtils.showSafeToast(CallSafeActivity2.this, "已经是第一页了");
return;
}
mCurrentPage--;
initData();
}
/**
* 下一页
*/
public void next(View view){
if(mCurrentPage >= totalPage - 1 ){
ToastUtils.showSafeToast(CallSafeActivity2.this, "已经是最后页了");
return ;
}
mCurrentPage++;
initData();
}
/**
* 跳转到那页
* @param view
*/
public void jump(View view){
String str_page = et_page.getText().toString().trim();
if(TextUtils.isEmpty(str_page)){
ToastUtils.showSafeToast(CallSafeActivity2.this, "请输入页面");
}else{
//获取到页面
int number = Integer.parseInt(str_page);
//判断页面输入是否正确
if(number < 0 || number > totalPage - 1){
ToastUtils.showSafeToast(CallSafeActivity2.this, "请输入正确页面");

}else{
mCurrentPage = number;
initData();
}
}
}

}


对应的DAO类:

public class BlackNumberDao {

private BlackNumberSQLiteOpenHelper helper;
private SQLiteDatabase db;

public BlackNumberDao(Context context) {
helper = new BlackNumberSQLiteOpenHelper(context);
}
/**
* 往数据库增加数据
* @param number
* @param mode
* @return
*/
public boolean add(String number,String mode){
db = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("number",number);
values.put("mode", mode);
long rawId = db.insert("blacknumber", null, values);
if (rawId==-1) {
//插入失败
return false;
}else {
//插入成功
return true;
}
}
/**
* 删除数据库中的数据
* @param number
* @return
*/
public boolean delete(String number){
db = helper.getWritableDatabase();
int rowNumber = db.delete("blacknumber", "number=?", new String[]{number});
if (rowNumber==0) {
return false;
}else {
return true;
}
}
/**
* 改变黑名单模式
* @param number
* @param newmode
* @return
*/
public boolean changeNumberMode(String number,String newmode){
db = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("mode", newmode);
int rowNumber = db.update("blacknumber", values, "number=?", new String[]{number});
if (rowNumber == 0) {
return false;
} else {
return true;
}
}
/**
* 根据电话号码查询黑名单的模式
*
* @param number
* @return
*/
public String find(String number) {
String mode = "";
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("blacknumber", new String[] { "mode" },
"number=?", new String[] { number }, null, null, null);
if (cursor.moveToNext()) {
mode = cursor.getString(0);
}
cursor.close();
db.close();
return mode;
}
/**
* 查询所有数据
* @return
*/
public List<BlackNumber> findAll(){
List<BlackNumber> list=new ArrayList<BlackNumber>();
db = helper.getWritableDatabase();
Cursor cursor = db.query("blacknumber", new String[]{"number","mode"}, null , null, null, null, null);
while (cursor.moveToNext()) {
BlackNumber blackNumber = new BlackNumber();
blackNumber.setNumber(cursor.getString(0));
blackNumber.setMode(cursor.getString(1));
list.add(blackNumber);
}
cursor.close();
db.close();
return list;
}
/**
* 分页查询
* @param pageSize 每页加载多少条数据
* @param startIndex 每页的开始位置
* @return
*/
public List<BlackNumber> findPar(int pageSize,int startIndex){
List<BlackNumber> list = new ArrayList<BlackNumber>();
db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery("select number,mode from blacknumber limit ? offset ?", new String[]{String.valueOf(pageSize),String.valueOf(startIndex*pageSize)});
while (cursor.moveToNext()) {
BlackNumber blackNumber = new BlackNumber();
blackNumber.setNumber(cursor.getString(0));
blackNumber.setMode(cursor.getString(1));
list.add(blackNumber);
}
cursor.close();
db.close();
return list;
}

/**
* 分批查询
* @param pageSize 每页加载多少条数据
* @param startIndex 每页的开始位置
* @return
*/
public List<BlackNumber> findPar2(int pageSize,int startIndex){
List<BlackNumber> list = new ArrayList<BlackNumber>();
db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery("select number,mode from blacknumber limit ? offset ?", new String[]{String.valueOf(pageSize),String.valueOf(startIndex)});
while (cursor.moveToNext()) {
BlackNumber blackNumber = new BlackNumber();
blackNumber.setNumber(cursor.getString(0));
blackNumber.setMode(cursor.getString(1));
list.add(blackNumber);
}
cursor.close();
db.close();
return list;
}
/**
* 查询总条数
* @return
*/
public int getTotalNumber(){
db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery("select count(*) from blacknumber", null);
cursor.moveToNext();
int count = cursor.getInt(0);
cursor.close();
db.close();
return count;
}
}


2、分批加载原理与分页加载原理相同,不同在于判断ListView是否下拉到底部,然后再加载数据,有个刷新的过程,代码如下:

描 述 :实现分批加载,新增setOnScrollListener监听器,list_view.getLastVisiblePosition()方法

public class CallSafeActivity extends BaseActivity implements OnClickListener{

private TextView tv_title;
private ImageView iv_left;
private ImageView iv_right;
private ListView list_view;
private List<BlackNumber> mBlackNumbers;
//表示每页多少条数据
private int maxCount=20;
//表示当前页面
private int startIndex=0;
//表示总页数
private int totalNumber;
private BlackNumberDao dao;

/**
* 初始化UI
*/
@Override
protected void initUI() {
setContentView(R.layout.activity_call_safe);
list_view = (ListView) findViewById(R.id.list_view);
list_view.setOnScrollListener(new OnScrollListener() {
//触屏状态改变的时候回调用(静止到滚动。。。)
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
//惯性滑动调用的方法
case OnScrollListener.SCROLL_STATE_FLING:

break;
//当滚动静止时调用的方法
case OnScrollListener.SCROLL_STATE_IDLE:
int lastVisiblePosition = list_view.getLastVisiblePosition();

//判断当前的最后一条数据是不是服务器返回的最后一条数据
if (lastVisiblePosition==mBlackNumbers.size()-1) {
//从服务器分批加载数据
startIndex+=maxCount;
if (startIndex>=totalNumber) {
ToastUtils.showSafeToast(CallSafeActivity.this, "已经没有更多的数据了");
return;
}
initData();
}
break;
//当触摸屏幕的时候调用的方法
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:

break;
default:
break;
}
}
//触摸到屏幕会调用
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {

}
});

}

/**
* 初始化标题栏
*/
@Override
protected void initTiltBar() {
tv_title = (TextView) findViewById(R.id.tv_title);
iv_left = (ImageView) findViewById(R.id.iv_left);
iv_right = (ImageView) findViewById(R.id.iv_right);
tv_title.setText("黑名单管理");
iv_left.setVisibility(View.INVISIBLE);
iv_right.setVisibility(View.VISIBLE);

//为添加黑名单设置点击事件
iv_right.setOnClickListener(this);
}

/**
* 初始化数据
*/
@Override
protected void initData() {
dao = new BlackNumberDao(this);

//分页加载,totalPage代表总页数,mCurrentPage代表起始坐标
totalNumber = dao.getTotalNumber();

new Thread(){
public void run(){
// 判断当前的集合是否有数据。如果没有数据那么就把数据库的20条数据添加进去
if (mBlackNumbers==null) {
mBlackNumbers= dao.findPar2(maxCount, startIndex);
}else {
//如果已经有了数据,防止覆盖
mBlackNumbers.addAll(dao.findPar2(maxCount, startIndex));
}
handler.sendEmptyMessage(0);
}
}.start();
}
private CallSafeAdapter adapter;
Handler handler=new Handler(){
public void handleMessage(Message msg) {
if (adapter==null) {
adapter = new CallSafeAdapter(mBlackNumbers, CallSafeActivity.this);
list_view.setAdapter(adapter);
}else {
//刷新当前界面的数据
adapter.notifyDataSetChanged();
}
};

};
private AlertDialog dialog;
/**
* listView适配器的定义
* @author dell
*
*/
private class CallSafeAdapter extends MyBaseAdapter<BlackNumber>{
//CallSafeAdapter的构造方法
public CallSafeAdapter(List<BlackNumber> mLists, Context mContext) {
super(mLists, mContext);
}

private TextView tv_number;
private TextView tv_mode;
private ImageView iv_delete;
private View view;
private ViewHolder holder;

//listView实现的核心方法
public View getView(final int position, View convertView, ViewGroup parent) {

//用convertView可以把效率提高200%,但是每次复用的时候需要findViewById,pull逐行解析的时候比较费时间
if (convertView==null) {
view = View.inflate(CallSafeActivity.this, R.layout.item_call_safe, null);

//viewHold为静态类,效率可再提高50%,因为它的实现不再需要复用的时候再去findViewById,而是直接复用
holder = new ViewHolder();

holder.tv_number = (TextView) view.findViewById(R.id.tv_number);
holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);
holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);

view.setTag(holder);
}else {
view=convertView;
holder = (ViewHolder) view.getTag();
}

holder.tv_number.setText(mLists.get(position).getNumber());
String mode = mLists.get(position).getMode();
if (mode.equals("1")) {
holder.tv_mode.setText("全部拦截");
} else if (mode.equals("2")) {
holder.tv_mode.setText("电话拦截");
} else if (mode.equals("3")) {
holder.tv_mode.setText("短信拦截");
}
//获取到黑名单的电话号码
final String number = mLists.get(position).getNumber();
//删除黑名单的电话号码
holder.iv_delete.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
//根据电话号码删除数据
boolean result = dao.delete(number);
//如果返回true说明删除成功
if (result) {
//将当前的对象从集合里边删除
mBlackNumbers.remove(position);
//刷新界面
adapter.notifyDataSetChanged();
ToastUtils.showSafeToast(CallSafeActivity.this, "删除成功");
}else {
ToastUtils.showSafeToast(CallSafeActivity.this, "删除失败");
}
}
});
return view;
}

}
/**
* listView的优化,可以把效率提高50%。省去findViewById的过程,只需要获取一次对象
* @author dell
*
*/
static class ViewHolder{
TextView tv_number;
TextView tv_mode;
ImageView iv_delete;
}
/**
* 返回键
*/
@Override
public void onBackPressed() {
SystemInfo.startActivity(this, MainActivity.class);
super.onBackPressed();
}

/**
* 添加黑名单
*/
public void onClick(View v) {
AlertDialog.Builder builder = new Builder(this);
final View view = View.inflate(this, R.layout.dialog_add_black_number, null);
//黑名单电话
final TextView et_number = (TextView) view.findViewById(R.id.et_number);
//确定
Button bt_ok = (Button) view.findViewById(R.id.bt_ok);
//取消
Button bt_cancel = (Button) view.findViewById(R.id.bt_cancel);
//电话拦截
final CheckBox cb_phone = (CheckBox) view.findViewById(R.id.cb_phone);
//短信拦截
final CheckBox cb_sms = (CheckBox) view.findViewById(R.id.cb_sms);

//取消的点击事件
bt_cancel.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
dialog.dismiss();
}
});

//确定的点击事件
bt_ok.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
//获取到黑名单电话号码
String str_number = et_number.getText().toString().trim();
//如果当前黑名单号码设置为空,就提示用户输入电话号码
if (TextUtils.isEmpty(str_number)) {
ToastUtils.showSafeToast(CallSafeActivity.this, "请输入电话号码");
return;
}

/**
* 1 电话拦截 + 短信拦截(全部拦截) 2 电话拦截 3短信拦截
*/
String mode;
//判断当前的电话号码和短信是否被勾选
if (cb_phone.isChecked()&&cb_sms.isChecked()) {
//全部拦截
mode="1";
}else if (cb_phone.isChecked()) {
//电话拦截
mode="2";
}else if (cb_sms.isChecked()) {
//短信拦截
mode="3";
}else{
ToastUtils.showSafeToast(CallSafeActivity.this, "请勾选拦截模式");
return;
}
BlackNumber blackNumber = new BlackNumber();

blackNumber.setNumber(str_number);
blackNumber.setMode(mode);

//判断当前是否添加成功——数据库
boolean result = dao.add(str_number, mode);
//如果true说明添加成功,刷新界面
if (result) {
mBlackNumbers.add(0, blackNumber);
adapter.notifyDataSetChanged();
ToastUtils.showSafeToast(CallSafeActivity.this, "添加成功");
}else{
ToastUtils.showSafeToast(CallSafeActivity.this, "添加失败");
}
dialog.dismiss();
}
});
builder.setView(view);
dialog = builder.show();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  listview 数据库