listview滚到底时动态载入更多系统联系人列表。SQL Limit的使用。
刚看了SQLITE不支持SQL里的TOP语句,只有LIMIT。所以想写个东西看看效果。
最简单想到的当然还是联系人列表。顺便还可以试试LIMIT可不可以在android系统的那些contentprovider里面用。
最后要达到的效果就是,一开始载入20条联系人。当listview滚到底后,再载入新的20联系人。一直到载入完所有联系人列表。
好吧直接上代码:
1 public class DynamicLoadContact extends Activity implements OnScrollListener{
2
3 private Activity thisInstance;
4 private ListView lstContact;
5 private ArrayAdapter<String> mAdapter;
6 private boolean mIsLoading = false; //是否正在载入
7
8
9 @Override
10 protected void onCreate(Bundle savedInstanceState) {
11 // TODO Auto-generated method stub
12 super.onCreate(savedInstanceState);
13 thisInstance = this;
14 setContentView(R.layout.dynamic_layout);
15 findView();
16 loadContact();
17 lstContact.setOnScrollListener(this);
18 }
19
20 private void findView(){
21 lstContact = (ListView) findViewById(android.R.id.list);
22 }
23
24 private ContactLoadTask mContactLoadTask;
25 //异步载入联系人
26 private void loadContact(){
27 if (mIsLoading){
28 return;
29 }
30 int currentCount = 0;
31 if (mAdapter != null){
32 currentCount = mAdapter.getCount();
33 }
34 //现情况下,可以不要
35 //因为有一个mIsLoading的成员变量保存载入状态
36 /*
37 if (mContactLoadTask != null){
38 mContactLoadTask.cancel(true);
39 }
40 */
41 mContactLoadTask = new ContactLoadTask();
42 mContactLoadTask.execute(currentCount);
43 Toast.makeText(thisInstance, "loading", Toast.LENGTH_SHORT).show();
44 }
45
46 /**
47 * 联系人列表异步载入类
48 * @author holmes zhang
49 *
50 */
51 private class ContactLoadTask extends AsyncTask<Integer, Void, List<String>>{
52
53 @Override
54 protected void onPreExecute() {
55 // TODO Auto-generated method stub
56 super.onPreExecute();
57 mIsLoading = true;
58 }
59
60 @Override
61 protected List<String> doInBackground(Integer... params) {
62 // TODO Auto-generated method stub
63 String[] projection = new String[]{
64 Contacts.DISPLAY_NAME
65 };
66 //载入新数据前,已显示的数据的总数
67 int lastCount = params[0];
68
69 //SQL 语句, 核心就是这个
70 //LIMIT 20 OFFSET 10
71 //从第11条开始,取20条记录
72 String limit = String.format("LIMIT %d OFFSET %d", 20, lastCount);
73 List<String> result = new ArrayList<String>();
74 Cursor c = null;
75
76 //limit语句最好放在order的后面
77 //虽然select * from table limit 20 offset 10,也可以。但不清楚andorid系统提供的contentprovider,的SQL是怎么构成的。
78 //所以防止SQL出错就加在order里面
79 c = thisInstance.getContentResolver().query(Contacts.CONTENT_URI, projection, null, null, "_id ASC " + limit);
80 if (c != null && !c.isAfterLast()){
81 while(c.moveToNext()){
82 result.add(c.getString(0));
83 }
84 }
85
86 if (c != null) c.close();
87 c = null;
88 return result;
89 }
90
91 @Override
92 protected void onPostExecute(List<String> result) {
93 // TODO Auto-generated method stub
94 super.onPostExecute(result);
95 if (mAdapter == null){
96 mAdapter = new ArrayAdapter<String>(thisInstance, android.R.layout.simple_list_item_1, result);
97 lstContact.setAdapter(mAdapter);
98 }else{
99 for (int i = 0; i < result.size(); i ++){
100 mAdapter.add(result.get(i));
101 }
102 }
103 mIsLoading = false;
104 }
105
106 }
107
108 @Override
109 public void onScroll(AbsListView view, int firstVisibleItem,
110 int visibleItemCount, int totalItemCount) {
111 // TODO Auto-generated method stub
112 if (firstVisibleItem + visibleItemCount >= totalItemCount){
113 //滚到底,载入更多的联系人
114 //判断不精确
115 //要精确的判断可以参考: http://blog.csdn.net/hellogv/article/details/6615487
116 loadContact();
117 }
118 }
119
120 @Override
121 public void onScrollStateChanged(AbsListView view, int scrollState) {
122 // TODO Auto-generated method stub
123
124 }
125 }
布局很简单:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
>
</ListView>
</LinearLayout>
最后预期效果基本达到。
当然滚到底的判断不是很准确。
作者:holmes Zhang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。