本篇來自:https://blog.csdn.net/u012551350/article/details/52026740
RecyclerView 是Android L版本中新添加的一個用來取代ListView的SDK壁晒,它的靈活性與可替代性比listview更好鲤屡。RecyclerView 同樣也用到適配岗钩,枯燥重復(fù)的適配肯定會讓你不勝其煩,下面讓我們一起來打造一款通用的適配(BaseQuickAdapter)填具。受益群體幾乎是所有Android開發(fā)者,希望更你們能夠一起來維護這個項目,把這個項目做得更好劳景,幫助更多人誉简。
看到這里你肯定會有疑問,通用適配(BaseQuickAdapter)盟广,它具體能夠做些什么呢闷串,或者說它都有哪些功能?
這里非常感謝?陳宇明
本文結(jié)合他文章和我的一些修改筋量,希望大家能夠喜歡烹吵。
一、BaseQuickAdapter 簡介
1桨武、減少重復(fù) Adapter 代碼
2肋拔、添加 Item 的點擊事件,長按事件以及子控件的點擊事件
3呀酸、添加頭部凉蜂、尾部,下拉刷新性誉、上拉加載(上拉加載的5種加載更多動畫任你選擇窿吩,后期會添加更多的加載動畫)、沒有更多數(shù)據(jù)
4错览、可以自定義頭部纫雁、尾部、加載更多布局
5蝗砾、添加 Item滑動動畫 (9種動畫切換先较,輕松一行代碼)
6、添加新增悼粮、刪除 Item動畫 (目前支持默認的動畫方式)
7闲勺、網(wǎng)格,列表扣猫,流式隨意切換
8菜循、添加空布局(列表無數(shù)據(jù)時,顯示更加人性化)
9申尤、拖拽和側(cè)滑刪除
10癌幕、支持多類型布局
11、類似淘寶列表切換
12昧穿、字母導(dǎo)航
13勺远、類似探探翻牌
看了 BaseQuickAdapter 的特性,接著來看看外面如何在項目中導(dǎo)入(依賴)它时鸵。
BaseQuickAdapter 導(dǎo)入(依賴)
方式一:build.gradle 的 dependencies 添加如下代碼:
//最新代碼還沒更新到 jcenter 倉庫胶逢,推薦使用方法二依賴項目
compile 'com.github.baserecycleradapter:library:1.1.0'
方式二:下載源碼厅瞎,添加?library?庫到你項目當中。
這里推薦使用方法二依賴進項目初坠。
BaseQuickAdapter 使用
mRecyclerView.setAdapter(mAdapter = new BaseQuickAdapter(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)};
? ? ? ? ? ? }
? ? ? ? }
});
設(shè)置加載更多
只需要設(shè)置加載更多接口锁保,就可以實現(xiàn)加載更多功能。
mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
? ? ? ? @Override
? ? ? ? public void onLoadMoreRequested() {? ? ? ? }
? ? });
以下演示正在加載中半沽,加載失敗點擊重試爽柒,加載完成等狀態(tài):
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);
? ? }
你可以設(shè)置加載更多類型抄囚,只需要添加一行代碼霉赡,實現(xiàn)不同的加載更多動畫:
//設(shè)置加載更多 loadingview
setLoadMoreType(@LoadMoreTypeintloadMoreType)
這里有四種模式供你選擇,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();? ? ? ? }? ? });
拖拽和側(cè)滑
添加以下代碼:
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(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);
? ? }});
數(shù)據(jù)源:
public static List getMultiItemDatas() {
? ? List 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;
}
這樣就輕松實現(xiàn)了聊天界面谬哀。
這樣簡單的配置就可以實現(xiàn)多類型布局刺覆,不需要你寫格外的代碼。
流式布局
先來看看效果圖:
一行代碼實現(xiàn)流式布局效果:
mRecyclerView.setLayoutManager(newFlowLayoutManager());
探探翻牌
類似流式效果史煎,重寫 LayoutManager 實現(xiàn)翻牌效果:
mRecyclerView.setLayoutManager(newOverLayCardLayoutManager());
//添加 itemTouchHelper
final TanTanCallback callback = new TanTanCallback(mRecyclerView, mAdapter, mAdapter.getData());
? ? //測試豎直滑動是否已經(jīng)不會被移除屏幕
? ?//callback.setHorizontalDeviation(Integer.MAX_VALUE);
? ? final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);? ? itemTouchHelper.attachToRecyclerView(mRecyclerView);
效果圖一覽:
具體實現(xiàn)請參考 Demo
淘寶商品列表切換
先來看看效果圖:
看看代碼的實現(xiàn):
//線性 if (mIsLinearManager) {
? ? ? ? ? ? mAdapter.setLayoutType(BaseQuickAdapter.TRANS_0_VIEW);
? ? ? ? ? ? mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
? ? ? ? } else {
? ? ? ? ? ? //網(wǎng)格
? ? ? ? ? ? mAdapter.setLayoutType(BaseQuickAdapter.TRANS_1_VIEW);
? ? ? ? ? ? mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
? ? ? ? ? ? //需要顯示加載更多則加上下面這句? 從新關(guān)聯(lián)recycler
? ? ? ? ? ? mAdapter.onAttachedToRecyclerView(mRecyclerView);
? ? ? ? }
? ? ? ? mIsLinearManager = !mIsLinearManager;
注意:最多支持3種不同類型的轉(zhuǎn)換谦屑。
單選
實現(xiàn)單選,有好幾位同仁都在問我篇梭,其實實現(xiàn)單選是比較簡單的氢橙,方案也比較多,我這里就不在細講了恬偷。下面我給出一種實現(xiàn)方案:
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 。
敬請大家的關(guān)注袍患,后期會一直維護本庫坦康,有什么好的想法,可以提出來诡延。我們互相學(xué)習(xí)進度滞欠。 下一個版本會自定義下拉刷新,全新多項的刷新貢大家喜歡肆良。再次感謝大家一直對我的關(guān)注仑撞,新年將近赤兴,祝愿大家新年新氣象,新年大吉隧哮!