`

Lazy延时加载的ListView

阅读更多
使用的是第三方开发包CWAC-AdapterWrapper.jar



package com.ql.app;


/***
Copyright (c) 2008-2009 CommonsWare, LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
	http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import java.util.ArrayList;

import android.app.ListActivity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter;
/**
 * 这个库不好之处,就是底部Loading的View无法定制
 * http://blog.sina.com.cn/s/blog_643e83860100q4vj.html
 * @author admin
 *
 */
public class EndlessAdapterDemo extends ListActivity {
@Override
public void onCreate(Bundle icicle) {
	super.onCreate(icicle);
	setContentView(R.layout.main);
	
	ArrayList<Integer> items=new ArrayList<Integer>();
	
	for (int i=0;i<15;i++) { items.add(i); }
	
	setListAdapter(new DemoAdapter(items));
}

class DemoAdapter extends EndlessAdapter {
	private RotateAnimation rotate=null;
	
	DemoAdapter(ArrayList<Integer> list) {
		super(new ArrayAdapter<Integer>(EndlessAdapterDemo.this,
					R.layout.row,android.R.id.text1,list));
		
		rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
					0.5f, Animation.RELATIVE_TO_SELF,0.5f);
					
		rotate.setDuration(600);
		rotate.setRepeatMode(Animation.RESTART);
		rotate.setRepeatCount(Animation.INFINITE);
	}
	
	@Override
	protected View getPendingView(ViewGroup parent) {
		View row=getLayoutInflater().inflate(R.layout.row, null);
		
		View child=row.findViewById(android.R.id.text1);
		
		child.setVisibility(View.GONE);
		
		child=row.findViewById(R.id.throbber);
		child.setVisibility(View.VISIBLE);
		child.startAnimation(rotate);
		
		return(row);
	}
	
	@Override
	protected boolean cacheInBackground() {
		SystemClock.sleep(5000);				// pretend to do work
		
		return(getWrappedAdapter().getCount()<75);
	}
	
	@Override
	protected void appendCachedData() {
		if (getWrappedAdapter().getCount()<75) {
			@SuppressWarnings("unchecked")
			ArrayAdapter<Integer> a=(ArrayAdapter<Integer>)getWrappedAdapter();
			
			for (int i=0;i<15;i++) { a.add(a.getCount()); }
		}
	}
}
}

package com.ql.app;


/***
Copyright (c) 2008-2009 CommonsWare, LLC
Portions (c) 2009 Google, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
	http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/		

import android.content.Context;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.util.Log;
import android.widget.ListAdapter;
import java.util.concurrent.atomic.AtomicBoolean;
import com.commonsware.cwac.adapter.AdapterWrapper;

/**
* Adapter that assists another adapter in appearing endless.
* For example, this could be used for an adapter being
* filled by a set of Web service calls, where each call returns
* a "page" of data.
*
* Subclasses need to be able to return, via getPendingView()
* a row that can serve as both a placeholder while more data
* is being appended.
*
* The actual logic for loading new data should be done in
* appendInBackground(). This method, as the name suggests,
* is run in a background thread. It should return true if
* there might be more data, false otherwise.
*
* If your situation is such that you will not know if there
* is more data until you do some work (e.g., make another
* Web service call), it is up to you to do something useful
* with that row returned by getPendingView() to let the user
* know you are out of data, plus return false from that final
* call to appendInBackground().
*/
abstract public class EndlessAdapter extends AdapterWrapper {
abstract protected boolean cacheInBackground();
abstract protected void appendCachedData();

private View pendingView=null;
private AtomicBoolean keepOnAppending=new AtomicBoolean(true);
private Context context;
private int pendingResource=-1;

/**
	* Constructor wrapping a supplied ListAdapter
*/
public EndlessAdapter(ListAdapter wrapped) {
	super(wrapped);
}

/**
 * Constructor wrapping a supplied ListAdapter and providing a id for a pending view.
 * @param context
 * @param wrapped
 * @param pendingResource
 */
public EndlessAdapter(Context context, ListAdapter wrapped, int pendingResource) {
	super(wrapped);
	this.context=context;
	this.pendingResource=pendingResource;
}

/**
	* How many items are in the data set represented by this
	* Adapter.
*/
@Override
public int getCount() {
	if (keepOnAppending.get()) {
		return(super.getCount()+1);		// one more for "pending"
	}
	
	return(super.getCount());
}

/**
 * Masks ViewType so the AdapterView replaces the "Pending" row when new
 * data is loaded.
 */
public int getItemViewType(int position) {
	if (position==getWrappedAdapter().getCount()) {
		return(IGNORE_ITEM_VIEW_TYPE);
	}
	
	return(super.getItemViewType(position));
}

/**
 * Masks ViewType so the AdapterView replaces the "Pending" row when new
 * data is loaded.
 * 
 * @see #getItemViewType(int)
 */
public int getViewTypeCount() {
	return(super.getViewTypeCount()+1);
}

/**
	* Get a View that displays the data at the specified
	* position in the data set. In this case, if we are at
	* the end of the list and we are still in append mode,
	* we ask for a pending view and return it, plus kick
	* off the background task to append more data to the
	* wrapped adapter.
	* @param position Position of the item whose data we want
	* @param convertView View to recycle, if not null
	* @param parent ViewGroup containing the returned View
*/
@Override
public View getView(int position, View convertView,
										ViewGroup parent) {
	if (position==super.getCount() &&
			keepOnAppending.get()) {
		if (pendingView==null) {
			pendingView=getPendingView(parent);

			new AppendTask().execute();
		}

		return(pendingView);
	}
	
	return(super.getView(position, convertView, parent));
}

/**
	* Called if cacheInBackground() raises a runtime exception,
	* to allow the UI to deal with the exception on the
	* main application thread.
	* @param pendingView View representing the pending row
	* @param e Exception that was raised by cacheInBackground()
	* @return true if should allow retrying appending new data, false otherwise
*/
protected boolean onException(View pendingView, Exception e) {
	Log.e("EndlessAdapter", "Exception in cacheInBackground()", e);
	
	return(false);
}

/**
 * A background task that will be run when there is a need
 * to append more data. Mostly, this code delegates to the
 * subclass, to append the data in the background thread and
 * rebind the pending view once that is done.
 */
class AppendTask extends AsyncTask<Void, Void, Exception> {
	@Override
	protected Exception doInBackground(Void... params) {
		Exception result=null;
		
		try {
			keepOnAppending.set(cacheInBackground());
		}
		catch (Exception e) {
			result=e;
		}
		
		return(result);
	}

	@Override
	protected void onPostExecute(Exception e) {
		if (e==null) {
			appendCachedData();
		}
		else {
			keepOnAppending.set(onException(pendingView, e));
		}
		
		pendingView=null;
		notifyDataSetChanged();
	}
}

/**
 * Inflates pending view using the pendingResource ID passed into the constructor
 * @param parent
 * @return inflated pending view, or null if the context passed into the pending view constructor was null.
 */
protected View getPendingView(ViewGroup parent) {
	if(context != null) {
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		return inflater.inflate(pendingResource, parent, false);
	}
	
	throw new RuntimeException("You must either override getPendingView() or supply a pending View resource via the constructor");
}
}

row.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
>
	<TextView android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:paddingLeft="6dip"
    android:minHeight="?android:attr/listPreferredItemHeight"
	/>
	<ImageView android:id="@+id/throbber"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
	android:src="@drawable/android:ic_popup_sync"
	android:layout_gravity="center_horizontal"
	android:visibility="gone"
	/>
</FrameLayout>


main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@android:id/list"
	android:layout_width="fill_parent" 
	android:layout_height="fill_parent"
	android:drawSelectorOnTop="false"
/>

http://blog.sina.com.cn/s/blog_643e83860100q4vj.html

精确监听AbsListView滚动至底部
http://blog.csdn.net/hellogv/article/details/6615487

Android ListView pull up to refresh
http://www.iteye.com/topic/1116292
https://github.com/johannilsson/android-pulltorefresh

完整工程:
  • 大小: 3.5 KB
  • LoadingListView.rar (61.2 KB)
  • 描述: 另一个延时加载的ListView(PageableListview)
  • 下载次数: 111
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    ListView 延迟加载图片 改进

    延迟加载(Lazy Loading)是一种策略,它不一次性加载所有图片,而是当用户滚动到某一个列表项时,才加载对应的图片。这种技术可以显著减少初始加载时间,节省内存,提高应用性能。 在描述中提到了一个博客链接,...

    ListView异步延迟加载

    为了解决这些问题,ListView引入了异步延迟加载(Lazy Loading)机制。这种机制的核心思想是只加载当前屏幕可见的数据,当用户滚动时,再按需加载其他数据,从而提高应用的响应速度和用户体验。 异步延迟加载通常...

    Android延迟加载综合案例

    在Android开发中,延迟加载(Lazy Loading)是一种优化策略,用于提高应用性能和用户体验,特别是当处理大量数据或资源时。本案例主要关注在ListView和ImageView中的应用,这两个组件经常在展示大量信息时使用。 ...

    ListView延迟加载

    ListView 延迟加载 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new LongOperation(this,new Excution(){ @Override public void longExcute(){ ...

    安卓listview相关相关-ListView异步延迟加载的代码.rar

    本压缩包中的"ListView异步延迟加载的代码"涉及到的是一个优化技术,即ListView的异步加载和懒加载(Lazy Loading)。这种技术是为了解决当ListView包含大量数据时,一次性加载所有数据可能导致内存消耗过大,甚至...

    android ListView网络延迟加载图片,缓存到本地

    为了解决这个问题,开发者通常会采用延迟加载(Lazy Loading)技术。本文将深入探讨如何在Android中实现ListView的网络延迟加载图片,并将其缓存到本地。 延迟加载是一种优化策略,它只在需要的时候加载数据或资源...

    ListView利用内存缓存异步加载网络大图Demo

    6. **延迟加载**(Lazy Loading):只有当图片所在的列表项进入可视区域时才开始加载图片,其他时候保持占位符,降低内存压力。 7. **弱引用**:使用WeakReference或者SoftReference来保存Bitmap对象,避免内存泄漏...

    网络下载图片ListView加载

    对于ListView,考虑到滑动流畅性,我们通常会采用延迟加载(Lazy Loading)策略,只在图片即将显示在屏幕范围内时才进行加载。 接下来是ListView的优化。由于ListView需要频繁地添加、删除和复用Item,所以性能优化...

    LazyList——对ListView加载网络图片的优化,解决各种问题

    `LazyList`的核心思想是“延迟加载”(Lazy Loading),即只在列表项可见时才去加载相应的图片,而非一次性加载所有图片。这样显著降低了内存占用,提高了应用的运行效率。以下将详细介绍`LazyList`的工作原理和优化...

    Listview显示图片优化

    3.延迟加载(Lazy Loading):当ListView中的图片不在可视区域时,不立即加载,只有当item进入可视范围时才开始加载图片。这大大减少了同时加载的图片数量,降低了内存压力。 4. 图片尺寸适配:根据ListView item的...

    ListView的优化及分类显示

    3. **延迟加载(Lazy Loading)**:对于大图片,不建议一次性加载所有图片,而是当ListView项即将可见时才加载。可以通过实现AbsListView的`onScrollListener`监听滚动事件,判断当前项是否在可视区域。 4. **设置...

    android listview内存优化

    6. **延时加载(Lazy Loading)**:只在列表项进入可视区域时才加载对应的数据,离开可视区域时释放资源,可以显著减少内存占用。 7. **避免多余的数据加载**:在Adapter中,根据ListView的滚动位置,只加载当前...

    Listview显示网络图片demo--真正简单好用

    "Lazy"一词意味着延迟加载,即只有当图片所在的列表项出现在可视区域时才开始加载图片,而不是一次性加载所有图片。这样可以显著降低内存使用,并提升应用性能。 LazyList的核心实现通常包括以下几个关键部分: 1....

    lazy-load-scrollview:Flutter ScrollView的包装器,可进行延迟加载

    将启用延迟加载用法将lazy_load_scrollview依赖项添加到您的pubspec.yaml : dependencies : lazy_load_scrollview : 1.3.0 在DART代码,进口package:lazy_load_scrollview/lazy_load_scrollview.dart然后你可以用你...

Global site tag (gtag.js) - Google Analytics