依靠SwipeRefreshLayout实现android
1.在xml文件中,使用SwipeRefreshLayout布局包裹bash
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/srl_base"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_base"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
复制代码
2.设置刷新的回调ide
mSwpBase.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//具体的刷新逻辑
onFresh();
}
});
复制代码
3.刷新结束后,将刷新状态置为false布局
mSwpBase.setRefreshing(false);
复制代码
4.其余动画
//设置进度圈的背景色。
setProgressBackgroundColor(int colorRes);ui
//设置进度动画的颜色。
setColorSchemeResources(int… colorResIds);spa
//设置进度圈的大小,只有两个值:DEFAULT、LARGE)
setSize(int size);code
1.使用自带的addOnScrollListener监听 添加:cdn
rcBase.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//滑动状态改变调用
onAdd(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
复制代码
2.在onAdd方法中判断是否加载到最后一个xml
public void onAdd(RecyclerView recyclerView, int newState){
if (newState == RecyclerView.SCROLL_STATE_IDLE && mManager.findLastVisibleItemPosition() == mAdapter.getItemCount()) {
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(2000);
list.addAll(list);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
Toast.makeText(getActivity(), "加载完成", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
}
复制代码
其中:
RecyclerView.SCROLL_STATE_IDLE :判断手指是否离开屏幕
mManager.findLastVisibleItemPosition() :是不是最后一个(为LinearLayoutManager中方法,GridLayoutManager 继承 LinearLayoutManager)
与不含footiew上拉加载相似,但多了footview,在处理时要加些判断。
RecyclerView没有相似listview的addfootview的方法,可是在adapter中有getItemViewType方法,那么咱们就能够根据position的不一样,让holder在建立的时候建立不一样的holder
1.在adapter中重写getItemViewType方法:
@Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
复制代码
其中:
position+1:添加了footview数量加1
一样的在getItemCount中return的list.size()+1
//普通Item View
private static final int TYPE_ITEM = 0;
//底部FootView
private static final int TYPE_FOOTER = 1;
2.在ViewHolder的基础上,在new一个FootHolder
class FootHolder extends RecyclerView.ViewHolder {
private final TextView tvFt;
public FootHolder(View itemView) {
super(itemView);
tvFt = (TextView) itemView.findViewById(R.id.tv_ft);
}
}
复制代码
注:因为有两个ViewHolder在继承的RecyclerView.Adapter的泛型里面须要改为公共父类RecyclerView.ViewHolder
3.在onCreateViewHolder中根据viewType建立不一样的view,并返回不一样的holder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == TYPE_ITEM) {
view = getActivity().getLayoutInflater().inflate(R.layout.fragment_video, parent, false);
return new VideoHolder(view);
} else if (viewType == TYPE_FOOTER) {
view = getActivity().getLayoutInflater().inflate(R.layout.foot_view, parent, false);
return new FootHolder(view);
}
return null;
}
复制代码
4.在onBindViewHoder中根据holder的类型加载不用的逻辑
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof VideoHolder) {
VideoBean videoBean = list.get(position);
VideoHolder videoHolder = (VideoHolder) holder;
videoHolder.fbVideo.setImageURI(videoBean.getImg());
videoHolder.tvTitle.setText(videoBean.getTitle());
//把数据当tag传到view中,写一个listener就能够了
videoHolder.llVideo.setTag(videoBean);
videoHolder.llVideo.setOnClickListener(mListerner);
} else if (holder instanceof FootHolder) {
FootHolder footHolder = (FootHolder) holder;
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footHolder.tvFt.setText("上拉加载更多");
break;
case LOADING_MORE:
footHolder.tvFt.setText("正在加载更多");
break;
}
}
}
复制代码
使用instance判断,而后强转holder类
//上拉加载更多
public static final int PULLUP_LOAD_MORE = 0;
//正在加载中
public static final int LOADING_MORE = 1;
//上拉加载更多状态-默认为0
private int load_more_status = 0;
5.onScrollStateChanged修改
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
load_more_status = LOADING_MORE;
if (newState == RecyclerView.SCROLL_STATE_IDLE && getCount() + 1 == mAdapter.getItemCount()) {
new Thread(new Runnable() {
@Override
public void run() {
load_more_status = PULLUP_LOAD_MORE;
SystemClock.sleep(2000);
list.addAll(list);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
Toast.makeText(getActivity(), "加载完成", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
}
复制代码
1.当GridLayoutManager添加footview时会形成布局错乱:
缘由:
GridLayoutManager manager = new GridLayoutManager(getActivity(), 3);
在咱们new GridLayoutManager的时候,传进去的3
至关于把一行分红了3份,一个items默认占1份,也就是一行3个,你的footview也占1份,因此不会居中。
知道了缘由,改也就好改了
介绍咱们关键的类:public static abstract class SpanSizeLookup (GridLayoutManager包下)
继承后会重写 getSpanSize方法 默认返回1,也就是一个布局占1份
class GridSpanSizeLookop extends GridLayoutManager.SpanSizeLookup {
@Override
public int getSpanSize(int position) {
return 1;
}
}
复制代码
那么,在这个方法里面咱们就能够判断,当是footview的时候,返回一行就能够解决问题了。
修改getSpanSize方法的返回值
class GridSpanSizeLookop extends GridLayoutManager.SpanSizeLookup {
@Override
public int getSpanSize(int position) {
// Log.d(TAG, position + "xx" + list.size() + 1);
if (position == list.size()) {
return mManager.getSpanCount();
}
return 1;
}
}
复制代码
最后在adapter中重写onAttachedToRecyclerView方法:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
if (mGridSpanSizeLookup == null) {
mGridSpanSizeLookup = new GridSpanSizeLookop();
}
mManager.setSpanSizeLookup(mGridSpanSizeLookup);
}
复制代码
另外,也能够在new GridLayoutManager之后这么写:
mManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position == list.size() ? mManager.getSpanCount() : 1;
}
});
复制代码
2.getSpanSize方法的其余用法:
经过更改返回值实现下面的布局
代码:
mManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position == list.size() ? mManager.getSpanCount() : 3 - position % 3;
}
});
复制代码
3.流式布局处理 因为StaggeredGridLayoutManager中没有setSpanSizeLookup方法,没法经过上述办法实现上拉加载,可是StaggeredGridLayoutManager.LayoutParams中有setFullSpan方法能够达到一样的效果。
这时候重写的再也不是onAttachedToRecyclerView方法而是onViewAttachedToWindow方法
//将上拉加载的布局添加到正中间
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if (layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
//是不是最后一个
if (holder.getLayoutPosition() == list.size()) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
p.setFullSpan(true);
//能够上拉加载
mIsFresh = true;
}
}
}
复制代码