自定義RecyclerView新增HeaderView,新增FooterView,實現滑動到底部,載入更多
顯示效果圖
同步更新CSDN
http://blog.csdn.net/wuyinlei/article/details/52662960
PS
接觸過RecyclerView的應該會有個感覺,那就是我不想在使用ListView和GridView了,因為這個控制元件是可以實現那兩個控制元件(ListView和GridView)所實現的幾乎所有吧,哈哈我也沒用他們倆幹過多少的變種哈。所以在新專案中
自然也要使用這個RecyclerView來實現效果啊。
產品要求
頭部可以任意定義的,比如說Banner圖輪播,各種列表顯示,幾種分類,然後滑動到底部(RecyclerView)顯示載入更多提示,然後子執行緒請求資料,進行資料載入,更新UI,如果沒有資料,就給一個友好的使用者提示。
剛開始想法
因為這個看起來很好辦的,整個放到一個ScrollView裡面,這樣可以實現整體可以滑動,然後監聽ScrollView滑動到底部的事件,然後去請求資料,但是我自己實現過一次,效果是可以了,但是滑動起來是有阻尼的(感覺啊),滑動不過2-3個item就會停止,感覺雖然效果實現了,但是使用者體驗卻不怎麼好,(PS:還沒找到為啥有阻尼,可能自己使用了一個RelativeLayout的(實現上拉載入更多監聽和下拉重新整理監聽的自定義類吧)),有空去自己看下原因吧。
去實現
說實話,對於RecyclerView自己還是瞭解一些的,也寫過一些簡單的介紹,之前也自己實現了一個下拉載入更多的提交到的了git,大家可以去參考下。(小弟功底有限,還請多多包涵https://github.com/wuyinlei/RecycleViewRefreshDemo),那麼今天這個實現的上拉載入更多也是按照這個思路去實現的,就是通過監聽RecyclerView滑動到底部的方法來判斷是否要顯示底佈局,然後去載入資料。
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//是否是最後一個顯示的item位置
int lastVisiableItemPosition = manager.findLastVisibleItemPosition();
if (lastVisiableItemPosition + 1 == mCategoryAdapter.getItemCount()){
if (!isLoading){
isLoading = true; //標誌位 防止重複載入資料
handler.postDelayed(new Runnable() {
@Override
public void run() {
//requestData();
requestLoadMoreData(); //請求資料
// Toast.makeText(MainActivity.this, "已經沒有新的了", Toast.LENGTH_SHORT).show();
isLoading = false; //載入完成資料 更新標誌位
// adapter.notifyItemRemoved(adapter.getItemCount());
}
},2000);
}
}
}
});
private void requestLoadMoreData(){
index++; //這個是模擬載入幾次之後通知沒有資料的
if (index <= 3) {
initData();
} else {
Toast.makeText(MainActivity.this, "已經沒有新的了", Toast.LENGTH_SHORT).show();
}
// swipeRefreshLayout.setRefreshing(false);
mCategoryAdapter.notifyItemRemoved(mCategoryAdapter.getItemCount()); //載入完成之後移除footerView,也就是隱藏(去除載入中的view)
}
這樣就可以很簡單的實現上拉載入更多的邏輯實現了,(這個需要新增一個footerView,接下來就來分析一下如果新增FooterView,還有就是新增HeaderView)
Adapter如果寫
首先定義三個變數用來說明是哪一個View,(HeaderView、View、FooterView)
public static final int TYPE_HEADER = 0;
public static final int TYPE_NORMAL = 1;
private static final int TYPE_FOOTER = 2;
RecyclerView提供個getItemViewType(int position)方法來判斷需要展示的哪種型別的View
if (mHeaderView == null) return TYPE_NORMAL;
if (position == 0) return TYPE_HEADER;
if (mHeaderView != null && position +1 == getItemCount()) return TYPE_FOOTER;
if (mHeaderView == null && position == getItemCount()) return TYPE_FOOTER;
return TYPE_NORMAL;
對於FooterView和HeaderView我們可以共用同一個ViewHolder(其實也就是使用一下,對於HeaderView的點選事件我們是在Activity或者Fragment裡面去寫的,後面有介紹)。這個時候我們在繫結ViewHolder的時候去判斷我們需要展示的哪種View
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mHeaderView != null && viewType == TYPE_HEADER) return new ViewHolder(mHeaderView);
if (viewType == TYPE_FOOTER) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_foot, parent, false);
return new FooterViewHolder(view);
}
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_item_layout, parent, false);
return new ViewHolder(view);
}
對於正常View的ViewHolder也是正常的寫,按照之前的正常使用RecyclerView的方式。例如:
class ViewHolder extends RecyclerView.ViewHolder {
private LinearLayout mCategoryLl;
private ImageView mCategoryImg;
private TextView mCategoryTitle, mCategoryDes;
public ViewHolder(View itemView) {
super(itemView);
mCategoryImg = (ImageView) itemView.findViewById(R.id.category_book_img);
mCategoryTitle = (TextView) itemView.findViewById(R.id.category_title);
mCategoryDes = (TextView) itemView.findViewById(R.id.category_book_des);
mCategoryLl = (LinearLayout) itemView.findViewById(R.id.category_ll);
}
}
對於HeaderView,我們的處理方式(在Adapter裡面進行)
public void setHeaderView(View headerView) {
mHeaderView = headerView;
notifyItemInserted(0); //位於頂部,通知一下view的第一項
}
這個時候通過在activity或者fragment裡面進行
private void setHeader(RecyclerView view) {
//找到控制元件佈局
View header = LayoutInflater.from(this).inflate(R.layout.category_item_header, view, false);
mRlBoy = (RelativeLayout) header.findViewById(R.id.rl_boy);
mRlGirl = (RelativeLayout) header.findViewById(R.id.rl_girl);
mRlEnd = (RelativeLayout) header.findViewById(R.id.rl_end);
mRlUpdate = (RelativeLayout) header.findViewById(R.id.rl_update);
mCategoryAdapter.setHeaderView(header); //設定headerview
}
HeaderView控制元件監聽方式可以如下:
private void initListener() {
mRlBoy.setOnClickListener(this);
mRlGirl.setOnClickListener(this);
mRlEnd.setOnClickListener(this);
mRlUpdate.setOnClickListener(this);
}
基本到此為止,就能實現一般的需求了,如果有複雜的,應該還是存在其他方式的實現,以後有空或者有此需求之後自己在去研究。
解決在GridView形式下,HeaderView和FooterView只顯示在最前面一個或者最後面一個(而不是佔據一行bug)
final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
gridLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(gridLayoutManager);
// gridLayoutManager 佈局管理器
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//如果是第一個(新增HeaderView) 還有就是最後一個(FooterView)
return position == mCategoryBean.size() + 1 || position == 0 ? gridLayoutManager.getSpanCount() : 1;
}
});
效果如開始哈,在次就貼下程式碼吧。
程式碼傳動門:demo地址
相關文章
- (轉) Android 優雅的為RecyclerView新增HeaderView和FooterViewAndroidViewHeader
- 為RecyclerView新增分頁載入(上拉載入更多)功能View
- 封裝RecyclerView,實現新增頭部和底部封裝View
- 自定義RecyclerView實現側滑刪除View
- Android LRecyclerView 實現下拉重新整理,滑動到底部自動載入更多AndroidView
- 為bootstrap新增更多自定義圖示boot
- jQuery如何實現新增自定義函式jQuery函式
- ListView FooterView HeaderView介紹ViewHeader
- RecyclerView載入更多監聽View
- 如何在vue中監聽scroll,從而實現滑動載入更多Vue
- RecyclerView新增動態水印View
- 微信小程式底部實現自定義動態Tabbar微信小程式tabBar
- [deviceone開發]-HeaderView和FooterView的示例devHeaderView
- flutter 如何自定義一個loadmore / 載入更多Flutter
- UI介面微信底部(ViewPager實現Tab,左右滑動+底部點選)UIViewpager
- RecyclerView滑動到指定Position的方法View
- 封裝ListView,實現自動載入更多封裝View
- 微信小程式實現滾動載入更多微信小程式
- RecyclerView 實現滑動刪除和拖拽功能View
- RecyclerView實現滑動刪除和拖拽功能View
- 自定義RecyclerView動畫——實現remove飛出效果View動畫REM
- 自定義View:側滑選單實現View
- Taro UI 2.0 釋出:新增自定義主題功能,適配更多小程式UI
- 自定義註解+反射 實現給註解新增功能的效果反射
- 自定義九宮格載入的實現
- 載入更多 功能的實現
- Laravel 新增自定義助手函式Laravel函式
- Azure AD(六)新增自定義域名
- 自定義UICollectionViewLayout並新增UIDynamicUIView
- 基於 RecyclerView 實現的歌詞滾動自定義控制元件View控制元件
- 自定義View:側滑選單動畫實現View動畫
- MultiItem進階 實現Head Foot和載入更多-多型別RecyclerView Adapter多型型別ViewAPT
- jmeter介面自動化:登入到新增JMeter
- 給 zsh 自定義命令新增引數自動補全
- ubuntu下OpenLDAP新增自定義屬性UbuntuLDA
- AUTOCAD——新增自定義填充圖案
- Google Cloud IAM中新增自定義域名GoCloud
- 公眾號新增自定義連結