和大多数初级玩家一样,偶也终于玩到分页了~ ~分页有两个方法:一个是handler,一个是AsyncTask.
我的listview里没有包括图像,所以就没有用到AsyncTask.
准备工作:1.一个用来显示正在加载的xml文件:
View Code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/loading_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:gravity="center_horizontal" > <RelativeLayout android:id="@+id/load_id" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:gravity="center_vertical" android:text="Loading..." android:textSize="12pt" /> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:layout_alignParentRight="true"/> </RelativeLayout> </LinearLayout>
2.listview布局文件:
View Code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/customer_list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:orientation="vertical" > <ListView android:id="@+id/lv_newtask" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:layout_marginRight="5dip" android:cacheColorHint="#ffffff" android:divider="#ffffff" android:dividerHeight="5dip" android:listSelector="#00000000" > </ListView> </LinearLayout>
3.listview_item
View Code
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/newtask_selector_bg" android:minHeight="?android:attr/listPreferredItemHeight" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/avatar_image" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="订单号:" android:textColor="#2894ff" android:textSize="17sp" > </TextView> <TextView android:id="@+id/tv_newtask_item_cwb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="01056895426" android:textColor="#2894ff" android:textSize="17sp" > </TextView> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="客户名:" android:textColor="#2894ff" android:textSize="17sp" > </TextView> <TextView android:id="@+id/tv_newtask_item_consigneeName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="大胡子李" android:textColor="#2894ff" android:textSize="17sp" > </TextView> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="地 址:" android:textColor="#2894ff" android:textSize="17sp" > </TextView> <TextView android:id="@+id/tv_newtask_item_consigneeAddress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" android:text="龙口西" android:textColor="#2894ff" android:textSize="17sp" > </TextView> </LinearLayout> <TextView android:id="@+id/user_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" /> <TextView android:id="@+id/user_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" /> </LinearLayout> <ImageView android:id="@+id/iv_newtask_detail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="@drawable/detail" /> </RelativeLayout>
下面就要开始写我们的分页类了。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.newtask); context = this; findViews(); initListView(); }
View Code
TextView tv_newtask_num; ListView lv_newtask; Context context; View loadingView; protected void findViews(){ tv_newtask_num = (TextView) findViewById(R.id.tv_newtask_num); lv_newtask = (ListView) findViewById(R.id.lv_newtask); tv_newtask_num.setText(Constant.loginInfo.newTasksCount); loadingView = LayoutInflater.from(this).inflate( R.layout.list_page_load, null); }
初始化listView,第一页
NewTaskAdapter adapter; protected void initListView(){ lv_newtask.addFooterView(loadingView); Constant.currentData = getData(currentPage, pageSize); adapter = new NewTaskAdapter(); lv_newtask.setAdapter(adapter); lv_newtask.setOnScrollListener(this); lv_newtask.setOnItemClickListener(this); }
别急,NewTaskAdapter是它的内部类:
class NewTaskAdapter extends BaseAdapter { public NewTaskAdapter(){ DebugLog.i("调用了adapter的构造函数"); } LayoutInflater inflater = LayoutInflater.from(context); int count=Constant.currentData.size(); @Override public int getCount() { return count; } @Override public TaskInfo getItem(int position) { return Constant.currentData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder mHolder = null; if (convertView == null) { mHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.item_newtask, null); mHolder.tv_cwb = (TextView) convertView.findViewById(R.id.tv_newtask_item_cwb); mHolder.tv_consigneeName = (TextView) convertView.findViewById(R.id.tv_newtask_item_consigneeName); mHolder.tv_consigneeAddress = (TextView) convertView.findViewById(R.id.tv_newtask_item_consigneeAddress); mHolder.iv_newtask_detail = (ImageView)convertView.findViewById(R.id.iv_newtask_detail); convertView.setTag(mHolder); }else{ mHolder = (ViewHolder) convertView.getTag(); } mHolder.tv_cwb.setText(Constant.currentData.get(position).cwb); mHolder.tv_consigneeName.setText(Constant.currentData.get(position).consigneeName); mHolder.tv_consigneeAddress.setText(Constant.currentData.get(position).consigneeAddress); mHolder.iv_newtask_detail.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); bundle.putSerializable("taskDetail", Constant.currentData.get(position)); Intent intent = new Intent(context,NewTaskDetailActivity.class); intent.putExtras(bundle); context.startActivity(intent); } }); return convertView; } public class ViewHolder{ public TextView tv_cwb; public TextView tv_consigneeName; public TextView tv_consigneeAddress; public ImageView iv_newtask_detail; } }
Constant.currentData是什么呢?是我的全局类变量汇总: public static ArrayList<TaskInfo> currentData = new ArrayList<TaskInfo>();
获取网络数据:
View Code
private ProgressDialog progressDialog; //private ArrayList<TaskInfo> tempList = null; private String fail_reason; protected ArrayList<TaskInfo> getData(int currentPage, int pageSize){ ArrayList<TaskInfo> tempList = null; final String url = String.format(Constant.URL_NEWTASKLIST, Constant.loginInfo.mSessionId,0,pageSize,(currentPage-1)*pageSize); DebugLog.i("url: **"+url); String result = HttpClient.INSTANCE.get(url); if(result!=null){ TaskInfoListParser parser = new TaskInfoListParser(); tempList = parser.parse(result); fail_reason = parser.reason; } return tempList; }
HttpClient.INSTANCE.get(url);这个方法:
View Code
public enum HttpClient { INSTANCE; final int Timeouts = 30 * 1000; // milliseconds DefaultHttpClient httpClient = null; HttpContext localContext = null; HttpResponse response = null; HttpPost httpPost = null; HttpGet httpGet = null; public void initHttpClient() { HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, Timeouts); HttpConnectionParams.setSoTimeout(myParams, Timeouts); httpClient = new DefaultHttpClient(myParams); localContext = new BasicHttpContext(); } public String get(String url) { if (httpClient == null) { initHttpClient(); } httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); httpGet = new HttpGet(url); response = null; httpGet.setHeader("Accept", "application/soap+xml,application/dime,multipart/related,text/*"); httpGet.setHeader("Content-Type", "text/xml;charset=utf-8"); try { response = httpClient.execute(httpGet, localContext); if (response != null) { HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toString(entity, "utf-8"); } } } catch (Exception ex) { ex.printStackTrace(); } return ""; } }
接下来是重点:监听事件里面实现了分页;
View Code
private int last_item_position; boolean isLoading = false;//是否加载过,控制加载次数 @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { last_item_position = firstVisibleItem + visibleItemCount - 1; if (last_item_position == totalItemCount - 2){//表示在第九个位置加载 if(!isLoading){ new Thread(){ public void run() { isLoading = true; updateCurrendData(); }; }.start(); } } }
View Code
private int addnum = 0;//新增加的项目条数 protected void updateCurrendData(){ currentPage++; ArrayList<TaskInfo> list = getData(currentPage, pageSize); Message msg = new Message(); if(list==null){ msg.what = Constant.NODATA; }else{ addnum = list.size(); for(TaskInfo ti:list){ Constant.currentData.add(ti); } msg.what = Constant.FINISH; } handler.sendMessage(msg); }
我的handler:
private int currentPage = 1; private int pageSize = 10; protected Handler handler = new Handler(){ String tips = null; public void handleMessage(Message msg) { switch(msg.what){ case Constant.FINISH: adapter.count = (currentPage-1)*pageSize+addnum; adapter.notifyDataSetChanged(); handler.removeMessages(0); isLoading = false; break; case Constant.NODATA: Toast.makeText(context, "没有了", Toast.LENGTH_LONG).show(); lv_newtask.removeFooterView(loadingView); break; } if(tips!=null){ Toast.makeText(context, tips, Toast.LENGTH_LONG).show(); } }; };
这样就实现了分页。一定要注意的是,
private int currentPage = 1;
private int pageSize = 10;
这两个变量,一定不能设置成static 。这和activity的生命周期有关系。如果设置成了static ,那么onRestart以后,再请求的数据是空的,就会报出所谓的空指针异常了!