Android 萬能適配器BRVAH

概述

在Android開發(fā)過程中,我們經(jīng)常會用到adapter聚假。因為adapter在基本使用的過程中锦庸,代碼比較繁瑣机蔗,于是進行一個簡單封裝,使調(diào)用起來更加簡單便捷酸员。這節(jié)就來講講這個適配器的封裝吧蜒车。

前言

在Android開發(fā)過程中,我們經(jīng)常會用到adapter幔嗦。因為adapter在基本使用的過程中酿愧,代碼比較繁瑣,于是進行一個簡單封裝邀泉,使調(diào)用起來更加簡單便捷嬉挡。這節(jié)就來講講這個適配器的封裝吧。

今天涉及的內(nèi)容:

  1. adapter庫依賴
  2. 封裝類ComAdapter和GroupAdapter概述
  3. 通用適配器ComAdapter的使用
  4. 分組適配器GroupAdapter的使用
  5. MainActivity中調(diào)用示例
  6. 效果圖和項目結(jié)構(gòu)圖

先來波adapter使用的效果圖吧


image

一. adapter庫依賴

Github地址
本adapter的封裝是建立在一個第三方庫的基礎(chǔ)之上的汇恤。在使用之前庞钢,你需要添加該庫的依賴:
將JitPack存儲庫添加到您的構(gòu)建文件中(項目根目錄下build.gradle文件):

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

添加依賴項以最新版本為準:

dependencies {
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34'
}

二.封裝類ComAdapter和GroupAdapter概述

適配器庫BaseRecyclerViewAdapterHelper是一個專注adapter的庫,里面有一個適配器基類:BaseQuickAdapter因谎,為了方便日常調(diào)度使用基括,我在BaseQuickAdapter基礎(chǔ)上再度擴展,分別整合了兩個adapter基類:ComAdapter和GroupAdapter财岔。
ComAdapter:基于一般的列表或九宮格布局的使用
GroupAdapter:基于簡單的分組列表展示使用风皿。

三.通用適配器ComAdapter的使用

ComAdapter是一個通用適配器基類,里面集成了adapter創(chuàng)建需要的一些基本方法匠璧,包括控件初始化,獲取布局對象桐款,加載動畫,列表數(shù)據(jù)加載夷恍,控件點擊事件監(jiān)聽等方法魔眨。 當你要實現(xiàn)一個線性列表,需要創(chuàng)建adapter的時候酿雪,繼承ComAdapter可以幫你快速實現(xiàn)自己的adapter遏暴。

3.1 繼承ComAdapter,寫自己的Adapter

當RecyclerView加載列表的時候,需要一個適配器(NameAdapter)指黎,你可以像這樣快速來創(chuàng)建它:

public class NameAdapter<T>extends ComAdapter {
    private TextView mTvName;
    public NameAdapter(List<T> data, Context context) {
        //加載布局和數(shù)據(jù)
        super(R.layout.item_layout, data, context);
    }
    @Override
    public <T>void initView(BaseViewHolder viewHolder, T obj) {
        //控件初始化
        mTvName=viewHolder.getView(R.id.tv);
    }
    @Override
    public <T>void initData(BaseViewHolder viewHolder, T obj) {
        String name=obj.toString();
        mTvName.setText(name);
    }
    @Override
    public <T>void setListener(BaseViewHolder viewHolder, T obj) {
        //添加控件監(jiān)聽
        addOnClickListener(mTvName,viewHolder,obj);
    }
}
3.2 線性布局調(diào)用
mNames=new ArrayList<>();
//for (int i = 0; i < 10; i++) {
//    mNames.add("小黃"+i);
//}
mNameAdapter=new NameAdapter<>(mNames,MainActivity.this);
mNameAdapter.setRecyclerLinearManager(mRecyclerView);
3.3 九宮格布局調(diào)用
mNames=new ArrayList<>();
//for (int i = 0; i < 10; i++) {
//    mNames.add("小黃"+i);
//}
mNameAdapter=new NameAdapter<>(mNames,MainActivity.this);
mNameAdapter.setRecyclerGridManager(mRecyclerView,4);
3.4 設(shè)置分割線,返回RecyclerView.ItemDecoration對象

//設(shè)置線性布局分割線
LinearDividerItemDecoration linearDivider=mNameAdapter.setLinearLayoutItemSpace(mRecyclerView,5,R.color.colorAccent);
//設(shè)置九宮格局分割線
GridDividerItemDecoration gridDivider=mNameAdapter.setGridLayoutItemSpace(mRecyclerView,5,R.color.colorAccent);

3.5 移除分割線
/**移除RecycleView間距**/
removeItemSpace(RecyclerView recyclerView,  RecyclerView.ItemDecoration divider)
3.6 點擊事件
       //點擊事件
       mNameAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() {
            @Override
            public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) {
                switch (view.getId()) {
                    case R.id.tv:
                        ToastUtil.shortShow("====1====="+obj.toString());
                        break;
                    default:
                        break;
                }
            }
        });

四. 分組適配器GroupAdapter的使用

GroupAdapter是一個列表分組顯示的適配器基類朋凉,里面集成了adapter創(chuàng)建需要的一些基本方法,包括控件初始化,獲取布局對象袋励,加載動畫,列表數(shù)據(jù)加載,控件點擊事件監(jiān)聽等方法茬故。 當你要船創(chuàng)建一個分組顯示功能的adapter盖灸,繼承GroupAdapter可方便快捷實現(xiàn)

4.1 javaBean繼承SectionEntity類

GroupAdapter顯示的數(shù)據(jù),都需要用javaBean進行封裝磺芭。并且JavaBean需要繼承SectionEntity類,然后重寫含(boolean isHeader, String header)參數(shù)的構(gòu)造方法赁炎。 以Person對象為例,你需要這樣處理:

public class Person extends SectionEntity {
    private String name;
    private int age;
    public Person(boolean isHeader, String header) {
        super(isHeader,header);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
4.2 繼承GroupAdapter,寫自己的adapter

然后寫一個自己的adapter钾腺,繼承自GroupAdapter徙垫,以PersonAdapter為例:

public class PersonAdapter<T> extends GroupAdapter {
    //header
    private TextView mTvHeader;
    //item
    private TextView mTvItem;
    public PersonAdapter(List<T> data, Context context) {
        super(R.layout.item_layout, R.layout.header_layout, data,context);
    }
    @Override
    protected void convertHead(BaseViewHolder viewHolder, SectionEntity item) {
        //標題相關(guān)所有都在此處理
        //標題初始化
        mTvHeader=viewHolder.getView(R.id.tv_title);
        //標題數(shù)據(jù)處理
        mTvHeader.setText(item.header);
        //標題點擊事件
        addOnClickListener(mTvHeader,viewHolder,item);
    }
    @Override
    public <T>void initView(BaseViewHolder viewHolder, T obj) {
        //item初始化
        mTvItem=viewHolder.getView(R.id.tv);
    }
    @Override
    public <T>void initData(BaseViewHolder viewHolder, T obj) {
        //item數(shù)據(jù)處理
        Person person= (Person) obj;
        mTvItem.setText("姓名:"+person.getName()+"     年齡:"+person.getAge());
    }
    @Override
    public <T>void setListener(BaseViewHolder viewHolder, T obj) {
        //item中控件監(jiān)聽
        addOnClickListener(mTvItem,viewHolder,obj);
    }
}

其中PersonAdapter(List data, Context context)構(gòu)造方法的super方法中,要引入兩個布局id放棒,一個是item的一個是header的姻报。 Header相關(guān)方法都在convertHead中處理。item的相關(guān)處理在initView,initData和setListener方法中進行间螟。

4.3 線性布局使用
       mPersonList=new ArrayList<>();
       //for (int i = 0; i < 10; i++) {
       //Person person;
       //if(i%7==0){//header
       //   person=new Person(true,"標題"+i);
       //}else{//item
       //   person=new Person(false,null);
       //   person.setName("小黑"+i);
       //   person.setAge(25+i);
       // }
       //   mPersonList.add(person);
       //}
       mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this);
       mPersonAdapter.setRecyclerLinearManager(mRecyclerView);
4.4 九宮格布局使用
        mPersonList=new ArrayList<>();
        //for (int i = 0; i < 10; i++) {
        //Person person;
        //if(i%7==0){//header
        //   person=new Person(true,"標題"+i);
        //}else{//item
        //   person=new Person(false,null);
        //   person.setName("小黑"+i);
        //   person.setAge(25+i);
        // }
        //   mPersonList.add(person);
        //}
        mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this);
        mPersonAdapter.setRecyclerGridManager(mRecyclerView,3);
4.5 設(shè)置分割線,返回RecyclerView.ItemDecoration對象

線性布局的時候吴旋,可以像下面這樣設(shè)置分割線:

//線性布局分割線
LinearDividerItemDecoration linearDivider=mPersonAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent);

注意: 在實現(xiàn)分組適配器<即繼承GroupAdapter的adapter>不能使用setGridLayoutItemSpace給列表設(shè)置分割線,會出現(xiàn)ui上顯示的bug厢破,為了避免 用戶使用不當荣瑟,我已經(jīng)將GroupAdapter類中的setGridLayoutItemSpace拋出異常并做以錯誤提示。大家若還是需要在分組九宮格布局中做分割線的話摩泪, 需要自己在布局中笆焰,或者在adapter中處理數(shù)據(jù)的時候,用代碼來實現(xiàn)分割線效果见坑。

4.6 移除分割線
/**移除RecycleView間距**/
removeItemSpace(RecyclerView recyclerView, RecyclerView.ItemDecoration divider)
4.7 點擊事件

若要設(shè)置adapter的點擊事件嚷掠,你可以像下面這樣寫:

        //點擊事件
        mPersonAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() {
            @Override
            public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) {
                Person person= (Person) obj;
                switch (view.getId()) {
                    case R.id.tv_title://header
                        ToastUtil.shortShow("===="+person.header+"===");
                        break;
                    case R.id.tv://item
                        ToastUtil.shortShow("===="+person.getName()+"===");
                        break;
                    default:
                        break;
                }
            }
        });

五.MainActivity中調(diào)用示例

下面貼出adapter在MainActivity中使用的代碼:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button mBtn1;
    private Button mBtn2;
    private Button mBtn3;
    private Button mBtn4;
    private RecyclerView mRecyclerView;
    private List<String>mNames;
    private NameAdapter<String>mNameAdapter;
    private List<Person>mPersonList;
    private PersonAdapter<Person>mPersonAdapter;
    private LinearDividerItemDecoration mLinearDivider;
    private GridDividerItemDecoration mGridDivider;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        setListener();
    }
    private void initData() {
        mBtn1 = findViewById(R.id.btn1);
        mBtn2 = findViewById(R.id.btn2);
        mBtn3 = findViewById(R.id.btn3);
        mBtn4 = findViewById(R.id.btn4);
        mRecyclerView = findViewById(R.id.rv);
        mBtn1.setText("通用線性");
        mBtn2.setText("通用九宮");
        mBtn3.setText("分組線性");
        mBtn4.setText("分組九宮");
    }
    private void setListener() {
        mBtn1.setOnClickListener(this);
        mBtn2.setOnClickListener(this);
        mBtn3.setOnClickListener(this);
        mBtn4.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn1://通用布局線性測試
                commonLinearLayout();
                break;
            case R.id.btn2://通用布局九宮格測試
                commonGridLayout();
                break;
            case R.id.btn3://分組布局線性測試
                diffGropLinearLayout();
                break;
            case R.id.btn4://分組布局九宮格測試
                diffGropGridLayout();
                break;
            default:
                break;
        }
        //點擊事件
        commonDiffClick();
    }
    private void initCommonData(){
        //通用布局
        if(mNames==null) {
            mNames = new ArrayList<>();
        }
        mNames.clear();
        for (int i = 0; i < 10; i++) {
            mNames.add("小黃" + i);
        }
    }
    private void initdiffGropData(){
        //分組布局
        if(mPersonList==null) {
            mPersonList = new ArrayList<>();
        }
        mPersonList.clear();
        for (int i = 0; i < 10; i++) {
            Person person;
            if(i%7==0){//header
                person=new Person(true,"標題"+i);
            }else{//item
                person=new Person(false,null);
                person.setName("小黑"+i);
                person.setAge(25+i);
            }
            mPersonList.add(person);
        }
    }
    /**
     * 通用布局線性測試
     **/
    private void commonLinearLayout() {
        initCommonData();
        mNameAdapter = new NameAdapter<>(mNames, MainActivity.this);
        mNameAdapter.setRecyclerLinearManager(mRecyclerView);
        //清除舊的分割線
        mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider);
        mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider);
        //設(shè)置分割線
        mLinearDivider=mNameAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent);
    }
    /**
     * 通用布局九宮格測試
     **/
    private void commonGridLayout() {
        initCommonData();
        mNameAdapter = new NameAdapter<>(mNames, MainActivity.this);
        mNameAdapter.setRecyclerGridManager(mRecyclerView, 3);
        //清除舊的分割線
        mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider);
        mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider);
        //設(shè)置分割線
        mGridDivider=mNameAdapter.setGridLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent);
    }
    /**
     * 分組布局線性測試
     **/
    private void diffGropLinearLayout() {
        initdiffGropData();
        mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this);
        mPersonAdapter.setRecyclerLinearManager(mRecyclerView);
        //清除舊的分割線
        mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider);
        mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider);
        //設(shè)置分割線
        mLinearDivider=mPersonAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent);
    }
    /**
     * 分組布局九宮格測試
     **/
    private void diffGropGridLayout() {
        initdiffGropData();
        mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this);
        mPersonAdapter.setRecyclerGridManager(mRecyclerView,3);
        //清除舊的分割線
        mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider);
        mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider);
    }
    /**點擊事件**/
    private void commonDiffClick(){
        //通用布局點擊事件
        if(mNameAdapter!=null) {
            mNameAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() {
                @Override
                public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) {
                    switch (view.getId()) {
                        case R.id.tv:
                            ToastUtil.shortShow("====1=====" + obj.toString());
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        //分組布局點擊事件
        if(mPersonAdapter!=null) {
            mPersonAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() {
                @Override
                public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) {
                    Person person = (Person) obj;
                    switch (view.getId()) {
                        case R.id.tv_title://header
                            ToastUtil.shortShow("====" + person.header + "===");
                            break;
                        case R.id.tv://item
                            ToastUtil.shortShow("====" + person.getName() + "===");
                            break;
                        default:
                            break;
                    }
                }
            });
        }
    }
}

六. 效果圖和項目結(jié)構(gòu)圖

效果圖


image

項目結(jié)構(gòu)圖


image

最后

雖然萬能適配器方便好用,但是我還是推薦使用原生寫法,因為原生寫法更靈活鳄梅,不會出現(xiàn)莫名的問題叠国。萬能適配器的動畫目前可能有點毛病,謹慎使用列表動畫!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戴尸,隨后出現(xiàn)的幾起案子粟焊,更是在濱河造成了極大的恐慌,老刑警劉巖孙蒙,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件项棠,死亡現(xiàn)場離奇詭異,居然都是意外死亡挎峦,警方通過查閱死者的電腦和手機香追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坦胶,“玉大人透典,你說我怎么就攤上這事晴楔。” “怎么了峭咒?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵税弃,是天一觀的道長。 經(jīng)常有香客問我凑队,道長则果,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任漩氨,我火速辦了婚禮西壮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叫惊。我一直安慰自己款青,他們只是感情好,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布赋访。 她就那樣靜靜地躺著可都,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚓耽。 梳的紋絲不亂的頭發(fā)上渠牲,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音步悠,去河邊找鬼签杈。 笑死,一個胖子當著我的面吹牛鼎兽,可吹牛的內(nèi)容都是我干的答姥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼谚咬,長吁一口氣:“原來是場噩夢啊……” “哼鹦付!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起择卦,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤敲长,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后秉继,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祈噪,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年尚辑,在試婚紗的時候發(fā)現(xiàn)自己被綠了辑鲤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡杠茬,死狀恐怖月褥,靈堂內(nèi)的尸體忽然破棺而出弛随,到底是詐尸還是另有隱情,我是刑警寧澤宁赤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布撵幽,位于F島的核電站,受9級特大地震影響礁击,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逗载,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一哆窿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厉斟,春花似錦挚躯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至感挥,卻和暖如春缩搅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背触幼。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工硼瓣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人置谦。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓堂鲤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親媒峡。 傳聞我的和親對象是個殘疾皇子瘟栖,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容