【從 0 開始開發一款直播 APP】3.2 高層封裝之 Adapter — RecyclerView 實現單佈局展示...
本文為菜鳥窩作者蔣志碧的連載。“從 0 開始開發一款直播 APP ”系列來聊聊時下最火的直播 APP,如何完整的實現一個類"騰訊直播"的商業化專案
視訊地址:http://www.cniao5.com/course/10121
【從 0 開始開發一款直播 APP】3.1 高層封裝之 Adapter — ListView & GridView
【從 0 開始開發一款直播 APP】3.2 高層封裝之 Adapter — RecyclerView 實現單佈局展示
【從 0 開始開發一款直播 APP】3.3 高層封裝之 Adapter -- RecyclerView 實現多條目展示
【從 0 開始開發一款直播 APP】3.4 高層封裝之 Adapter -- RecyclerView 優雅的新增 Header、Footer
一、前言
之前已經講過 ListView、GridView 的 Adapter 封裝,這次將帶來 RecyclerView 的封裝。
RecyclerView 是一種新的檢視組,目標是為任何基於介面卡的檢視提供相似的渲染方式。該控制元件用於在有限的窗中展示大量資料集,它被作為 ListView 和 GridView 控制元件的繼承者。
主要有以下功能:
1、簡單資料繫結(單種 item)
2、多佈局繫結 (多種 item)
**3、設定監聽 **
4、優雅的新增 header、footer
老規矩,先封裝 ViewHolder,再封裝 Adapter。
二、ViewHolder 的封裝
2.1、RecyclerView 在使用之前需要新增依賴
dependencies {
compile 'com.android.support:recyclerview-v7:25.2.0'
}
2.2、建立一個類繼承 RecyclerView.ViewHolder,實現其建構函式
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
public RecyclerViewHolder(View itemView) {
super(itemView);
}
}
2.3、其它的封裝和之前寫過對 Adapter 封裝類似,講了封裝的大致步驟,這裡不細講了,直接看 從 0 開始開發一款直播 APP | 3.1 高層封裝之 Adapter — ListView & GridView,一個 getView() 獲取控制元件,通過 SparseArray 儲存控制元件。
private SparseArray<View> mViews;
public RecyclerViewHolder(View itemView) {
super(itemView);
this.mViews = new SparseArray<>();
}
/**
* 從ItemView獲取View
* @param id ItemView裡包含的ViewId
* @param <V> 返回View
* @return
*/
public <V extends View> V getView(int id) {
View view = mViews.get(id);
if (view == null) {
view = itemView.findViewById(id);
mViews.put(id, view);
}
return (V) view;
}
2.4、設定控制元件以及監聽(採用鏈式程式設計方法)
/**
* 設定TextView的值
* @param viewId
* @param text
* @return
*/
public RecyclerViewHolder setText(int viewId, String text) {
TextView tv = getView(viewId);
tv.setText(text);
return this;
}
/**
* 設定ImageView的值
* @param viewId
* @param resId
* @return
*/
public RecyclerViewHolder setImageResource(int viewId, int resId) {
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}
/**
* 設定ImageView的值
* 第三方 ImageLoder Glide Picasso
* 不能直接寫死第三方圖片載入
* 使用自己的一套規範 ImageLoder
* @param viewId
* @return
*/
public RecyclerViewHolder setImagePath(int viewId,ImageLoder imageLoder) {
ImageView view = getView(viewId);
imageLoder.loadImage(view,imageLoder.getPath());
return this;
}
//圖片載入 (對第三方庫載入圖片等封裝)
public abstract static class ImageLoder{
private String path;
public ImageLoder(String path){
this.path = path;
}
//需要複寫該方法載入圖片
public abstract void loadImage(ImageView imageView,String path);
public String getPath() {
return path;
}
}
/**
* 設定是否可見
* @param viewId
* @param visible
* @return
*/
public RecyclerViewHolder setVisible(int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
/**
* 設定tag
* @param viewId
* @param tag
* @return
*/
public RecyclerViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return this;
}
public RecyclerViewHolder setTag(int viewId, int key, Object tag) {
View view = getView(viewId);
view.setTag(key, tag);
return this;
}
/**
* 設定Checkable
* @param viewId
* @param checked
* @return
*/
public RecyclerViewHolder setChecked(int viewId, boolean checked) {
Checkable view = (Checkable) getView(viewId);
view.setChecked(checked);
return this;
}
//點選事件
public RecyclerViewHolder setOnClickListener(int viewId,View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
//觸控事件
public RecyclerViewHolder setOnTouchListener(int viewId,View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}
//長按事件
public RecyclerViewHolder setOnLongClickListener(int viewId,View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
三、Adapter 的封裝
首先建立 Adapter 並繼承 RecyclerView.Adapter
,將 ViewHolder 作為範型傳入,將資料作為範型傳入,並實現其方法。方法和 ListView 封裝類似,傳入佈局,資料,上下文,通過 onCreateViewHolder()
例項化 ViewHolder,onBindViewHolder()
繫結 ViewHolder,用於資料,事件繫結,將該方法抽象出去,讓使用者實現,使用者通過該方法拿到 item 物件。
public abstract class RecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> {
protected int mLayoutId;//佈局id
protected List<T> mDatas;//資料來源
protected Context mContext;//上下文
private LayoutInflater mInflater;
public RecyclerViewAdapter(Context context, int layoutId, List<T> datas) {
this.mContext = context;
this.mLayoutId = layoutId;
this.mDatas = datas;
this.mInflater = LayoutInflater.from(mContext);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(mLayoutId,parent,false);
return new RecyclerViewHolder(itemView);
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
bindData(holder,mDatas.get(position),position);
}
/**
* 把必要引數傳進去,讓每個 Adapter 去設定具體值
* @param holder RecyclerViewHolder
* @param t 資料
* @param position 當前位置
*/
protected abstract void bindData(RecyclerViewHolder holder, T t,int position);
@Override
public int getItemCount() {
return mDatas.size();
}
}
四、Demo 演示單佈局顯示
4.1、由於用到網路圖片,我使用的Glide載入,先新增依賴
dependencies {
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:recyclerview-v7:25.2.0'
}
4.2、在 AndroidManifest.xml 中新增網路訪問許可權
<uses-permission android:name="android.permission.INTERNET"/>
4.3、建立一個類繼承 RecyclerView.ViewHolder,實現其建構函式RecyclerAdapterDemo.java
public class RecyclerAdapterDemo extends RecyclerViewAdapter<Item> {
public RecyclerAdapterDemo(Context context, List<Item> datas) {
super(context, R.layout.list_item, datas);
}
@Override
protected void bindData(RecyclerViewHolder holder, final Item item, int position) {
holder.setText(R.id.tv1,item.getTv1())
// .setImageResource(R.id.img,item.getRes())
.setOnClickListener(R.id.tv1, new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,item.getTv1(),Toast.LENGTH_SHORT).show();
}
}).setOnLongClickListener(R.id.tv1, new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(mContext,"長按:"+item.getTv1(),Toast.LENGTH_SHORT).show();
return true;//true 表示不響應點選事件 false 長按事件結束還會響應點選事件
}
});
//載入網路圖片
holder.setImagePath(R.id.img, new RecyclerViewHolder.ImageLoder("http://tomcat.apache.org/images/tomcat.png") {
@Override
public void loadImage(ImageView imageView, String path) {
Glide.with(mContext).load(path).into(imageView);
}
});
}
}
4.5、單佈局 Adapter 的使用
public class AdapterActivity extends BaseActivity {
private RecyclerAdapterDemo mAdapterDemo;
private ArrayList<Item> Datas;
private RecyclerView mRecyclerView;
@Override
protected void setToolbar() {
}
@Override
protected void setListener() {
}
//填充資料
@Override
protected void initData() {
Datas = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
Datas.add(new Item(R.drawable.tab_publish_normal,"我 get 新技能 " + i));
}
mAdapterDemo = new RecyclerAdapterDemo(this, Datas);
mRecyclerView.setAdapter(mAdapterDemo);
}
@Override
protected void initView() {
mRecyclerView = obtainView(R.id.recyclerView);
//LinearLayoutManager
//新增分割線
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
//新增布局管理器
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
//分割線網上有很多示例,這裡不貼程式碼
//GridLayoutManager
// mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
// mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));
}
@Override
protected int getLayoutId() {
return R.layout.activity_adapter;
}
}
4.6、activity_adapter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
tools:context="com.dali.admin.fragment.AdapterActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
五、執行效果
**5.1、LinearLayoutManager **
5.2、GridLayoutManager
總結
單條目封裝步驟
1、 ViewHolder 的封裝,繼承 RecyclerView.ViewHolder,實現其方法和建構函式
2、封裝 ViewHolder 的 getView() 方法,避免 findViewById 及型別轉換,提供設定控制元件和監聽的一系列方法
3、Adapter 的封裝,繼承 RecyclerView.Adapter 類,將封裝的 ViewHolder 作為範型傳入,將資料來源作為範型傳入。如:BaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder>。實現其構造方法和抽象方法。
4、設定資料來源,上下文物件,佈局 ID,抽象繫結 ViewHolder 具體實現,將 ViewHolder 和資料來源作為引數傳遞出去,讓使用者對資料進行相應處理。
單條目 Adapter 封裝及其使用講解完,下一章講解多條目 Adapter 封裝
更多內容,請關注菜鳥窩(微信公眾號ID: cniao5),程式猿的線上學習平臺。 轉載請註明出處,本文出自菜鳥窩,原文連結http://www.cniao5.com/forum/thread/107b6b5210fe11e790dc00163e0230fa
相關文章
- 【從 0 開始開發一款直播 APP】10 騰訊雲通訊及SDK整合APP
- 從零開始實現線上直播
- 直播app開發,封裝式標題欄APP封裝
- Flutter 開發從 0 到 1(三)佈局與 ListViewFlutterView
- 從今天開始學習iOS開發(iOS 7版)–構建一款App之App開發過程iOSAPP
- 基於 Multitype 開源庫封裝更好用的RecyclerView.Adapter封裝ViewAPT
- RecyclerView.Adapter的封裝(RecyclerAdapter)ViewAPT封裝
- 從0開始搭建自己的直播平臺
- iOS開發之自定義表情鍵盤(元件封裝與自動佈局)iOS元件封裝
- 直播app開發,實現輪播圖上下自動滑動展示效果APP
- RecyclerView Adapter 優雅封裝,一個Adapter搞定所有列表ViewAPT封裝
- 直播app開發,Android ListView好友列表展示APPAndroidView
- 從0開始寫一個基於Flutter的開源中國客戶端(5)——App整體佈局框架搭建Flutter客戶端APP框架
- [敏捷開發實踐](0) 開始敏捷
- 週末直播錄影:現場寫程式碼,從 0 開始開發 AI 評測平臺AI
- 從0開始搭建preact開發環境React開發環境
- UIColletionView瀑布流佈局實現思路以及封裝的實現UIView封裝
- 直播軟體app開發,flutter 驗證碼輸入框的簡單封裝APPFlutter封裝
- 從0開始的高併發(一)--- Zookeeper的基礎概念
- Android實現RecyclerView巢狀流式佈局AndroidView巢狀
- 快速開始grid佈局
- Android開發之常用佈局Android
- 從零開始的高併發(二)--- Zookeeper實現分散式鎖分散式
- 簡單5步,從0開始搭建你的第一款小程式
- Android 從零開始實現RecyclerView分組及粘性頭部效果AndroidView
- 直播app開發,實現簡單的釋出訂閱者模式APP模式
- 一個RecyclerView實現QQ空間相簿佈局View
- JavaWeb專案開發從0開始的要點!JavaWeb
- 從0開發一款iOS App-朱德權-極客時間iOSAPP
- 從0到1使用VUE-CLI3開發實戰(四): Axios封裝VueiOS封裝
- 從0開始寫一個基於Flutter的開源中國客戶端(4)——Flutter佈局基礎Flutter客戶端
- 從0開始,手把手教你用Vue開發一個答題AppVueAPP
- RecyclerView基礎(一)Adapter與Holder的封裝之RvAdapter,RvHolderViewAPT封裝
- 直播平臺軟體開發,flex佈局例項Flex
- 直播app開發搭建,實現圖片和影片列表展示、檢視、刪除等功能APP
- 直播平臺開發,直播各個分類單例設計展示單例
- 封裝RecyclerView,實現新增頭部和底部封裝View
- 從 0 開始實現程式語言(一):手寫 jsonParserJSON