您的位置:首页 > 移动开发 > Android开发

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

2016-03-01 23:20 471 查看
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"};

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: