<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
介面編碼設計實現中,我們肯定會用到列表展示控制元件,大家肯定用過ListView。後來google推出了RecycleView,幫我們去做了很多優化(內建viewholder增加複用率、可以支援區域性重新整理、佈局可以通過外層指定layout等),正常的使用,如下:
MyRecycleViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_decorator); Component component = new ConCreateComponent(); ComponentImplA impl1 = new ComponentImplA(component); impl1.operation(); List<String> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { list.add("position " + i); } adapter = new MyRecycleViewAdapter(this); adapter.setData(list); } /** * 原始的yRecycleViewAdapter v1 */ public void buttonv1(View view) { findViewById(R.id.recycleview).setVisibility(View.VISIBLE); findViewById(R.id.wrapperR).setVisibility(View.GONE); RecyclerView recyclerView = findViewById(R.id.recycleview); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); }
但是RecycleView大家發現有一個問題,我們如果想要為這個RecycleView新增自定義的頭部view、尾部view的話,官方這個明顯做不到,那這時我們可以考慮用裝飾者模式或者繼承去擴充套件一下。
首先我們通過UML圖,來設計一下,設計之前想一下,我們是想要擴充套件RecyclerView.Adapter和RecyclerView,從而可以實現addHeadView、addFootView的功能,那麼需要以下幾步驟。
1)首先,由於RecyclerView.Adapter已經是一個抽象類介面,我們自己繼承與它,然後進行包裝定義為WrapperRecyclerAdapter類
2)WrapperRecyclerAdapter肯定要持有RecyclerView.Adapter的參照,所以需要有一個構造方法,將RecyclerView.Adapter的參照傳遞進來
3)由於WrapperRecyclerAdapter繼承與RecyclerView.Adapter,肯定要去實現關鍵的方法,onCreateViewHolder(建立viewitem的holder)、onBindViewHolder(viewholder資料繫結)、getItemCount(獲取列表item的數量)
4)關鍵的一步來了,就是使用RecyclerView.Adapter、footviews、headviews,這三者組合,重寫上面的三個重要方法,給列表相應位置建立對應的item
package com.itbird.design.decorator.recycleview; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; /** * RecyclerView.Adapter包裝類,擴充套件實現headView、footView的新增 * Created by itbird on 2022/6/10 */ public class WrapperRecyclerAdapter extends RecyclerView.Adapter { RecyclerView.Adapter adapter; List<View> headViews = new ArrayList<>(); List<View> footViews = new ArrayList<>(); public WrapperRecyclerAdapter(RecyclerView.Adapter adapter) { this.adapter = adapter; adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { notifyDataSetChanged(); } }); } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) { //頭部的,返回頭部的viewholder if (position < headViews.size()) { return new WrapperViewHolder(headViews.get(position)); } //adapter返回中間資料holder if (position >= headViews.size() && position < headViews.size() + adapter.getItemCount()) { return adapter.onCreateViewHolder(parent, adapter.getItemViewType(position - headViews.size())); } //尾部的,返回尾部的viewholder return new WrapperViewHolder(footViews.get(position - headViews.size() - adapter.getItemCount())); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (position < headViews.size() || position >= adapter.getItemCount() + headViews.size()) { return; } //頭部和底部不需要做處理,只需要真實的adapter需要處理 adapter.onBindViewHolder(holder, position - headViews.size()); } @Override public int getItemViewType(int position) { return position; } @Override public int getItemCount() { return headViews.size() + footViews.size() + adapter.getItemCount(); } public void addHeadView(View view) { if (!headViews.contains(view)) { headViews.add(view); notifyDataSetChanged(); } } public void addFootView(View view) { if (!footViews.contains(view)) { footViews.add(view); notifyDataSetChanged(); } } public void removeHeadView(View view) { if (headViews.contains(view)) { headViews.add(view); notifyDataSetChanged(); } } public void removeFootView(View view) { if (footViews.contains(view)) { footViews.remove(view); notifyDataSetChanged(); } } static class WrapperViewHolder extends RecyclerView.ViewHolder { public WrapperViewHolder(@NonNull View itemView) { super(itemView); } } }
這時再去呼叫,發現就可以如下呼叫
/** * 擴充套件的,可以增加頭尾的recycleview v2 */ public void buttonv2(View view) { findViewById(R.id.recycleview).setVisibility(View.VISIBLE); findViewById(R.id.wrapperR).setVisibility(View.GONE); RecyclerView recyclerView = findViewById(R.id.recycleview); recyclerView.setLayoutManager(new LinearLayoutManager(this)); WrapperRecyclerAdapter wrapperRecyclerAdapter = new WrapperRecyclerAdapter(adapter); //這裡head為什麼不會全螢幕,因為LayoutInflater需要parent才會全螢幕 wrapperRecyclerAdapter.addHeadView(LayoutInflater.from(this).inflate(R.layout.layout_header_view, recyclerView, false)); wrapperRecyclerAdapter.addFootView(new Button(this)); recyclerView.setAdapter(wrapperRecyclerAdapter); // 物件導向的六大基本原則,好像不符合最小知道原則,每次呼叫需要去new WrapperRecyclerAdapter這樣的一個包裝者,這肯定是不對的,所以需要封裝自己的recycleview }
看一下執行效果
這裡我們發現一個問題,這樣豈不是讓開發者,每每次去使用的時候,new原始的adapter,還需要去new WrapperRecyclerAdapter,然後才能給recyclerView去setAdapter,物件導向的六大基本原則,好像不符合最小知道原則,每次呼叫需要去new WrapperRecyclerAdapter這樣的一個包裝者,這肯定是不對的,所以需要封裝自己的recycleview。
所以我們做如下優化,將WrapperRecyclerAdapter的new操作,我們可以放入recyclerView中,這樣外界開發者只需要去關心WrapperRecycleView和RecyclerView.Adapter就可以了,對於開發者來講,只需關心RecyclerView自定義就可以了。
自定義WrapperRecycleView
,重寫方法setAdapter,用於封裝new WrapperRecyclerAdapter的操作
package com.itbird.design.decorator.recycleview; import android.content.Context; import android.util.AttributeSet; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; /** * 自定義WrapperRecycleView,重寫方法setAdapter,用於封裝new WrapperRecyclerAdapter的操作 * Created by itbird on 2022/6/10 */ public class WrapperRecycleView extends RecyclerView { WrapperRecyclerAdapter wrapperRecyclerAdapter; public WrapperRecycleView(@NonNull Context context) { super(context); } public WrapperRecycleView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public WrapperRecycleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setAdapter(@Nullable Adapter adapter) { wrapperRecyclerAdapter = new WrapperRecyclerAdapter(adapter); super.setAdapter(wrapperRecyclerAdapter); } @Nullable @Override public Adapter getAdapter() { return wrapperRecyclerAdapter; } public void addHeadView(View view) { wrapperRecyclerAdapter.addHeadView(view); } public void addFootView(View view) { wrapperRecyclerAdapter.addFootView(view); } public void removeHeadView(View view) { wrapperRecyclerAdapter.removeHeadView(view); } public void removeFootView(View view) { wrapperRecyclerAdapter.removeFootView(view); } }
呼叫一下
/** * 將wrapperadapter的new操作,內部實現 v3 * 封裝的必要性,這樣的話,只需要關注WrapperRecycleView,不再需要關注WrapperRecyclerAdapter */ public void buttonv3(View view) { findViewById(R.id.wrapperR).setVisibility(View.VISIBLE); findViewById(R.id.recycleview).setVisibility(View.GONE); WrapperRecycleView wrapperRecycleView = findViewById(R.id.wrapperR); wrapperRecycleView.setLayoutManager(new LinearLayoutManager(this)); wrapperRecycleView.setAdapter(adapter); wrapperRecycleView.addHeadView(LayoutInflater.from(this).inflate(R.layout.layout_header_view, wrapperRecycleView, false)); wrapperRecycleView.addFootView(new Button(this)); //這時再去考慮一個事情,我們通過裝飾者模式把adapter封裝了一層,如果adpater有資料更新,導致變動,這時會有問題嗎? //這時會發現,並未更新,原因是裝飾類,並未做事件響應 }
以上就是Android開發可新增頭尾的RecycleView的實現的詳細內容,更多關於Android RecycleView新增頭尾的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45