ListView,AsyncTask异步加载

ListView结合getView来显示数据的时候,可能每一个listItem都需要后台进行大量的耗时处理,比如从网络下载,或者计算得出结果等等。这时候如果用户滚动ListView就会得到不好的用户体验,会很卡。

 

可以这样解决这个问题:

 

当用户滚动屏幕的时候,监听listview滚动onScroll()和停止滚动的事件onScrollStateChanged()。

 

每次滚动的时候触发onScroll(),在onScroll()中获得firstVisibleItem和visibleItemCount。保存起来。

 

当用户停止滚动的时候,触发onScrollStateChanged(),这时候将获得的firstVisibleItem和visibleItemCount传递给自定义的一个接口方法scrollTo()。

 

在scrollTo()中开启一个AsyncTask线程。通过这个线程来实现后台数据的加载

 

Activity:

class LvOfCallLogsScrollListener implements OnScrollListener {

		private int firstVisibleItem;
		private int visibleItemCount;

		public void onScrollStateChanged(AbsListView view, int scrollState) {
			System.out.println("---------onScrollStateChanged---------"
					+ scrollState + " ==" + OnScrollListener.SCROLL_STATE_IDLE
					+ "firstVisibleItem" + firstVisibleItem
					+ "visibleItemCount:" + visibleItemCount);
			if (popWindowOfKeyboard.isShowing()) {
				popWindowOfKeyboard.dismiss();

				sendBroadcastToMain(KEYBOARD_CLOSED);
			}
			if (myPopupWindowOfCallLogSort.isShowing()) {
				myPopupWindowOfCallLogSort.dismiss();
			}
			if (scrollState == OnScrollListener.SCROLL_STATE_IDLE)
				if (view.getAdapter() instanceof GenerateItemView) {
					((GenerateItemView) view.getAdapter()).scrollTo(
							firstVisibleItem, visibleItemCount);
				}

		}

		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			// System.out.println("---------onScroll---------");
			this.firstVisibleItem = firstVisibleItem;
			this.visibleItemCount = visibleItemCount;
			if(firstVisibleItem==0)
			{
				if (view.getAdapter() instanceof GenerateItemView) {
					((GenerateItemView) view.getAdapter()).scrollTo(
							firstVisibleItem, visibleItemCount);
				}
			}

		}

	}

 

BaseAdapter:

/** 
	 * 
	 * @param firsP
	 * @param lasp
	 */
	public  void scrollTo(int firsP,int lasp)
	{
		
		loadRunnable=new LoadRunnable(firsP,lasp);
		
		loadRunnable.execute(null);
		
		
	}
	
	 
	private class LoadRunnable extends AsyncTask {

		private int first;
		private int visible;
		public LoadRunnable(int firsP,int visible)
		{
			first=firsP;
			this.visible=visible;
		}
		 
		@Override
		protected void onPostExecute(Object result) {
			//.....
			 notifyDataSetChanged();
		}

		@Override
		protected Object doInBackground(Object... params) {
			//.....耗时操作
			for(int i=0;i<visible;i++)
				listOfPersonList.get(i+first).get(0).setTelLocation("fuzhou");
			return null;
		}
		
		
		
	};

 

但是这样做有一个不好的地方,当用户一直滚动的时候,会出现明显的加载数据延时。因为没有把无效滚动的消息忽略掉。

 

 

 

你可能感兴趣的:(AsyncTask)