想把網(wǎng)頁(yè)上的一些效果改成Android上的领迈,就遇到一個(gè)列表的上拉加載和下拉刷新推掸,Android只提供了下拉加載更多SwipeRefreshLayout,但是沒(méi)有直接的下拉加載更多,很頭痛,搜索了下教程豹爹,然后自己思考了下,摸索出一個(gè)相對(duì)簡(jiǎn)單的方法矛纹,(比較簡(jiǎn)陋臂聋,沒(méi)有什么動(dòng)畫,我不會(huì)啊或南。孩等。。采够。)
使用的是RecyclerView+SwiperRefreshLayout,recyclerView具體怎么使用就不用詳細(xì)介紹了
1.上拉刷新:
我直接使用了SwiperRefreshLayout,相對(duì)比較簡(jiǎn)單吧
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:id="@+id/refresh"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/list"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>
SwiperRefreshLayout需要設(shè)置onRefreshListener: setOnRefreshListener 在onRefresh中設(shè)置刷新的操作肄方,另外需要setRefreshing(false); 不然刷新的圖標(biāo)一直都在
2、下拉加載更多:
由于recyclerview沒(méi)有addfooterview 所以我們要自己添加:
在adapter中
@Override
public int getItemCount() {
return mList.size()+1;
}
需要在原有的長(zhǎng)度上+1蹬癌,來(lái)存放下拉加載更多的view
@Override
public int getItemViewType(int position) {
return position==mList.size()?1:0;
}
然后再 getItemViewType方法中設(shè)置viewType 用來(lái)區(qū)分不同的View
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=null;
if(viewType==0){
view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
}else {
view= LayoutInflater.from(parent.getContext()).inflate(R.layout.load,parent,false);
}
view.setTag(viewType);
return new ViewHolder(view);
}
接著在onCreateViewHolder 方法中 區(qū)分viewType 用不同的View
然后運(yùn)行权她,出現(xiàn)了底部的加載更多,但是現(xiàn)在還沒(méi)有效果(原諒我沒(méi)有圖 逝薪,真的不好傳隅要,照這種換個(gè)方法應(yīng)該能看到吧。董济。步清。)
接下來(lái)就是最重要的加載更多的功能了
重寫 OnScrollListener 來(lái)監(jiān)聽(tīng)滑動(dòng)事件
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
官方介紹:
/**
* Callback method to be invoked when RecyclerView's scroll state changes.
*
* @param recyclerView The RecyclerView whose scroll state has changed.
* @param newState The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
* {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
*/
說(shuō)明:onScrollStateChanged:當(dāng)recyclerview滑動(dòng)狀態(tài)改變時(shí)調(diào)用 有暗中狀態(tài)
SCROLL_STATE_IDLE:滑動(dòng)停止時(shí)
SCROLL_STATE_DRAGGING:觸摸拖動(dòng)時(shí)
SCROLL_STATE_SETTLING:拖動(dòng)到最后,不受外界影響
onScrolled:recyclerview滑動(dòng)時(shí) 調(diào)用的方法
問(wèn)題的關(guān)鍵:需要在recyclerview滑動(dòng)到最后一個(gè)視圖的時(shí)候 調(diào)用加載更多的方法
拆分問(wèn)題:
什么時(shí)候算是滑到底部虏肾?
那么必須使用onScrolled方法 廓啊,layoutManager中有一個(gè)方法findLastVisibleItemPosition()
可以找到屏幕最后一個(gè)顯示的itemview,返回的是它的位置
(layoutManager 是 mRecyclerView.setLayoutManager(layoutManager); 這里的layoutManager,我已開(kāi)始默認(rèn)使用了LinearLayoutManager)
那么就是當(dāng)findLastVisibleItemPosition==(adapter.getItemCount()-1)(position從0開(kāi)始)
的時(shí)候询微,就可以操作了 但是并不是最后一個(gè)加載更多的視圖出來(lái)崖瞭,我們就可以刷新了,你會(huì)發(fā)現(xiàn)有很多app都是可以選擇的撑毛,比如我在滑動(dòng)時(shí)會(huì)提示我松手加載更多之類书聚,喲普寫也是當(dāng)你滑動(dòng)是字會(huì)發(fā)生來(lái)提示你刷新,所以我選擇的是 當(dāng)最后一個(gè)itemView 上啦超過(guò)80px的時(shí)候藻雌,現(xiàn)在是可以加載更多的狀態(tài) 但是 他需要松手停止滑動(dòng)后才可以雌续,當(dāng)他超過(guò)80px后,又向上滑回去了胯杭,那么就不執(zhí)行加載更多的操作:
這是我重寫的方法:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(layoutManager.findLastVisibleItemPosition()==mRefreshAdapter.getItemCount()-1){
View view1=layoutManager.findViewByPosition(mRefreshAdapter.getItemCount()-1);
TextView textView=view1.findViewById(R.id.text);
if(recyclerView.getHeight()-view1.getTop()>80){
//當(dāng)超過(guò)80的時(shí)候 設(shè)置isRefresh=true驯杜,代表可以松手后滑動(dòng)刷新了
textView.setText("正在加載內(nèi)容");
isRefresh=true;
}else {
//如果這個(gè)時(shí)候又向上滑 導(dǎo)致 最后一個(gè)itemview露出的部分小于80做个,那么就不可以滑動(dòng)了
textView.setText("上拉加載更多");
isRefresh=false;
}
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//加載更多的操作顽频,當(dāng)滑動(dòng)停止又可以刷新的時(shí)候 我們使用 loadMore()加載新數(shù)據(jù)
if((newState==RecyclerView.SCROLL_STATE_IDLE) && isRefresh){
//首先緩慢平移到 可以添加動(dòng)畫 有一個(gè)回單效果
recyclerView.smoothScrollBy(0,-200);
loadMore();
isRefresh=false;
}
}
接著又遇到了一個(gè)更加嚴(yán)重的問(wèn)題,如果使用的是GridLayoutManager呢最住,每行兩個(gè),那么這個(gè)怎么獨(dú)占一行仗岖?還有可不可以使用同樣的方法來(lái)做下拉刷險(xiǎn)轧拄,就不需要用SwipeRefreshLayout府树,并且還可以封裝成一個(gè)獨(dú)立的VIew
下次更新卓箫,睡覺(jué)了,困