zoukankan      html  css  js  c++  java
  • 一手遮天 Android

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

    一手遮天 Android - view(ListView): ListView 滚动到底部加载更多数据

    示例如下:

    /view/listview/ListViewDemo8.java

    /**
     * ListView 滚动到底部加载更多数据
     *
     * 自定义的用于支持滚动到底部加载更多数据的 ListView 的代码参见 ListViewDemo8LoadMoreListView.java
     */
    
    package com.webabcd.androiddemo.view.listview;
    
    import android.content.Context;
    import android.os.AsyncTask;
    import android.os.SystemClock;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.webabcd.androiddemo.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ListViewDemo8 extends AppCompatActivity {
    
        private ListViewDemo8LoadMoreListView _listView1;
    
        // 数据源
        private List<MyData> _myDataList = new ArrayList<MyData>();
        // BaseAdapter
        private MyAdapter _myAdapter;
        // 数据分页的页索引
        private int _pageIndex = 0;
        // 数据分页的页大小
        private int _pageSize = 20;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_view_listview_listviewdemo8);
    
            _listView1 = (ListViewDemo8LoadMoreListView) findViewById(R.id.listView1);
    
            sample();
        }
    
        private void sample() {
            // 异步加载数据
            new MyTask().execute(_pageIndex, _pageSize);
            _myAdapter = new MyAdapter(_myDataList, this);
            _listView1.setAdapter(_myAdapter);
            // 告知 ListView 有更多数据可供加载
            _listView1.setHasMoreItems(true);
    
            // 处理 ListView 的需要加载更多数据的事件
            _listView1.setOnLoadMoreListener(new ListViewDemo8LoadMoreListView.OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    _pageIndex++;
                    new MyTask().execute(_pageIndex, _pageSize);
                }
            });
        }
    
        // 异步加载数据
        private class MyTask extends AsyncTask<Integer, Void, List<MyData>> {
            @Override
            protected List<MyData> doInBackground(Integer... params) {
                SystemClock.sleep(1000);
    
                int pageIndex = params[0];
                int pageSize = params[1];
    
                List<MyData> result = new ArrayList<MyData>();
                for (int i = pageIndex * pageSize; i < pageIndex * pageSize + pageSize; i++) {
                    result.add(new MyData(R.drawable.img_sample_son, "name " + i, "comment " + i));
                }
                return result;
            }
    
            @Override
            protected void onPostExecute(List<MyData> result) {
                if (_pageIndex > 3) {
                    // 告知 ListView 没有更多数据可供加载了
                    _listView1.setHasMoreItems(false);
                }
    
                // 添加数据
                _myDataList.addAll(result);
                // 刷新 ListView
                _myAdapter.notifyDataSetChanged();
                // 告知 ListView 当前数据加载已经完成
                _listView1.loadComplete();
            }
        }
    
        // 自定义实体类
        class MyData {
            private int _logoId;
            private String _name;
            private String _comment;
    
            public MyData() {
            }
    
            public MyData(int logoId, String name, String comment) {
                this._logoId = logoId;
                this._name = name;
                this._comment = comment;
            }
    
            public int getLogoId() {
                return _logoId;
            }
    
            public String getName() {
                return _name;
            }
    
            public String getComment() {
                return _comment;
            }
    
            public void setLogoId(int logoId) {
                this._logoId = logoId;
            }
    
            public void setName(String name) {
                this._name = name;
            }
    
            public void setComment(String comment) {
                this._comment = comment;
            }
        }
    
        // 自定义 BaseAdapter
        class MyAdapter extends BaseAdapter {
    
            private List<MyData> _myDataList;
            private Context _context;
    
            public MyAdapter(List<MyData> myDataList, Context context) {
                this._myDataList = myDataList;
                this._context = context;
            }
    
            // 需要呈现的 item 的总数
            @Override
            public int getCount() {
                return _myDataList.size();
            }
    
            // 返回指定索引位置的 item 的对象
            @Override
            public Object getItem(int position) {
                return _myDataList.get(position);
            }
    
            // 返回指定索引位置的 item 的 id
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            // 每构造一个 item 就会调用一次 getView() 来获取这个 item 的 view
            // 每次绘制 item 都会调用 getView()
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder = null;
                if (convertView == null) {
                    convertView = LayoutInflater.from(_context).inflate(R.layout.item_view_listview_listviewdemo8, parent, false);
    
                    holder = new ViewHolder();
                    holder.imgLogo = (ImageView) convertView.findViewById(R.id.imgLogo);
                    holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
                    holder.txtComment = (TextView) convertView.findViewById(R.id.txtComment);
                    convertView.setTag(holder); // 将 holder 保存到 convertView 中
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
    
                holder.imgLogo.setBackgroundResource(_myDataList.get(position).getLogoId());
                holder.txtName.setText(_myDataList.get(position).getName());
                holder.txtComment.setText(_myDataList.get(position).getComment());
    
                return convertView;
            }
    
            class ViewHolder {
                ImageView imgLogo;
                TextView txtName;
                TextView txtComment;
            }
        }
    }
    
    

    viewlistviewListViewDemo8LoadMoreListView.java

    /**
     * 自定义一个 ListView 用于支持滚动到底部加载更多数据
     */
    
    package com.webabcd.androiddemo.view.listview;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.AbsListView;
    import android.widget.ListView;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import com.webabcd.androiddemo.R;
    
    public class ListViewDemo8LoadMoreListView extends ListView implements AbsListView.OnScrollListener {
        // 用于显示“正在加载框”的 view
        private View _rootView;
        // “正在加载框”的 loading
        private ProgressBar _progressBar;
        // “正在加载框”的文字提示
        private TextView _textView;
    
        // 是否还有更多数据可供加载
        private boolean _hasMoreItems = true;
        // 是否正在加载数据
        private boolean _isLoading = false;
    
        public ListViewDemo8LoadMoreListView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            _rootView = LayoutInflater.from(context).inflate(R.layout.item_view_listview_listviewdemo8_loadmore, null);
            _progressBar = (ProgressBar) _rootView.findViewById(R.id.progressBar);
            _textView = (TextView) _rootView.findViewById(R.id.textView);
    
            // 将“正在加载框”添加到 ListView 的 footer 中
            super.addFooterView(_rootView, null, false);
    
            // 监听 ListView 的滚动事件
            super.setOnScrollListener(this);
        }
    
        // 外部调用,用于告诉 ListView 是否还有更多数据可供加载
        public void setHasMoreItems(boolean hasMoreItems) {
            this._hasMoreItems = hasMoreItems;
    
            if (!hasMoreItems) {
                _textView.setText("没有更多数据了");
                _progressBar.setVisibility(View.GONE);
            } else {
                _textView.setText("正在加载");
                _progressBar.setVisibility(View.VISIBLE);
            }
        }
    
        // 外部调用,用于告诉 ListView 当前数据是否已经加载完成
        public void loadComplete() {
            _isLoading = false;
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                if (view.getLastVisiblePosition() == view.getCount() - 1 && !_isLoading && mOnLoadMoreListener != null && _hasMoreItems) {
                    _isLoading = true;
                    // 触发需要加载更多数据的事件
                    performLoadMore();
                }
            }
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    
        }
    
        // ListView 需要获取更多数据时的事件
        private OnLoadMoreListener mOnLoadMoreListener;
        public interface OnLoadMoreListener {
            void onLoadMore();
        }
        public void setOnLoadMoreListener(OnLoadMoreListener listener) {
            mOnLoadMoreListener = listener;
        }
        protected void performLoadMore() {
            if (mOnLoadMoreListener != null)
                mOnLoadMoreListener.onLoadMore();
        }
    }
    
    

    /layout/activity_view_listview_listviewdemo8.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">
    
        <!--
            com.webabcd.androiddemo.view.listview.ListViewDemo8LoadMoreListView - 自定义的用于支持滚动到底部加载更多数据的 ListView
        -->
        <com.webabcd.androiddemo.view.listview.ListViewDemo8LoadMoreListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    
    

    /layout/item_view_listview_listviewdemo8.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:paddingLeft="10dp"
        android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/imgLogo"
            android:layout_width="64dp"
            android:layout_height="64dp" />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/txtName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#1D1D1D"
                android:textSize="24sp" />
    
            <TextView
                android:id="@+id/txtComment"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#B4B4B4"
                android:textSize="14sp" />
    
        </LinearLayout>
    
    </LinearLayout>
    
    

    /layout/item_view_listview_listviewdemo8_loadmore.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="64dp"
        android:gravity="center"
        android:orientation="horizontal">
    
        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_gravity="center"
            android:layout_marginRight="10dp"
            android:indeterminateDrawable="@drawable/rotate_progressbar_indeterminate"
            android:indeterminateDuration="500"
            android:visibility="visible" />
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="正在加载"
            android:textColor="#999999" />
    
    </LinearLayout>
    
    

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

  • 相关阅读:
    初始化块:
    继承与组合:
    instanceof用法及本质:
    引用变量的强制类型转换:
    多态是如何产生的:
    program by the way......
    多层次继承,构造器之间的调用顺序!
    调用父类构造器:super
    子类覆写的变量被private隐藏,强制转换方式通过子类访问父类的被覆写变量:
    super限定,子类中系统查找变量的顺序:
  • 原文地址:https://www.cnblogs.com/webabcd/p/android_view_listview_ListViewDemo8.html
Copyright © 2011-2022 走看看