android-----ListView上拉加载更多实现

        前几篇博客,我们从缓存的角度优化了ListView,如果你对此还不太熟悉的话可以到android-----带你一步一步优化ListView(一)android-----带你一步一步优化ListView(二)android-----带你一步一步优化ListView(三),查看,其实,对于ListView的优化来说,还有一种方式我们没有涉及,那就是分页加载了,你在微信加载朋友圈的时候会发现每次显示到最下面会出现加载更多的提示信息,这就是分页加载的使用啦,我们没有必要每次加载ListView的数据时把所有数据全部都查找到,因为ListView本身能够显示在一个界面的条目数是有限的,我们完全可以只去查找一屏幕的数据并且显示他,当用户滑动到最下面的时候再去加载下一屏幕的数据,这对于ListView上面有图片显示的应用来说优化效果特别明显,那么这篇博客,我们将会实现类似于朋友圈上拉加载更多的功能;

        先来看看效果图:

                                             

        好了,接下来我们从代码层面来讲解该怎么实现:

        首先定义一个主界面布局listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ListView 
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</LinearLayout>
        定义每个item的显示布局item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        />
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_toRightOf="@id/imageView"
        android:layout_marginTop="20dp"
        android:layout_marginRight="70dp"
        />
</RelativeLayout>
        很简单,就是一个ImageView和一个TextView

        接下来就是一个用于显示加载更多的布局了load_more.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/loadmore"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"  
    android:orientation="horizontal" >
    
    <ProgressBar  
        android:id="@+id/progress"  
        style="?android:attr/progressBarStyleSmall"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginBottom="30dp"  
        android:layout_marginTop="30dp" />  
  
    <TextView  
        android:id="@+id/tv"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="20dp"  
        android:text="正在加载..."  
        android:textColor="#FF0000" />
</LinearLayout>
        这个界面中会显示一个进度条和正在加载的TextView

        之后便是为我们的ListView设置适配器ListViewAdapter了

public class ListViewAdapter extends BaseAdapter{
	
	public List<String> list;
	public LayoutInflater inflater;
	
	
	public ListViewAdapter() {
	}
	
	public ListViewAdapter(Context context,List<String> list) {
		this.list = list;
		this.inflater = LayoutInflater.from(context);
	}
	
	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public String getItem(int position) {
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}
	
	public void updateView(List<String> nowList)
	{
		this.list = nowList;
		this.notifyDataSetChanged();//强制动态刷新数据进而调用getView方法
	}
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = null;
		ViewHolder holder = null;
		if(convertView == null)
		{
			view = inflater.inflate(R.layout.item, null);
			holder = new ViewHolder();
			holder.imageView = (ImageView)view.findViewById(R.id.imageView);
			holder.textView = (TextView)view.findViewById(R.id.textView);
			view.setTag(holder);//为了复用holder
		}else
		{
			view = convertView;
			holder = (ViewHolder) view.getTag();
		}
		holder.imageView.setImageResource(R.drawable.image);
		holder.textView.setText(list.get(position));
		return view;
	}	
	static class ViewHolder
	{
		ImageView imageView;
		TextView textView;
	}
}

        这段代码中的getView方法就是我们平常使用ListView为其设置适配器所要重写的方法,重点在于第30行的updateView方法了,这个方法用于修改需要显示在ListView上面的数据信息,并且随后调用notifyDataSetChanged方法来通知适配器告诉他ListView上面需要显示的内容已经发生了改变,这时候就会调用getView方法来重新加载数据了;

        接下来就是我们的主Activity

public class MainActivity extends Activity implements OnScrollListener{

	public View loadmoreView;
	public LayoutInflater inflater;
	public ListView listView;
	public int last_index;
	public int total_index;
	public List<String> firstList = new ArrayList<String>();//表示首次加载的list
	public List<String> nextList = new ArrayList<String>();//表示出现刷新之后需要显示的list
	public boolean isLoading = false;//表示是否正处于加载状态
	public ListViewAdapter adapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.listview);
		inflater = LayoutInflater.from(this);
		loadmoreView = inflater.inflate(R.layout.load_more, null);//获得刷新视图
		loadmoreView.setVisibility(View.VISIBLE);//设置刷新视图默认情况下是不可见的
		listView = (ListView) findViewById(R.id.listView);
		initList(10, 10);
		adapter = new ListViewAdapter(this, firstList);
		listView.setOnScrollListener(this);
		listView.addFooterView(loadmoreView,null,false);
		listView.setAdapter(adapter);
	}
	/**
	 * 初始化我们需要加载的数据
	 * @param firstCount
	 * @param nextCount
	 */
	public void initList(int firstCount,int nextCount)
	{
		for(int i = 0;i < firstCount;i++)
		{
			firstList.add("第"+(i+1)+"个开始加载");
		}
		for(int i = 0;i < firstCount;i++)
		{
			nextList.add("第"+(i+1)+"个开始加载");
		}
		for(int i = 0;i < nextCount;i++)
		{
			nextList.add("刷新之后第"+(i+1)+"个开始加载");
		}
	}
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		last_index = firstVisibleItem+visibleItemCount;
		total_index = totalItemCount;
		System.out.println("last:  "+last_index);
		System.out.println("total:  "+total_index);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if(last_index == total_index && (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE))
		{
			//表示此时需要显示刷新视图界面进行新数据的加载(要等滑动停止)
			if(!isLoading)
			{
				//不处于加载状态的话对其进行加载
				isLoading = true;
				//设置刷新界面可见
				loadmoreView.setVisibility(View.VISIBLE);
				onLoad();
			}
		}
	}
	
	/**
	 * 刷新加载
	 */
	public void onLoad()
	{
		try {
			//模拟耗时操作
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if(adapter == null)
		{
			adapter = new ListViewAdapter(this, firstList);
			listView.setAdapter(adapter);
		}else
		{
			adapter.updateView(nextList);
		}
		loadComplete();//刷新结束
	}
	
	/**
	 * 加载完成
	 */
	public void loadComplete()
	{
		loadmoreView.setVisibility(View.GONE);//设置刷新界面不可见
		isLoading = false;//设置正在刷新标志位false
		MainActivity.this.invalidateOptionsMenu();
		listView.removeFooterView(loadmoreView);//如果是最后一页的话,则将其从ListView中移出
	}
}

        在第19行获得了加载更多的刷新视图并且第20行设置该视图是可见的,因为我们模拟的是要加载两页的数据,这样的话第一页加载结束之后需要显示加载更多的视图,在第24行将该视图添加到了ListView的最下面,随后为Listview添加滑动事件,这里面最重要的两个方法就是第48行的onScroll和第56行的onScrollStateChanged,通过onScroll中的last_index用于获得当前页面表示在现时屏幕可以见到的最大Item的位置,total_index用于表示ListView可以加载的ListItem总数;第57行判断当前页面表示在现时屏幕可以见到的最大Item的位置如果等于ListView可以加载的ListItem总数并且滑动停止的话,则判断isLoading是否处于加载状态,如果不处于加载状态的话,则调用onLoad方法去加载,这个方法里面的Thread.sleep(2000)用于模拟耗时操作,随后利用ListAdapter的updateView方法更新ListView需要显示的数据,最后调用loadComplete来结束刷新操作,第98行设置刷新视图不可见,修改isLoading加载标志,最后将加载更多视图从当前ListView中移除;

        至此,上拉加载更多讲解结束,下一篇我们将讲解一下下拉刷新的实现,谢谢大家!

点击下载源码!!!!!


  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现 Android ListView 上拉加载更多的常用方法是使用下拉刷新框架,如 SwipeRefreshLayout 和 SmartRefreshLayout。这些框架提供了方便的 API 来实现下拉刷新和上拉加载更多。 这里提供一种基于 SmartRefreshLayout 的实现方法: 1. 在布局文件中添加 SmartRefreshLayout 和 ListView 组件: ``` <com.scwang.smartrefresh.layout.SmartRefreshLayout android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> </com.scwang.smartrefresh.layout.SmartRefreshLayout> ``` 2. 在 Activity 或 Fragment 中初始化 SmartRefreshLayout 和 ListView: ``` SmartRefreshLayout refreshLayout = findViewById(R.id.refreshLayout); ListView listView = findViewById(R.id.listView); // 设置下拉刷新监听器 refreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh(@NonNull RefreshLayout refreshLayout) { // 下拉刷新操作 // 刷新完成后调用 refreshLayout.finishRefresh() 方法 } }); // 设置上拉加载更多监听器 refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { @Override public void onLoadMore(@NonNull RefreshLayout refreshLayout) { // 上拉加载更多操作 // 加载完成后调用 refreshLayout.finishLoadMore() 方法 } }); ``` 3. 当需要触发上拉加载更多时,调用 SmartRefreshLayout 的 `autoLoadMore()` 方法即可触发加载更多。 ``` refreshLayout.autoLoadMore(); ``` 在上面的代码中,你需要在上拉加载更多操作完成后手动调用 `refreshLayout.finishLoadMore()` 方法来通知 SmartRefreshLayout 完成加载更多操作。同样,在下拉刷新操作完成后,你也需要调用 `refreshLayout.finishRefresh()` 方法来通知 SmartRefreshLayout 完成下拉刷新操作。 总体来说,以上是一种基于 SmartRefreshLayout 的实现上拉加载更多的方法,你也可以使用其他类似框架来实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值