RecyclerView 之通用適配
RecyclerView 是Android L版本中新新增的一個用來取代ListView的SDK,它的靈活性與可替代性比listview更好。RecyclerView 同樣也用到適配,枯燥重複的適配肯定會讓你不勝其煩,下面讓我們一起來打造一款通用的適配(BaseQuickAdapter)。受益群體幾乎是所有Android開發者,希望更你們能夠一起來維護這個專案,把這個專案做得更好,幫助更多人。
看到這裡你肯定會有疑問,通用適配(BaseQuickAdapter),它具體能夠做些什麼呢,或者說它都有哪些功能?
這裡非常感謝 陳宇明
本文結合他文章和我的一些修改,希望大家能夠喜歡。
一、BaseQuickAdapter 簡介
減少重複 Adapter 程式碼
新增 Item 的點選事件,長按事件以及子控制元件的點選事件
新增頭部、尾部,下拉重新整理、上拉載入(上拉載入的5種載入更多動畫任你選擇,後期會新增更多的載入動畫)、沒有更多資料
可以自定義頭部、尾部、載入更多佈局
新增 Item滑動動畫 (9種動畫切換,輕鬆一行程式碼)
新增新增、刪除 Item動畫 (目前支援預設的動畫方式)
網格,列表,流式隨意切換
新增空佈局(列表無資料時,顯示更加人性化)
拖拽和側滑刪除
支援多型別佈局
類似淘寶列表切換
字母導航
類似探探翻牌
看了 BaseQuickAdapter 的特性,接著來看看外面如何在專案中匯入(依賴)它。
BaseQuickAdapter 匯入(依賴)
方式一:build.gradle 的 dependencies 新增如下程式碼:
//最新程式碼還沒更新到 jcenter 倉庫,推薦使用方法二依賴專案
compile 'com.github.baserecycleradapter:library:1.1.0'
方式二:下載原始碼,新增 library 庫到你專案當中。
這裡推薦使用方法二依賴進專案。
BaseQuickAdapter 使用
mRecyclerView.setAdapter(mAdapter = new BaseQuickAdapter<String, BaseViewHolder>(R.layout.rv_item, getItemDatas()) {
@Override
protected void convert(final BaseViewHolder helper, String item) {
helper.setText(R.id.tv_item_text, item);
}
});
Item點選,長按事件
//Item 點選事件
setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener)
//長按事件
setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener)
子控制元件的點選事件
helper.setOnClickListener(R.id.tv_item_text, new View.OnClickListener() {
@Override
public void onClick(View v) {
//事件處理
}
});
新增頭部,尾部
//頭部
mAdapter.addHeaderView();
//尾部
mAdapter.addFooterView();
以下是新增頭部的程式碼:
View headerView=getLayoutInflater().inflate(R.layout.rv_header, null);
headerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
mAdapter.addHeaderView(headerView);
部的新增與頭部的新增類似。
新增 Item動畫
//一行程式碼開啟動畫 預設CUSTOM動畫
mAdapter.openLoadAnimation(BaseQuickAdapter.CUSTOMIN);
當然你可以更換其他動畫:
//ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT, //SLIDEIN_LEFT_RIGHT, SLIDEIN_BOTTOM_TOP, CUSTOMIN
mAdapter.openLoadAnimation(BaseQuickAdapter.CUSTOMIN);
最後你可以自定義 Item動畫:
mAdapter.openLoadAnimation(new BaseAnimation[]{
new BaseAnimation() {
@Override
public Animator[] getAnimators(View view) {
return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", 0.5f, 1.0f),
ObjectAnimator.ofFloat(view, "scaleX", 0.5f, 1.0f)};
}
}
});
設定載入更多
只需要設定載入更多介面,就可以實現載入更多功能。
mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
@Override
public void onLoadMoreRequested() {
}
});
以下演示正在載入中,載入失敗點選重試,載入完成等狀態:
mShowType++;
if (mShowType == 2) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//載入失敗,點選重試
mAdapter.loadMoreFail();
}
}, DELAY_MILLIS);
} else if (mShowType >= 4) {
mHandler.post(new Runnable() {
@Override
public void run() {
//載入完成
mAdapter.loadMoreEnd();
}
});
} else {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mAdapter.addData(addDatas());
//載入更多完成
mAdapter.loadMoreComplete();
}
}, DELAY_MILLIS);
}
你可以設定載入更多型別,只需要新增一行程式碼,實現不同的載入更多動畫:
//設定載入更多 loadingview
setLoadMoreType(@LoadMoreType int loadMoreType)
這裡有四種模式供你選擇,APAY, BALL_BEAT, BALL_CLIP_ROTATE, BALL_SCALE
,如果都不滿足你的需求,你可以繼承 BaseIndicator
類從新載入檢視,或給我留言。
新增空佈局
View emptyView=getLayoutInflater().inflate(R.layout.rv_empty, null);
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
//新增空檢視
mAdapter.setEmptyView(emptyView);
emptyView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "your click empty", Snackbar.LENGTH_SHORT).show();
}
});
拖拽和側滑
新增以下程式碼:
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mAdapter);
ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(callback);
mAdapter.setItemTouchHelper(mItemTouchHelper);
mAdapter.setDragViewId(R.id.iv_drag);
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
支援不同型別
mRecyclerView.setAdapter(mAdapter = new BaseMultiItemAdapter<MultiItem>(this, getMultiItemDatas()) {
@Override
protected void convert(BaseViewHolder helper, MultiItem item) {
switch (helper.getItemViewType()) {
case MultiItem.SEND:
helper.setText(R.id.chat_from_content, item.content);
//helper.setImageBitmap(R.id.chat_from_icon,getRoundCornerBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.chat_head), 16));
break;
case MultiItem.FROM:
helper.setText(R.id.chat_send_content, item.content);
//helper.setImageBitmap(R.id.chat_send_icon,getRoundCornerBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.from_head), 16));
break;
}
}
@Override
protected void addItemLayout() {
addItemType(MultiItem.SEND, R.layout.chat_send_msg);
addItemType(MultiItem.FROM, R.layout.chat_from_msg);
}
});
mAdapter.openLoadAnimation(true);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MultiItem multiItem = new MultiItem();
multiItem.itemType = MultiItem.SEND;
multiItem.content = etChat.getText().toString();
mAdapter.add(multiItem);
mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount());
//mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
}
});
資料來源:
public static List<MultiItem> getMultiItemDatas() {
List<MultiItem> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
MultiItem multiItem = new MultiItem();
if (i % 2 == 0) {
multiItem.itemType = MultiItem.SEND;
multiItem.content = "海,妹子約嗎";
} else {
multiItem.itemType = MultiItem.FROM;
multiItem.content = "大哥,你別怕";
}
list.add(multiItem);
}
return list;
}
這樣就輕鬆實現了聊天介面。
這樣簡單的配置就可以實現多型別佈局,不需要你寫格外的程式碼。
流式佈局
先來看看效果圖:
一行程式碼實現流式佈局效果:
mRecyclerView.setLayoutManager(new FlowLayoutManager());
探探翻牌
類似流式效果,重寫 LayoutManager 實現翻牌效果:
mRecyclerView.setLayoutManager(new OverLayCardLayoutManager());
//新增 itemTouchHelper
final TanTanCallback callback = new TanTanCallback(mRecyclerView, mAdapter, mAdapter.getData());
//測試豎直滑動是否已經不會被移除螢幕
//callback.setHorizontalDeviation(Integer.MAX_VALUE);
final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
效果圖一覽:
具體實現請參考 Demo
淘寶商品列表切換
先來看看效果圖:
看看程式碼的實現:
//線性
if (mIsLinearManager) {
mAdapter.setLayoutType(BaseQuickAdapter.TRANS_0_VIEW);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
} else {
//網格
mAdapter.setLayoutType(BaseQuickAdapter.TRANS_1_VIEW);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
//需要顯示載入更多則加上下面這句 從新關聯recycler
mAdapter.onAttachedToRecyclerView(mRecyclerView);
}
mIsLinearManager = !mIsLinearManager;
注意:最多支援3種不同型別的轉換。
單選
實現單選,有好幾位同仁都在問我,其實實現單選是比較簡單的,方案也比較多,我這裡就不在細講了。下面我給出一種實現方案:
public void setItemChecked(int position) {
if (mLastCheckedPosition == position)
return;
mBooleanArray.put(position, true);
if (mLastCheckedPosition > -1) {
mBooleanArray.put(mLastCheckedPosition, false);
mAdapter.notifyItemChanged(mLastCheckedPosition);
}
mAdapter.notifyDataSetChanged();
mLastCheckedPosition = position;
}
mBooleanArray 儲存是否被點選,把點選前的索引值置為 false , 點選索引置為 true 。
敬請大家的關注,後期會一直維護本庫,有什麼好的想法,可以提出來。我們互相學習進度。 下一個版本會自定義下拉重新整理,全新多項的重新整理貢大家喜歡。再次感謝大家一直對我的關注,新年將近,祝願大家新年新氣象,新年大吉!
如果對你有所幫助請給star
歡迎加入478720016來幫助更多的人。
相關推薦
RecyclerView 之通用適配
RecyclerView 是Android L版本中新新增的一個用來取代ListView的SDK,它的靈活性與可替代性比listview更好。RecyclerView 同樣也用到適配,枯燥重複的適配肯定會讓你不勝其煩,下面讓我們一起來打造一款通用的適配(Bas
dubbo之日誌適配及訪問日誌
訪問日誌 DDU ring toc accesslog span rate slf4j spa 日誌適配 自 2.2.1 開始,dubbo 開始內置 log4j、slf4j、jcl、jdk 這些日誌框架的適配 1,也可以通過以下方式顯示配置日誌輸出策略: 命令行
Android 螢幕適配之 dimens 適配
相信做手機端的 App 的小夥伴,只要是產品稍微大一點,就會面臨螢幕適配的問題,對於適配這個問題,網上眾說紛紜,以前雖然有零零散散的看過,但是沒有實踐過,也是在最近遇到這個需求的情況下才研究了一下,現在做個記錄。 1 參考連結 http://blog.csdn.net/qq_341
Android中ListView、GridView的通用適配封裝簡化程式碼
轉載請註明出處:http://blog.csdn.net/u013038616/article/details/50733935 ListView和GridView是我們平時經常用來展示集合資料,每次都要為每種列表建一個專門的適配,雖然建立介面卡灰常簡單,但是每次都會有很多類似的程式碼,作
Android修煉之Pie 適配的搬運工
自嘲時刻 Android P正式版(以下稱為Pie)已經正式上線了,各大廠商已經開始了系統升級工作,咱做上層開發的也得跟上節奏。當然了,新版本所有的行為更改內容都可以在官網上找到,對於其中如何繞開非SDK介面限制的問題,也有各路大神給出瞭解決方案。所以,我只能當
Android APP全方位效能調優之螢幕適配終結者
優點 1. 無侵入性 首先科普下 Android 中的一個長度單位:pt,它表示一個點,是螢幕的物理尺寸,其大小為 1 英寸的 1 / 72,也就是 72pt 等於 1 英寸(其實 Android 中還有比較少見的 in 和 mm 的長度單位)。而我本次的適配使用的單位恰好是 pt,所以對你
Android之機型適配
Android中的機型適配 在軟體開發的過程中,為了讓軟體在不同的場景下都可以使用,所以機型適配是不可或缺並且非常重要耗時的一個環節. 一:機型適配需要考慮的幾個方面: 1,Android的版本 2.手機廠商 3.螢幕的尺寸 4.網路的制式 5
android之螢幕適配(三)實踐dimens.xml尺寸適配不同的平板
android3.2以後,為了提供更精準的對佈局檔案的控制,可以通過為資原始檔(res目錄下檔案)增加字尾來指定該資料夾裡的xml佈局檔案或color.xml,string.xml是為哪種大小的螢幕使用。 第一種字尾:sw<N>dp,如layout-sw600
Android之螢幕適配
網上螢幕適配的方式有很多,比如按百分比的、按解析度的,這裡我是按最小寬度去適配,也是Google建議的方式。 1.首先下載螢幕適配外掛ScreenMatch。 AS→File→Settings→plugins→SreenMa
android 手機適配之values適配dimen值
android 適配螢幕的方式有很多,最方便最直接的無非就是適配values裡的dimens檔案值來進行適配. 張鴻洋大神已經寫過一篇適配的文章,很詳細 但是我在閱讀的時候還是有點疑問,這個values-1920x1080到底是dp值還是手機解析度,因為我在
React Native入門(十一)之螢幕適配
準備 首先,我們在官方文件寬度和高度一節可以知道,RN中單位是dp,這個跟Android中的單位是一致的! 官網中: A dp is equal to one physical pixel on a screen with a density of 1
Swift之動態適配UITableView的cell高度
首先在Xib中拖一個UITableView,讓其充滿整個檢視控制器,並遵守實現UITableViewDelegate,UITableViewDataSource協議; 其次,新建一個繼承於UItabl
Android筆記之螢幕適配全攻略
Android螢幕適配出現的原因 在我們學習如何進行螢幕適配之前,我們需要先了解下為什麼Android需要進行螢幕適配。 由於Android系統的開放性,任何使用者、開發者、OEM廠商、運營商都可以對Android進行定製,修改成他們想要的樣子。
cocos2dx進階學習之螢幕適配
背景在學習cocos2dx時,我們在main函式中發現一句程式碼,#include "main.h" #include "AppDelegate.h" #include "CCEGLView.h" USING_NS_CC; int APIENTRY _tWinMain(H
Android知識梳理之螢幕適配全攻略
引言: 我相信Android碎片化問題是讓所有的Android開發者都比較頭疼的問題.尤其是螢幕適配這一塊兒.想要自己的app在不同的裝置上面都有一個比較好的顯示效果.就必須做好相應的螢幕適配.本文是結合網上的相關知識總結、官方文件結合自己的一些理解來進行闡述
原始碼分析 Sentinel 之 Dubbo 適配原理
在Alibaba Sentinel 限流與熔斷初探(技巧篇) 的示例中我選擇了 sentinel-demo-apache-dubbo 作為突破點,故本文就從該專案入手,看看 Sentinel 是如何對 Dubbo 做的適配,讓專案使用方無感知,只需要引入對應的依即可。 sentinel-apache-dubb
android之實現萬能適配RecyclerView的adapter
現在基本大家都推薦RecyclerView,很少有人使用ListView了,包括我自己也是,已經很久沒用ListView了,所以關於ListView的萬能adapter就不寫了。 每次寫專案的時候,每次遇到RecyclerView都要重新寫一個Adapter,
通用的recyclerview adapter 適配
統一管理適配Adapter多型別處理,更加方便的管理和操作。 joe 偉大的地獄逃脫者 讓我來和你講個故事,關於joe 的MyLittleZoo公司 。關於他是怎麼創造可複用的不同型別的Recyclerview adapter來終結他的噩夢。和他最終
xcode7和ios9適配之路
get sans att 新建 技術分享 matching resolve down 二進制 從xcode6.x升級xcode7.2之後,發現要做一堆事情來做適配,不然之前的項目沒法好好執行。 一.換庫 dylib後綴的庫都要換成tbd後綴的。例如以下所看到的
移動端適配之rem 筆記
mcal ont padding 字體大小 頁面 所有 1.2 resize 筆記 /*移動端適配 width|height|font-size = 視覺稿量出來的值 / 100rem;@lbl*/ @media screen and (max-width:359px)