4.5.3 Go Android 下拉刷新的整理:SwipeRefreshLayout,android-Ultra-Pull-To-Refresh(ptr),PullToRefreshListView

1: 使用SwipeRefreshLayout 来实现下拉刷新和上拉加载, 和RecyclerView 来实现


http://blog.csdn.net/Rodulf/article/details/50514742


首先获取mSwipeRefreshLayout =(SwipeRefreshLayout)ret.findViewById(R.id.leibie_swiperefreshlayout);
然后可以设置这个SwipeRefreshLayout
mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE, Color.CYAN);
        mSwipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);


下拉刷新可以直接通过onRefresh 来执行。
然后在回调方法里面执行请求:
    @Override
    public void onRefresh() {
        HttpUtils.getLeiBieService().getLeiBie(1446).enqueue(this);
    }
}


上拉加载的实现是通过:例如这里是RecyclerView,设置一个监听器,在这里面有两个方法onScrolled,onScrollStateChanged
里面设置一个全局变量lastVisisbleItem,这个值在每次的onScrolled 里面修改,在最后的onScrollStateChanged里面 判断状态是否为SCROLL_STATE_IDEL
就是滑动结束,如果是的话,在判断这个lastViewItem是否到底了,到底了就进行加载的操作。


mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {  
  
   @Override  
   public void onScrollStateChanged(RecyclerView recyclerView,  
     int newState) {  
    super.onScrollStateChanged(recyclerView, newState);  
    if (newState == RecyclerView.SCROLL_STATE_IDLE  
      && lastVisibleItem + 1 == adapter.getItemCount()) {  
     mSwipeRefreshWidget.setRefreshing(true);  
     // 此处在现实项目中,请换成网络请求数据代码,sendRequest .....  
     handler.sendEmptyMessageDelayed(0, 3000);  
    }  
   }
  


   @Override  
   public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
    super.onScrolled(recyclerView, dx, dy);  
    lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();  
   }  
  
  });  


我之前的 代码:
mouge_lei_bie_detail_recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
            /**
             * 在这个方法里面判断当前状态是不是SCROLL_STATE_IDLE,并且 最后一个可见的Item也就是lastVisibleItem
             * 是倒数第二个 数据 ,如果两个条件都满足,那么进行上拉加载的操作,就是发送一个 新的handle的消息。
             * 这个消息的what是ADD
             */
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==adapter.getItemCount()){
                        Message message = new Message();
                        message.what=ADD;
                        handler.sendMessage(message);
                }
            }


            /**
             * 通过recyclerView_layoutManager,这个recyclerView_layoutManager是通过下面的两句话来设置的
             * recyclerView_layoutManager = new LinearLayoutManager(this);
             * mouge_lei_bie_detail_recyclerView.setLayoutManager(recyclerView_layoutManager);
             * 得到最后一个可见的item的位置,并且把这个传递给变量lastVisibleItem ,
             */
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                lastVisibleItem = recyclerView_layoutManager.findLastVisibleItemPosition();
            }
        });




关于 state 还有 2中状态:
SCROLL_STATE_TOUCH_SCROLL:  // 手指触屏拉动准备滚动,只触发一次        
        SCROLL_STATE_FLING:  // 持续滚动开始,只触发一次 
        SCROLL_STATE_IDLE:  // 整个滚动事件结束,只触发一次 






2: 使用PullToRefresh 来实现下拉刷新,上拉加载,里面可以添加一个Header
http://blog.csdn.net/rodulf/article/details/50766369
首先将这个包导入为model。
<com.handmark.pulltorefresh.library.PullToRefreshListView  
        xmlns:ptr = "http://schemas.android.com/apk/res-auto"   
        android:id="@+id/pull_refresh_list"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:dividerHeight="4dp"  
        android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrMode="both"  
         />  
在布局里面要设置几个参数,最重要的是要设置这个ptrMode 为Both,ptr:ptrMode="both" 
android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrMode="both" 


然后在activity 中获取这个PullToRefreshListView
通过 setOnRefreshListener 来添加 监听器。 监听器里面有两个方法:onPullDownToRefresh,onPullUpToRefresh


mPullRefreshListView.setOnRefreshListener(new OnRefreshListener2<ListView>() {  
            @Override  
            public void onPullDownToRefresh( PullToRefreshBase<ListView> refreshView) {  
                Toast.makeText(MainActivity.this, "onPullDownToRefresh", Toast.LENGTH_SHORT).show();  
                new GetDataTask().execute();  
            }  
            @Override  
            public void onPullUpToRefresh( PullToRefreshBase<ListView> refreshView) {  
                Toast.makeText(MainActivity.this, "onPullUpToRefresh", Toast.LENGTH_SHORT).show();  
                new GetDataTask().execute();  
            }  
        });  


获取ListView,然后就是直接使用listview的添加adapter这些东西了。


ListView actualListView =mPullRefreshListView.getRefreshableView()
通过registerForContextMenu(actualListView)来注册上下文茶蛋
mListItems = new LinkedList<String>();
mListItems.addAll();
mAdapter= new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mListItems);
actualListView.setAdapter(mAdapter);




在 请求的里面进行添加:通过mAdapter.notifyDataSetChanged()来通知变化。


 protected void onPostExecute(String[] result) {  
              
            //向RefreshListView Item 添加一行数据  并刷新ListView  
            //mListItems.addLast("Added after refresh...");  
            mListItems.addFirst("Added after refresh...");  
            mAdapter.notifyDataSetChanged();  
  
            //通知RefreshListView 我们已经更新完成  
            // Call onRefreshComplete when the list has been refreshed.  
            mPullRefreshListView.onRefreshComplete();  
  
            super.onPostExecute(result);  
        }  


这里面可以通过,设置一个page 的全局变量,在进行数据请求的时候,
先判断这个变量,如果是1 的话,就进行重新的加载
如果是大于1的话就进行,添加的操作。




/** 
         *   设置下拉刷新和上拉加载时的 铃声(可有可无) 
         */  
        SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);  
        soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);  
        soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);  
        soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);  
        mPullRefreshListView.setOnPullEventListener(soundListener);  

<?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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <!--  xmlns:ptr = "http://schemas.android.com/apk/res-auto"  为我们要使用PullToRefresh 里面一些属性需要引的命名空间 -->
    <com.handmark.pulltorefresh.library.PullToRefreshListView
        xmlns:ptr = "http://schemas.android.com/apk/res-auto"
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="4dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="false"
        android:smoothScrollbar="true"
        ptr:ptrMode="both"
        />
</RelativeLayout>



package tech.androidstudio.pulltorefresh;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.extras.SoundPullEventListener;

import java.util.Arrays;
import java.util.LinkedList;

public class MainActivity extends AppCompatActivity {

    static final int MENU_MANUAL_REFRESH = 0;
    static final int MENU_DISABLE_SCROLL = 1;
    static final int MENU_SET_MODE = 2;
    static final int MENU_DEMO = 3;

    private LinkedList<String> mListItems;
    private PullToRefreshListView mPullRefreshListView;
    private ArrayAdapter<String> mAdapter;
    private int mPage=1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);

        /**
         * 实现 接口  OnRefreshListener2<ListView>  以便与监听  滚动条到顶部和到底部
         */
        mPullRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
            @Override
            public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
                Toast.makeText(MainActivity.this, "onPullDownToRefresh", Toast.LENGTH_SHORT).show();
                mPage=1;
                new GetDataTask().execute();
            }

            @Override
            public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
                Toast.makeText(MainActivity.this, "onPullUpToRefresh", Toast.LENGTH_SHORT).show();
                mPage++;
                new GetDataTask().execute();
            }
        });

        ListView actualListView = mPullRefreshListView.getRefreshableView();
        // Need to use the Actual ListView when registering for Context Menu
        registerForContextMenu(actualListView);

        mListItems = new LinkedList<String>();
        mListItems.addAll(Arrays.asList(mStrings));

        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);

        /**
         * Add Sound Event Listener
         */

        /**
         *   设置下拉刷新和上拉加载时的 铃声(可有可无)
         */
        SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
//        soundListener.addSoundEvent(PullToRefreshBase.State.PULL_TO_REFRESH, R.raw.pull_event);
//        soundListener.addSoundEvent(PullToRefreshBase.State.RESET, R.raw.reset_sound);
//        soundListener.addSoundEvent(PullToRefreshBase.State.REFRESHING, R.raw.refreshing_sound);
        mPullRefreshListView.setOnPullEventListener(soundListener);

        // You can also just use setListAdapter(mAdapter) or
        // mPullRefreshListView.setAdapter(mAdapter)
        actualListView.setAdapter(mAdapter);

    }
    //模拟网络加载数据的   异步请求类
    //
    private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        //子线程请求数据
        @Override
        protected String[] doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
            return mStrings;
        }

        //主线程更新UI
        @Override
        protected void onPostExecute(String[] result) {

            //RefreshListView Item 添加一行数据  并刷新ListView
            //mListItems.addLast("Added after refresh...");
            if(mPage==1){
                mListItems.clear();
                mListItems.addAll(Arrays.asList(mStrings));
            }else {
                mListItems.addFirst("Added after refresh...");
            }
            mAdapter.notifyDataSetChanged();

            //通知RefreshListView 我们已经更新完成
            // Call onRefreshComplete when the list has been refreshed.
            mPullRefreshListView.onRefreshComplete();

            super.onPostExecute(result);
        }
    }



    //数据源
    private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler" };
}





3: 使用Utrl-PullToRefresh 来实现下拉刷新,里面可以添加一个Header
https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh


首先 导入包:in.srain.cube:ultra-ptr:1.0.11
导入布局进去in.srain.cube.views.ptr.PtrFrameLayout


<in.srain.cube.views.ptr.PtrFrameLayout
    android:id="@+id/store_house_ptr_frame"
    xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"


    cube_ptr:ptr_resistance="1.7"
    cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
    cube_ptr:ptr_duration_to_close="300"
    cube_ptr:ptr_duration_to_close_header="2000"
    cube_ptr:ptr_keep_header_when_refresh="true"
    cube_ptr:ptr_pull_to_fresh="false" >


    <LinearLayout
        android:id="@+id/store_house_ptr_image_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/cube_mints_333333"
        android:clickable="true"
        android:padding="10dp">


        <in.srain.cube.image.CubeImageView
            android:id="@+id/store_house_ptr_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>


</in.srain.cube.views.ptr.PtrFrameLayout>




在 布局里面获取然后设置头部。


        final PtrFrameLayout ptrFrameLayout = (PtrFrameLayout)findViewById(R.id.store_house_ptr_frame);
        StoreHouseHeader header = new StoreHouseHeader(this);
        header.setPadding(0, 20, 0, 20);
        header.initWithString("Updating");


        ptrFrameLayout.setDurationToCloseHeader(2500);
        ptrFrameLayout.setHeaderView(header);
        ptrFrameLayout.addPtrUIHandler(header);




设置数据Handler:这里面有onRefreshBegin里面开始数据加载,
然后在checkCanDoRefresh里面判断是否进行刷新。


        ptrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
            }


            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                mPage=1;
                new GetDataTask().execute();


                ptrFrameLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        ptrFrameLayout.refreshComplete();
                    }
                }, 1500);
            }
        });


    }

完整的代码:


上拉加载和上面的一样只是在listView.setOnScrollListener(this);
注意了这里是setOnScrollListener(this),setOnScrollChangeListener(this);


@Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
            if(scrollState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE&&
                    view.getLastVisiblePosition()>=list.size()-1){
                mPage++;
                new GetDataTask().execute();
            }
    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            

    }


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <in.srain.cube.views.ptr.PtrFrameLayout
        android:id="@+id/store_house_ptr_frame"
        xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        cube_ptr:ptr_resistance="1.7"
        cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
        cube_ptr:ptr_duration_to_close="300"
        cube_ptr:ptr_duration_to_close_header="2000"
        cube_ptr:ptr_keep_header_when_refresh="true"
        cube_ptr:ptr_pull_to_fresh="false" >
        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/list_item"></ListView>

    </in.srain.cube.views.ptr.PtrFrameLayout>

</LinearLayout>

package tech.androidstudio.ultrapulltorefreshdemo;

import android.os.AsyncTask;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.Arrays;

import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.header.StoreHouseHeader;
import in.srain.cube.views.ptr.indicator.PtrIndicator;

public class MainActivity extends AppCompatActivity implements AbsListView.OnScrollListener {

    private ArrayList<String> list;
    private ArrayAdapter<String> adapter;
    private int mPage=1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView =(ListView)findViewById(android.support.v7.appcompat.R.id.list_item);
        list = new ArrayList<String>();

        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, list);
        listView.setAdapter(adapter);
        listView.setOnScrollListener(this);

        final PtrFrameLayout ptrFrameLayout = (PtrFrameLayout)findViewById(R.id.store_house_ptr_frame);
        StoreHouseHeader header = new StoreHouseHeader(this);
        header.setPadding(0, 20, 0, 20);
        header.initWithString("Updating");

        ptrFrameLayout.setDurationToCloseHeader(2500);
        ptrFrameLayout.setHeaderView(header);
        ptrFrameLayout.addPtrUIHandler(header);
        ptrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
            }

            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                mPage=1;
                new GetDataTask().execute();

                ptrFrameLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        ptrFrameLayout.refreshComplete();
                    }
                }, 1500);
            }
        });

    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
            if(scrollState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE&&
                    view.getLastVisiblePosition()>=list.size()-1){
                mPage++;
                new GetDataTask().execute();
            }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }


    //模拟网络加载数据的   异步请求类
    //
    private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        //子线程请求数据
        @Override
        protected String[] doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
            return new String[]{"hello"};
        }

        //主线程更新UI
        @Override
        protected void onPostExecute(String[] result) {
            if(mPage==1) {
                list.clear();
                list.addAll(Arrays.asList(array));
            }else{
                list.add("new");
            }
            adapter.notifyDataSetChanged();
            //RefreshListView Item 添加一行数据  并刷新ListView
            //mListItems.addLast("Added after refresh...");
            super.onPostExecute(result);
        }
    }

    private String[] array={"0","1","2","3","1","2","3","1","2","3","1","2","3","1","2","3","1","2","3"};

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值