ptrFrameLayout实现炫酷的下拉刷新、上拉加载

本文介绍了如何使用ptrFrameLayout在Android中实现炫酷的下拉刷新和上拉加载效果。通过PtrClassicFrameLayout和PtrFrameLayout配合不同头部组件,展示了几种不同的刷新动画,包括经典、材料、店家和点阵效果。同时,还展示了ptrFrameLayout与RecyclerView结合使用,实现线性、网格和瀑布流布局的刷新和加载功能。
摘要由CSDN通过智能技术生成
compile 'com.chanven.lib:cptr:1.1.0'
//http://blog.csdn.net/evan_man/article/details/51570466


Header三种:经典(刷新加载)、材料(动画、或变色、或滚动)、店家(用点绘制的字,连续闪光)
github

这一类框架,对于任何内部子控件都可以刷新
效果一,经典效果:
PtrClassicFrameLayout继承于PtrFrameLayout,它是有动画效果的刷新类

<com.chanven.lib.cptr.PtrClassicFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main_ptrClassicFrameLayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:ptr_resistance="1.7"
app:ptr_ratio_of_header_height_to_refresh="1.2"
app:ptr_duration_to_close="300"
app:ptr_duration_to_close_header="2000"
app:ptr_keep_header_when_refresh="true"
app:ptr_pull_to_fresh="false"
tools:context="test.zt.com.ptrdemo.MainActivity">

这种刷新布局自带头布局,所以可以直接设置下拉刷新监听

自动刷新方法,auto。。。,内部自动执行下面那个蓝色的部分

public class MainActivity extends AppCompatActivity {

TextView textView;
PtrClassicFrameLayout ptrFrameLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = ((TextView) findViewById(R.id.activity_main_textViewId));
//刷新布局
ptrFrameLayout = ((PtrClassicFrameLayout) findViewById(R.id.activity_main_ptrClassicFrameLayoutId));

ptrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
//执行调用下拉刷新监听
ptrFrameLayout.autoRefresh(true);
}
},200);

//设置下拉刷新监听
ptrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
@Override
public void onRefreshBegin(final PtrFrameLayout frame) {
//清空数据源
textView.setText("");
//加载网络数据
frame.postDelayed(new Runnable() {
@Override
public void run() {
loadData();
//刷新完成隐藏刷新进度
frame.refreshComplete();
}
},2000);
}
});
}

private void loadData() {
textView.setText("MAIN1:"+System.currentTimeMillis());
}
}
效果二,也是经典效果,用PtrFL来做,比较基层的代码:
这种效果只能用PtrFrameLayout来做,不能用经典的,看图


布局文件中:注意已经是ptrFrameLayout了

<com.chanven.lib.cptr.PtrFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main2_ptrFrameLayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:ptr_resistance="1.7"
app:ptr_ratio_of_header_height_to_refresh="1.2"
app:ptr_duration_to_close="300"
app:ptr_duration_to_close_header="2000"
app:ptr_keep_header_when_refresh="true"
app:ptr_pull_to_fresh="false"
tools:context="test.zt.com.ptrdemo.Main2Activity">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="30sp"
android:gravity="center"
android:id="@+id/activity_main2_textViewId"/>
</com.chanven.lib.cptr.PtrFrameLayout>

java代码:别忘了隐藏刷新进度frame.refreshComplete();

/**
*
* 采用PtrFrameLayout作为刷新布局
* 1.可添加的头部有3种
* 1.ClassicHeader
* 2.MaterialHeader
* 3.StoreHouseHeader
*/
public class Main2Activity extends AppCompatActivity {

TextView textView;
PtrFrameLayout ptrFrameLayout;

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

textView = ((TextView) findViewById(R.id.activity_main2_textViewId));
//刷新控件
ptrFrameLayout = ((PtrFrameLayout) findViewById(R.id.activity_main2_ptrFrameLayoutId));

PtrClassicDefaultHeader ptrUIHandler = new PtrClassicDefaultHeader(this);

//添加头部处理功能
ptrFrameLayout.addPtrUIHandler(ptrUIHandler);
//设置头部
ptrFrameLayout.setHeaderView(ptrUIHandler);
//设置自动刷新
ptrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
ptrFrameLayout.autoRefresh(true);
}
},200);

//设置下拉刷新监听
ptrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
@Override
public void onRefreshBegin(final PtrFrameLayout frame) {
textView.setText("");
frame.postDelayed(new Runnable() {
@Override
public void run() {
loadData();
//隐藏刷新进度
frame.refreshComplete();
}
},2000);
}
});


}

private void loadData() {
textView.setText("MAIN2"+System.currentTimeMillis());
}
}
效果三,材料效果:
只有这里变化了【其他部分仿照效果二,不能仿照效果一,详情看原理图】

给加个padding效果会好些

效果四,店家效果:
只有这里变化了【其他部分仿照效果二,不能仿照效果一,详情看原理图】
String里不能出现中文

效果五,点阵效果,可以自己画中文矩阵点放进去……:
区别效果四只有红圈变了

private ArrayList<float[]> getPointList() {
// this point is taken from https://github.com/cloay/CRefreshLayout
List<Point> startPoints = new ArrayList<Point>();
startPoints.add(new Point(240, 80));
startPoints.add(new Point(270, 80));
startPoints.add(new Point(265, 103));
startPoints.add(new Point(255, 65));
startPoints.add(new Point(275, 80));
startPoints.add(new Point(275, 80));
startPoints.add(new Point(302, 80));
startPoints.add(new Point(275, 107));

startPoints.add(new Point(320, 70));
startPoints.add(new Point(313, 80));
startPoints.add(new Point(330, 63));
startPoints.add(new Point(315, 87));
startPoints.add(new Point(330, 80));
startPoints.add(new Point(315, 100));
startPoints.add(new Point(330, 90));
startPoints.add(new Point(315, 110));
startPoints.add(new Point(345, 65));
startPoints.add(new Point(357, 67));
startPoints.add(new Point(363, 103));

startPoints.add(new Point(375, 80));
startPoints.add(new Point(375, 80));
startPoints.add(new Point(425, 80));
startPoints.add(new Point(380, 95));
startPoints.add(new Point(400, 63));

List<Point> endPoints = new ArrayList<Point>();
endPoints.add(new Point(270, 80));
endPoints.add(new Point(270, 110));
endPoints.add(new Point(270, 110));
endPoints.add(new Point(250, 110));
endPoints.add(new Point(275, 107));
endPoints.add(new Point(302, 80));
endPoints.add(new Point(302, 107));
endPoints.add(new Point(302, 107));

endPoints.add(new Point(340, 70));
endPoints.add(new Point(360, 80));
endPoints.add(new Point(330, 80));
endPoints.add(new Point(340, 87));
endPoints.add(new Point(315, 100));
endPoints.add(new Point(345, 98));
endPoints.add(new Point(330, 120));
endPoints.add(new Point(345, 108));
endPoints.add(new Point(360, 120));
endPoints.add(new Point(363, 75));
endPoints.add(new Point(345, 117));

endPoints.add(new Point(380, 95));
endPoints.add(new Point(425, 80));
endPoints.add(new Point(420, 95));
endPoints.add(new Point(420, 95));
endPoints.add(new Point(400, 120));
ArrayList<float[]> list = new ArrayList<float[]>();

int offsetX = Integer.MAX_VALUE;
int offsetY = Integer.MAX_VALUE;

for (int i = 0; i < startPoints.size(); i++) {
offsetX = Math.min(startPoints.get(i).x, offsetX);
offsetY = Math.min(startPoints.get(i).y, offsetY);
}
for (int i = 0; i < endPoints.size(); i++) {
float[] point = new float[4];
point[0] = startPoints.get(i).x - offsetX;
point[1] = startPoints.get(i).y - offsetY;
point[2] = endPoints.get(i).x - offsetX;
point[3] = endPoints.get(i).y - offsetY;
list.add(point);
}
return list;
}
效果六,图形效果,需要自己写String数组:



<resources>
<string name="app_name">PtrDemo</string>
<string-array name="storehouse">
<item>0,35,12,42,</item>
<item>12,42,24,35,</item>
<item>24,35,12,28,</item>
<item>0,35,12,28,</item>
<item>0,21,12,28,</item>
<item>12,28,24,21,</item>
<item>24,35,24,21,</item>
<item>24,21,12,14,</item>
<item>0,21,12,14,</item>
<item>0,21,0,7,</item>
<item>12,14,0,7,</item>
<item>12,14,24,7,</item>
<item>24,7,12,0,</item>
<item>0,7,12,0,</item>
</string-array>
</resources>

效果七,ptrFrameLayout和recyclerView结合:
可以从这设置,也可以从JAVA中设置。还是从JAVA设置吧、这定死了怎么复用。

<?xml version="1.0" encoding="utf-8"?>
<com.chanven.lib.cptr.PtrFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main7_ptrFrameLayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:ptr_resistance="1.7"
app:ptr_ratio_of_header_height_to_refresh="1.2"
app:ptr_duration_to_close="300"
app:ptr_duration_to_close_header="2000"
app:ptr_keep_header_when_refresh="true"
app:ptr_pull_to_fresh="false"
tools:context="test.zt.com.ptrdemo.Main7Activity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/activity_main7_recyclerViewId">
</android.support.v7.widget.RecyclerView>
</com.chanven.lib.cptr.PtrFrameLayout>
以下是ptrFrameLayout+RecyclerView实现线性、网格、瀑布布局的刷新和加载功能,炫酷又好用
其实质就是拉了ptrFrameLayout,将rv中的数据变动
下拉刷新的话用前面的方法就行,上拉加载:给rvAdapter加个尾视图
public class Main7Activity extends AppCompatActivity{

RecyclerView recyclerView;
PtrFrameLayout ptrFrameLayout;
RVAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main7);

recyclerView = ((RecyclerView) findViewById(R.id.activity_main7_recyclerViewId));
ptrFrameLayout = ((PtrFrameLayout) findViewById(R.id.activity_main7_ptrFrameLayoutId));
recyclerView.setLayoutManager(new GridLayoutManager(this,2));

adapter = new RVAdapter(this);
//注意:设置适配器的时候一定要套用这个布局,adapter适配器不要泛型
recyclerView.setAdapter(new RecyclerAdapterWithHF(adapter){
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if(layoutManager instanceof GridLayoutManager){
final GridLayoutManager gridLayoutManager = (GridLayoutManager)layoutManager;
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if(position == adapter.getItemCount())
return gridLayoutManager.getSpanCount();
return 1;
}
});
}
}
});
// recyclerView.setLayoutManager(new StaggeredGridLayoutManager(StaggeredGridLayoutManager.VERTICAL,2));
//
// adapter = new RVAdapter(this);
// //注意:设置适配器的时候一定要套用这个布局,adapter适配器不要泛型
// recyclerView.setAdapter(new RecyclerAdapterWithHF(adapter){
// /**
// * 对StaggeredGridLayoutManager的处理
// * @param holder
// */
// @Override
// public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
// super.onViewAttachedToWindow(holder);
// ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
// if(layoutParams!=null&& layoutParams instanceof StaggeredGridLayoutManager.LayoutParams ){
// StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) layoutParams;
// int position = holder.getLayoutPosition();
// if(position == adapter.getItemCount())
// {
// lp.setFullSpan(true);
// }
// }
// holder.itemView.setLayoutParams(layoutParams);
// }
// });

final StoreHouseHeader ptrUIHandler = new StoreHouseHeader(this);

ptrUIHandler.initWithString("wang sheng");

ptrUIHandler.setPadding(40,40,40,40);

//添加头部ui处理功能
ptrFrameLayout.addPtrUIHandler(ptrUIHandler);
//设置头布局
ptrFrameLayout.setHeaderView(ptrUIHandler);


ptrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
ptrFrameLayout.autoRefresh(true);
}
},200);

//设置下拉刷新监听
ptrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
@Override
public void onRefreshBegin(final PtrFrameLayout frame) {
//清空数据源
adapter.clear();
//加载新数据
frame.postDelayed(new Runnable() {
@Override
public void run() {
loadData();
//隐藏刷新进度
frame.refreshComplete();
//激活加载更多
frame.setLoadMoreEnable(true);
}
},2000);
}
});

ptrFrameLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void loadMore() {
ptrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
loadData();
//已经加载完成
ptrFrameLayout.loadMoreComplete(true);
}
},2000);
}
});

loadData();
}

private void loadData() {
ArrayList<String> dd = new ArrayList<>();
for (int i = 0; i < 20; i++) {
dd.add("item:"+i);
}
adapter.addAll(dd);
}
}
adapter这样子
public class RVAdapter extends RecyclerView.Adapter {
private LayoutInflater inflater;
private List<String> datas;

public RVAdapter(Context context) {
this.inflater = LayoutInflater.from(context);
datas = new ArrayList<>();
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_rv,parent,false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewHolder)holder).textView.setText(datas.get(position));
}


@Override
public int getItemCount() {
return datas.size();
}

public void addAll(List<String> dd) {
datas.addAll(dd);
notifyDataSetChanged();
}

public void clear() {
datas.clear();
notifyDataSetChanged();
}


class ViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = ((TextView) itemView.findViewById(R.id.item_rv_textViewId));
}
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值