支持上拉加载更多的控件有很多,但是你知道背后的原理吗?有一些面试官可能会问到这方便的知识,他们认为会用不是目的,懂背后的原理才是真人才。下面我们通过实现OnScrollListener接口实现上拉加载更多的效果,这里用到了回调接口,你需要对回调进行比较好的理解,回调机制是Android中很重要的机制,下面我们看一下代码:
1.定义一个footer.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" > <LinearLayout android:id="@+id/ll_footer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:id="@+id/tv_wait" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="正在加载..." android:textSize="10sp" /> </LinearLayout> </LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.listviewscrolldemo.LoadListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
package com.example.listviewscrolldemo; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; public class LoadListView extends ListView implements OnScrollListener { private int lastVisibleItem;// 最后一个可见项 private int totalItems;// 所有项 private View footer;// 底部布局 private Boolean isLoading = false; private ILoadListener iListener; public LoadListView(Context context) { super(context); initView(context); } public LoadListView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public LoadListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } /** * 添加底部加载提示到布局Listview * * @param context */ private void initView(Context context) { LayoutInflater inflater = LayoutInflater.from(context); footer = inflater.inflate(R.layout.footer, null); footer.findViewById(R.id.ll_footer).setVisibility(View.GONE);// 首先设置加载提示不可见 this.addFooterView(footer); this.setOnScrollListener(this);// 设置滚动监听 } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (lastVisibleItem == totalItems && scrollState == SCROLL_STATE_IDLE) { if (!isLoading) {// 判断不是正在加载! footer.findViewById(R.id.ll_footer).setVisibility(View.VISIBLE);// 首先设置加载提示可见 iListener.onLoad(); isLoading = true; } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.lastVisibleItem = firstVisibleItem + visibleItemCount; this.totalItems = totalItemCount; } // 传递 public void setInterface(ILoadListener iListener) { this.iListener = iListener; } /** * 加载更多数据的回调接口 * * @author Administrator * */ public interface ILoadListener { public void onLoad(); } // 加载完毕 public void loadCompleted() { isLoading = false; footer.findViewById(R.id.ll_footer).setVisibility(View.GONE); } }
package com.example.listviewscrolldemo; import java.util.ArrayList; import java.util.List; import com.example.listviewscrolldemo.LoadListView.ILoadListener; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.widget.ArrayAdapter; public class MainActivity extends Activity implements ILoadListener { private LoadListView mListView; private ArrayAdapter<String> adapter; private List<String> datas; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); initDatas(); } private void initDatas() { for (int i = 1; i < 21; i++) { datas.add("数据" + i + ""); } } private void initMoreDatas() { for (int i = 1; i < 3; i++) { datas.add("新数据" + i + ""); } } private void initViews() { mListView = (LoadListView) findViewById(R.id.lv_main); mListView.setInterface(this); datas = new ArrayList<String>(); adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, datas); // adapter=new // ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1); mListView.setAdapter(adapter); } @Override public void onLoad() { // 添加延时效果 Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { initMoreDatas();// 获取更多数据 adapter.notifyDataSetChanged();// 刷新ListView mListView.loadCompleted();// 隐藏加载提示 } }, 2000); } }
2.判断到达底部的方法:lastVisibleItem == totalItems;即最后一个可见项的标值等于总Item数量的时候;
3.加载数据用到了接口回调的方式,这里应该注意;
4.模拟延时的效果,我们用到了Handler的postDelayed()方法。
运行实例:
喜欢的朋友关注我和我的公众号(左边栏),谢谢!
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)
原文地址:http://blog.csdn.net/yayun0516/article/details/48212987