<?xml version="1.0" encoding="utf-8"?><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"tools:context="com.company.listviewdeepknow.MainActivity"><ListViewandroid:id="@+id/mList"android:layout_width="match_parent"android:layout_height="match_parent"></ListView></RelativeLayout>foot_boot.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="70dp"android:gravity="center"android:orientation="horizontal"><ProgressBarandroid:id="@+id/progressBar"style="?android:attr/progressBarStyleSmall"android:layout_width="45dp"android:layout_height="45dp" /><TextViewandroid:id="@+id/mLoad"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="加载更多..."android:textSize="20sp" /></LinearLayout>list_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="horizontal"><TextViewandroid:id="@+id/mTv1"android:layout_width="100dp"android:layout_height="100dp"android:textSize="20sp" /><TextViewandroid:id="@+id/mTv2"android:layout_width="100dp"android:layout_height="100dp"android:layout_alignParentRight="true"android:textSize="20sp" /></RelativeLayout>MainActivity.java
public class MainActivity extends AppCompatActivity implements MyOnScrollListener.OnloadDataListener {//ListView展示的数据项private List<Student> data;//ListView控件private ListView mList;//自定义适配器MyAdapter adapter;//底部加载更多布局View footer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//首先加载默认数据,这里设置为10条getData();//显示到ListView上showListView(data);//自定义的滚动监听事件MyOnScrollListener onScrollListener = new MyOnScrollListener(footer, data);//设置接口回调onScrollListener.setOnLoadDataListener(this);//设置ListView的滚动监听事件mList.setOnScrollListener(onScrollListener);}/** * 初始化ListView数据,默认设置为10条 */private void getData() {data = new ArrayList<>();Student stu = null;for (int i = 0; i < 10; i++) {stu = new Student();stu.setName("姓名" + i);stu.setSex(i % 2 == 0 ? "男" : "女");data.add(stu);}}/** * 将数据加载到ListView上 * * @param data */private void showListView(List<Student> data) {//首先判断适配器是否为空,首次运行肯定是为空的if (adapter == null) {//查到ListView控件mList = (ListView) findViewById(R.id.mList);//将底部加载一个加载更多的布局footer = LayoutInflater.from(this).inflate(R.layout.foot_boot, null);//初始状态为隐藏footer.setVisibility(View.GONE);//加入到ListView的底部mList.addFooterView(footer);//创建adpter数据adapter = new MyAdapter(data);//设置adaptermList.setAdapter(adapter);} else {//不为空,则刷新数据this.data = data;//提醒ListView重新更新数据adapter.notifyDataSetChanged();}}@Overridepublic void onLoadData(List<Student> data) {//加载数据完成后,展示数据到ListViewshowListView(data);}}MyOnScrollListener.java
public class MyOnScrollListener implements AbsListView.OnScrollListener {//ListView总共显示多少条private int totalItemCount;//ListView最后的item项private int lastItem;//用于判断当前是否在加载private boolean isLoading;//底部加载更多布局private View footer;//接口回调的实例private OnloadDataListener listener;//数据private List<Student> data;public MyOnScrollListener(View footer, List<Student> data) {this.footer = footer;this.data = data;}//设置接口回调的实例public void setOnLoadDataListener(OnloadDataListener listener) {this.listener = listener;}/** * 滑动状态变化 * * @param view * @param scrollState 1 SCROLL_STATE_TOUCH_SCROLL是拖动2 SCROLL_STATE_FLING是惯性滑动 0SCROLL_STATE_IDLE是停止 , 只有当在不同状态间切换的时候才会执行 */@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {//如果数据没有加载,并且滑动状态是停止的,而且到达了最后一个item项if (!isLoading && lastItem == totalItemCount && scrollState == SCROLL_STATE_IDLE) {//显示加载更多footer.setVisibility(View.VISIBLE);Handler handler = new Handler();//模拟一个延迟两秒的刷新功能handler.postDelayed(new Runnable() {@Overridepublic void run() {if (listener != null) {//开始加载更多数据loadMoreData();//回调设置ListView的数据listener.onLoadData(data);//加载完成后操作什么loadComplete();}}}, 2000);}}/** * 当加载数据完成后,设置加载标志为false表示没有加载数据了 * 并且设置底部加载更多为隐藏 */private void loadComplete() {isLoading = false;footer.setVisibility(View.GONE);}/** * 开始加载更多新数据,这里每次只更新三条数据 */private void loadMoreData() {isLoading = true;Student stu = null;for (int i = 0; i < 3; i++) {stu = new Student();stu.setName("新名字" + i);stu.setSex("新性别" + i);data.add(stu);}}/** * 监听可见界面的情况 * * @param view ListView * @param firstVisibleItem 第一个可见的 item 的索引 * @param visibleItemCount 可以显示的 item的条数 * @param totalItemCount总共有多少个 item */@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {//当可见界面的第一个item + 当前界面多有可见的界面个数就可以得到最后一个item项了lastItem = firstVisibleItem + visibleItemCount;//总listView的item个数this.totalItemCount = totalItemCount;}//回调接口public interface OnloadDataListener {void onLoadData(List<Student> data);}}MyAdapter.java
public class MyAdapter extends MyBaseAdapter<Student> {public MyAdapter(List<Student> data) {super(data);}@Overridepublic void setData(ViewHolder holder, Student t) {holder.setText(R.id.mTv1, t.getName()).setText(R.id.mTv2, t.getSex());}}MyBaseAdapter.java
public abstract class MyBaseAdapter<T> extends BaseAdapter {protected List<T> data;public MyBaseAdapter(List<T> data){this.data = data;}@Overridepublic int getCount() {return data == null ? 0 : data.size();}@Overridepublic Object getItem(int position) {return data.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = ViewHolder.getHolder(convertView,parent,position, R.layout.list_item);setData(holder,data.get(position));return holder.getConvertView();}public abstract void setData(ViewHolder holder,T t);}ViewHolder.java
public class ViewHolder {private int position;private SparseArray<View> array;private View convertView;private Context context;private ViewHolder(ViewGroup parent, int position, int layout) {this.position = position;this.context = parent.getContext();convertView = LayoutInflater.from(parent.getContext()).inflate(layout, null);convertView.setTag(this);array = new SparseArray<>();}public static ViewHolder getHolder(View convertView, ViewGroup parent, int position, int layout) {if (convertView == null) {return new ViewHolder(parent, position, layout);} else {ViewHolder holder = (ViewHolder) convertView.getTag();holder.position = position;return holder;}}public <T extends View> T getView(int viewId) {View view = array.get(viewId);if (view == null) {view = convertView.findViewById(viewId);array.put(viewId, view);}return (T) view;}public View getConvertView() {return convertView;}public ViewHolder setText(int viewId, String data) {TextView tv = getView(viewId);tv.setText(data);return this;}Student.java
public class Student {private String name;private String sex;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}除了MyAdapter.java MyBaseAdapter.java ViewHolder.java 以及 Student.java实体类没有注解,其他两个主要实现类都已经注释了,关于自定义通用适配器的讲解,本篇不做讲解,如果想了解如何实现自定义通用适配器知识的可以查看:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。