首页 > 其他分享 >Lazy延时加载的ListView

Lazy延时加载的ListView

时间:2023-04-07 10:02:50浏览次数:44  
标签:Lazy return License 延时 import android ListView data View


使用的是第三方开发包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滚动至底部


Android ListView pull up to refresh


http://www.iteye.com/topic/1116292


https://github.com/johannilsson/android-pulltorefresh



完整工程:

标签:Lazy,return,License,延时,import,android,ListView,data,View
From: https://blog.51cto.com/u_5454003/6174603

相关文章

  • SwipeRefreshLayout和ListView的EmptyView共存冲突的问题
    SwipeRefreshLayout是android官方的下拉刷新控件;它内部有且只能有一个子控件;当一个ListView嵌入到它内部时,就不能为ListView带一个EmptyView了;于是很自然的想到将ListView和EmptyView纳入到一个父控件中;典型的像下面这样的布局:<android.support.v4.......
  • 使用ScheduledExecutorService延时关闭一个全屏的对话框
    自定义style,设置全屏属性<resources><stylename="AppTheme"parent="android:Theme.Black"/><stylename="processDialog"><itemname="android:windowIsFloating"......
  • LoadMoreListView+SwipeRefreshLayout(分页下拉)基本结构
    一切为了快速迭代importjava.util.ArrayList;importorg.json.JSONObject;importandroid.animation.ObjectAnimator;importandroid.os.Bundle;importandroid.support.v4.widget.SwipeRefreshLayout;importandroid.util.Log;importandroid.vie......
  • 关于ListView中使用GestureDetector冲突的解决办法
    在做OnGestureListener手势滑动界面的时候,会遇到这样的问题,就是当界面中含有ListView的时候,OnGestureListener的界面滑动就被ListView拦截并消费掉了。为了解决这个问题需要重写ListView的OnTouchListener接口:ListViewlistView=(ListView)findViewById(R......
  • 上拉下拉刷新,支持ListView,GridView,ScrollView
    开源项目PullToRefresh详解(一)——PullToRefreshListView类似Lollipop滚动溢出效果的下拉刷新布局:JellyRefreshLayouthttp://www.open-open.com/lib/view/open1437223823115.html网上很多这样的效果都是继承某个具体的AdapterView或ScrollView,这样很不通......
  • Listview中显示不同的视图布局
    1.使用场景在重写ListView的BaseAdapter时,我们常常在getView()方法中复用convertView,以提高性能。convertView在Item为单一的同种类型布局时,能够回收并重用,但是多个Item布局类型不同时,convertView的回收和重用会出现问题。比如有些行为纯文本,有些行则是......
  • 横向滑动的ListView
    我通常把GridView设置成1行来代替横向的listview了,呵呵。下面这个类留着以后试试。publicclassHorizontalListViewextendsAdapterView<ListAdapter>{publicbooleanmAlwaysOverrideTouch=true;protectedListAdaptermAdapter;privateint......
  • 运用手势操作ListView中的Item
    如下面这个图:需要实现的功能是:用手指在某条记录上从左往右划一下,出现一条横线,用于表示这个菜已经上过了;倒过来划,取消这条横线,表示这个菜没上过。如何实现呢?看我的吧!首先需要一个Item的布局,在布局的最上方有一个ImageView用于显示这条横线,如果没有就把这个I......
  • 分别设置listview加载中、空数据、加载数据失败三种状态的显示
    设置listview加载中,空数据,加载数据失败三种状态的显示.基本用法:importjava.util.ArrayList;importjava.util.Arrays;importcom.kanak.emptylayout.EmptyLayout;importandroid.os.Bundle;importandroid.view.View;importandroid.view.View.OnCl......
  • 在ListView上滑动显示Delete按钮
    SwipeLayout实现listview滑动删除功能http://www.devstore.cn/code/info/579.html首先设置listView.setOnTouchListener(onTouchListener);listView=(ListView)findViewById(R.id.listView);listView.setOnItemClickListener(onItemClickListener);li......