RecyclerView的超强辅助Graywater——综合实操篇

关于Graywater的系列文章

  1. RecyclerView的超强辅助Graywater——理论篇
  2. RecyclerView的超强辅助Graywater——基础实操篇
  3. RecyclerView的超强辅助Graywater——点击事件
  4. RecyclerView的超强辅助Graywater——综合实操篇

看到上一篇Graywater文章是11月8日写的,也是拖很久了,这篇是Graywater系列文章最后一篇完结篇,把自己挖的坑给填了。

这篇文章是Graywater综合练习文章,包括了复杂视图、基本增删改功能的实现,文末附有Demo地址,同样Demo也只是起一个抛砖引玉的作用,实际上还有很大的延展空间。

先上Demo效果图:

GraywaterDemo综合.gif

老规矩,还是先说说本文目录:

1. 复杂视图的实现
2. 数据的插入
3. 数据的删除
4. 数据的更新
5. 注意点

1. 复杂视图的实现

从GIF图中可以看到,该RecyclerView分为2大模块,娱乐新闻模块和体育新闻模块,每个模块对应一个数据源Primitive和一个管理器ItemBinder,数据源就对应了该模块所有数据内容,管理器对该模块所有视图进行管理。

比如娱乐新闻模块对应了一个EntertainPrimitive和EntertainItemBinder,包含了该模块的所有数据,同时还包含了娱乐新闻标题Binder和娱乐新闻内容的Binder(娱乐新闻内容的Binder使用List集合保存)。

GraywaterDemo模块图.png

接着往下看,在RecyclerView里有3种视图:标题视图、娱乐新闻视图、体育新闻视图。每种视图都有一组自己对应的Binder、ViewHolder和ViewHolderCreator以及自己的布局文件。

看看实现娱乐新闻视图的核心代码:
EntertainItemBinder.java

    @NonNull
    @Override
    public List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends PrimitiveViewHolder>> getBinderList(@NonNull final EntertainPrimitive model, int position) {
        return new ArrayList<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends PrimitiveViewHolder>>() {{
            add(titleBinder);  //添加娱乐新闻标题
            for (EntertainItem entertainItem : model.getEntertainItems()) {
                add(entertainBinder);    //添加娱乐新闻内容
            }
        }};
    }

所以在ItemBinder中可以添加多种类型的binder,就可以实现不同的视图了。

2. 数据的插入

插入娱乐新闻的核心代码:

      @Override
    public void onClickaddNews(String type) {
        Toast.makeText(this, "add " + type + " success", Toast.LENGTH_SHORT).show();
        switch (type) {
            case TYPE_ENTERTAIN:
                addEntertainNews();
                mPrimitiveAdapter.remove(POS_ENTERTAIN);
                mPrimitiveAdapter.add(POS_ENTERTAIN, mEntertainPrimitive);
                //不需要mPrimitiveAdapter.notifyDataSetChanged();在add()方法中已经包含了更新操作
                break;
            case TYPE_SPORT:
                addSportNews();
                mPrimitiveAdapter.remove(POS_SPORT);
                mPrimitiveAdapter.add(POS_SPORT, mSportPrimitive);
                break;
        }
    }    

    private void addEntertainNews() {
        if (entertainItems == null) {
            entertainItems = new ArrayList<>();
        }

        EntertainItem entertain = new EntertainItem();
        entertain.setId("" + (entertainItems.size() + 1));
        entertain.setUrl("https://img8.ccnxs.cn/uploadfile/hbase/201901/0129/HBC5C4FABFA51855.png");
        entertain.setTitle("item " + (entertainItems.size() + 1) + " : " + "胡海泉独自现身丽江 面带微笑任拍照");
        entertainItems.add(entertain);
    }

3. 数据的删除

删除娱乐新闻的核心代码:

    @Override
    public void onClickDeleteEntertain(EntertainItem entertain) {
        boolean needRefresh = false;
        Iterator iterator = entertainItems.iterator();
        while (iterator.hasNext()) {
            EntertainItem entertainItem = (EntertainItem) iterator.next();
            if (entertainItem.getId().equals(entertain.getId())) {
                iterator.remove();
                needRefresh = true;
                break;
            }
        }

        if (needRefresh) {
            mPrimitiveAdapter.remove(POS_ENTERTAIN);
            mPrimitiveAdapter.add(POS_ENTERTAIN, mEntertainPrimitive);
        }
    }

4. 数据的更新

更新娱乐新闻的核心代码:

点击娱乐新闻跳转到编辑页进行编辑,编辑成功返回MainActivity,在onActivityResult()方法中进行处理,实际上娱乐新闻和体育新闻的编辑是不应该放在同一个编辑页的,我这里图方便就写在一起了。

    @Override
    public void onClickEditEntertain(EntertainItem entertain) {
        Intent intent = new Intent(this, EditActivity.class);
        intent.putExtra("type", TYPE_ENTERTAIN);
        intent.putExtra("obj", entertain);
        startActivityForResult(intent, 11);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (resultCode) {
            case 100:
                String type = data.getStringExtra("type");
                if (MainActivity.TYPE_ENTERTAIN.equals(type)) {
                    updateEntertainItem((EntertainItem) data.getSerializableExtra("obj"));
                } else {
                    updateSportItem((SportItem) data.getSerializableExtra("obj"));
                }
                break;
        }
    }

    private void updateEntertainItem(EntertainItem item) {
        boolean needRefresh = false;
        Iterator iterator = entertainItems.iterator();
        while (iterator.hasNext()) {
            EntertainItem entertainItem = (EntertainItem) iterator.next();
            if (entertainItem.getId().equals(item.getId())) {
                entertainItem.setTitle(item.getTitle());
                needRefresh = true;
                break;
            }
        }

        if (needRefresh) {
            mPrimitiveAdapter.remove(POS_ENTERTAIN);
            mPrimitiveAdapter.add(POS_ENTERTAIN, mEntertainPrimitive);
        }
    }

5. 注意点

· binderIndex

看一下娱乐新闻内容EntertainBinder中的关键代码

    @Override
    public void bind(@NonNull EntertainPrimitive model, @NonNull EntertainViewHolder holder, @NonNull List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends EntertainViewHolder>>
            binders, int binderIndex, @NonNull GraywaterAdapter.ActionListener<EntertainPrimitive, EntertainViewHolder> actionListener) {
        EntertainItem entertain = model.getEntertainItems().get(binderIndex - 1);  //因为第一个数据是新闻标题,所以新闻内容数据获取时要减一

        Picasso.get().load(entertain.getUrl()).placeholder(R.mipmap.ic_launcher).into(holder.getImg());
        holder.getTitle().setText(entertain.getTitle());

        holder.getmActionListenerDelegate().update(actionListener, model, holder, binders, binderIndex, null);
        holder.getMainLayoutView().setOnClickListener(holder.getmActionListenerDelegate());
        holder.getDelete().setOnClickListener(holder.getmActionListenerDelegate());
    }

注意这句代码:

EntertainItem entertain = model.getEntertainItems().get(binderIndex - 1);

有没有疑惑为什么要binderIndex要减1?上文也提到EntertainItemBinder是对标题和内容统一进行管理,而binderIndex返回的是binder的下标。看一下断点截图就明白了:

断点.png

因为包含了标题TitleBinder,所以第一条新闻内容对应的binderIndex对应的下标是1,但新闻内容的数据集合与新闻标题的数据是相互独立,没有关系的,所以第一条新闻内容在数据集合中的位置是0,所以binderIndex需要减1。

补充:

如果对你有帮助的话,点赞、评论、赞赏都是对我的鼓励,也是支持我写下去的动力,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269