zoukankan      html  css  js  c++  java
  • 使用谷歌提供的SwipeRefreshLayout下拉控件,并自定义实现下拉加载的功能

    package com.loaderman.swiperefreshdemo;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.widget.SwipeRefreshLayout;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.loaderman.swiperefreshdemo.view.SwipeRefreshView;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    
    /**
     * 使用谷歌提供的SwipeRefreshLayout下拉控件进行下拉刷新
     */
    public class MainActivity extends AppCompatActivity {
        private List<String> mList;
        private int mCount;
        private StringAdapter mAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            final SwipeRefreshView swipeRefreshView = (SwipeRefreshView) findViewById(R.id.srl);
            ListView listView = (ListView) findViewById(R.id.lv);
    
            // 设置适配器数据
            mList = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                mList.add("我是天才" + i + "号");
                mCount++;
            }
            mAdapter = new StringAdapter();
            listView.setAdapter(mAdapter);
    
    
            // 不能在onCreate中设置,这个表示当前是刷新状态,如果一进来就是刷新状态,SwipeRefreshLayout会屏蔽掉下拉事件
            //swipeRefreshLayout.setRefreshing(true);
    
            // 设置颜色属性的时候一定要注意是引用了资源文件还是直接设置16进制的颜色,因为都是int值容易搞混
            // 设置下拉进度的背景颜色,默认就是白色的
            swipeRefreshView.setProgressBackgroundColorSchemeResource(android.R.color.white);
            // 设置下拉进度的主题颜色
            swipeRefreshView.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark);
    
            // 下拉时触发SwipeRefreshLayout的下拉动画,动画完毕之后就会回调这个方法
            swipeRefreshView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
    
                    // 开始刷新,设置当前为刷新状态
                    //swipeRefreshLayout.setRefreshing(true);
    
                    // 这里是主线程
                    // 一些比较耗时的操作,比如联网获取数据,需要放到子线程去执行
                    // TODO 获取数据
                    final Random random = new Random();
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mList.add(0, "我是天才" + random.nextInt(100) + "号");
                            mAdapter.notifyDataSetChanged();
    
                            Toast.makeText(MainActivity.this, "刷新了一条数据", Toast.LENGTH_SHORT).show();
    
                            // 加载完数据设置为不刷新状态,将下拉进度收起来
                            swipeRefreshView.setRefreshing(false);
                        }
                    }, 1200);
    
                    // System.out.println(Thread.currentThread().getName());
    
                    // 这个不能写在外边,不然会直接收起来
                    //swipeRefreshLayout.setRefreshing(false);
                }
            });
    
    
            // 设置下拉加载更多
            swipeRefreshView.setOnLoadListener(new SwipeRefreshView.OnLoadListener() {
                @Override
                public void onLoad() {
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
    
                            // 添加数据
                            for (int i = 30; i < 35; i++) {
                                mList.add("我是天才" + i+ "号");
                                // 这里要放在里面刷新,放在外面会导致刷新的进度条卡住
                                mAdapter.notifyDataSetChanged();
                            }
    
                            Toast.makeText(MainActivity.this, "加载了" + 5 + "条数据", Toast.LENGTH_SHORT).show();
    
                            // 加载完数据设置为不加载状态,将加载进度收起来
                            swipeRefreshView.setLoading(false);
                        }
                    }, 1200);
                }
            });
    
    
        }
    
    
        /**
         * 适配器
         */
        private class StringAdapter extends BaseAdapter {
    
            @Override
            public int getCount() {
                return mList.size();
            }
    
            @Override
            public Object getItem(int position) {
                return mList.get(position);
            }
            @Override
            public long getItemId(int position) {
                return position;
            }
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView == null) {
                    convertView = View.inflate(MainActivity.this, android.R.layout.simple_list_item_1, null);
                }
                TextView tv = (TextView) convertView;
                tv.setGravity(Gravity.CENTER);
                tv.setPadding(0, 20, 0, 20);
                tv.setText(mList.get(position));
    
                return convertView;
            }
        }
    }
    
    package com.loaderman.swiperefreshdemo.view;
    
    import android.content.Context;
    import android.support.v4.widget.SwipeRefreshLayout;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.widget.AbsListView;
    import android.widget.ListView;
    import com.loaderman.swiperefreshdemo.R;
    
    /**
     * 自定义View继承SwipeRefreshLayout,添加上拉加载更多的布局属性
     * Created by Pinger on 2016/9/26.
     */
    
    public class SwipeRefreshView extends SwipeRefreshLayout {
    
        private final int mScaledTouchSlop;
        private final View mFooterView;
        private ListView mListView;
        private OnLoadListener mOnLoadListener;
        /**
         * 正在加载状态
         */
        private boolean isLoading;
        public SwipeRefreshView(Context context, AttributeSet attrs) {
            super(context, attrs);
            // 填充底部加载布局
            mFooterView = View.inflate(context, R.layout.view_footer, null);
            // 表示控件移动的最小距离,手移动的距离大于这个距离才能拖动控件
            mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
            System.out.println("====" + mScaledTouchSlop);
        }
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            // 获取ListView,设置ListView的布局位置
            if (mListView == null) {
                // 判断容器有多少个孩子
                if (getChildCount() > 0) {
                    // 判断第一个孩子是不是ListView
                    if (getChildAt(0) instanceof ListView) {
                        // 创建ListView对象
                        mListView = (ListView) getChildAt(0);
    
                        // 设置ListView的滑动监听
                        setListViewOnScroll();
                    }
                }
            }
        }
        /**
         * 在分发事件的时候处理子控件的触摸事件
         *
         * @param ev
         * @return
         */
        private float mDownY, mUpY;
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 移动的起点
                    mDownY = ev.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    // 移动过程中判断时候能下拉加载更多
                    if (canLoadMore()) {
                        // 加载数据
                        loadData();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    // 移动的终点
                    mUpY = getY();
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }
        /**
         * 判断是否满足加载更多条件
         *
         * @return
         */
        private boolean canLoadMore() {
            // 1. 是上拉状态
            boolean condition1 = (mDownY - mUpY) >= mScaledTouchSlop;
            if (condition1) {
                System.out.println("是上拉状态");
            }
    
            // 2. 当前页面可见的item是最后一个条目
            boolean condition2 = false;
            if (mListView != null && mListView.getAdapter() != null) {
                condition2 = mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() - 1);
            }
    
            if (condition2) {
                System.out.println("是最后一个条目");
            }
            // 3. 正在加载状态
            boolean condition3 = !isLoading;
            if (condition3) {
                System.out.println("不是正在加载状态");
            }
            return condition1 && condition2 && condition3;
        }
        /**
         * 处理加载数据的逻辑
         */
        private void loadData() {
            System.out.println("加载数据...");
            if (mOnLoadListener != null) {
                // 设置加载状态,让布局显示出来
                setLoading(true);
                mOnLoadListener.onLoad();
            }
    
        }
    
        /**
         * 设置加载状态,是否加载传入boolean值进行判断
         *
         * @param loading
         */
        public void setLoading(boolean loading) {
            // 修改当前的状态
            isLoading = loading;
            if (isLoading) {
                // 显示布局
                mListView.addFooterView(mFooterView);
            } else {
                // 隐藏布局
               // mListView.removeFooterView(mFooterView);
                // 重置滑动的坐标
                mDownY = 0;
                mUpY = 0;
            }
        }
    
        /**
         * 设置ListView的滑动监听
         */
        private void setListViewOnScroll() {
    
            mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    // 移动过程中判断时候能下拉加载更多
                    if (canLoadMore()) {
                        // 加载数据
                        loadData();
                    }
                }
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                }
            });
        }
    
        /**
         * 上拉加载的接口回调
         */
        public interface OnLoadListener {
            void onLoad();
        }
        public void setOnLoadListener(OnLoadListener listener) {
            this.mOnLoadListener = listener;
        }
    }
    

     activity_main.xml

    <?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:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.pinger.swiperefreshdemo.MainActivity">
        <!--使用谷歌官方的下拉刷新组件,只有下拉刷新功能-->
    <!--
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/srl"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ListView
                android:id="@+id/lv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </android.support.v4.widget.SwipeRefreshLayout>
    -->
    
    
        <!--自定义View实现SwipeRefreshLayout,添加上拉加载更多的功能-->
        <com.loaderman.swiperefreshdemo.view.SwipeRefreshView
            android:id="@+id/srl"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ListView
                android:id="@+id/lv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </com.loaderman.swiperefreshdemo.view.SwipeRefreshView>
    </RelativeLayout>
    

     view-footer.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">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="50dp">
            <ProgressBar
                android:id="@+id/load_progress"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="30dp"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="正在努力加载中..."
                android:textColor="@android:color/holo_red_dark"
                android:textSize="16sp"/>
        </RelativeLayout>
    </RelativeLayout>
    

     效果图:

  • 相关阅读:
    JavaScript 为字符串添加样式 【每日一段代码80】
    JavaScript replace()方法 【每日一段代码83】
    JavaScript for in 遍历数组 【每日一段代码89】
    JavaScript 创建用于对象的模板【每日一段代码78】
    html5 css3 新元素简单页面布局
    JavaScript Array() 数组 【每日一段代码88】
    JavaScript toUTCString() 方法 【每日一段代码86】
    位运算
    POJ 3259 Wormholes
    POJ 3169 Layout
  • 原文地址:https://www.cnblogs.com/loaderman/p/6492514.html
Copyright © 2011-2022 走看看