New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

可以在 Activity 中进行 Diff,或者继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff. #56

Closed
zhengjieAdriod opened this Issue Jan 5, 2017 · 26 comments

Comments

Projects
None yet
5 participants
@zhengjieAdriod

大神,这个具体怎么做啊?
我是想把他这个diff的功能,与MutiType一起用的。搞了快一天了还是搞不定啊,一直不走三个参数的onBindViewHolder();

希望大神给指点指点,最好有个小demo/ 万分感谢...

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 5, 2017

Owner

请把你的代码和使用的 MultiType 版本号贴出来,并描述清楚问题,我可以帮你看看。

Owner

drakeet commented Jan 5, 2017

请把你的代码和使用的 MultiType 版本号贴出来,并描述清楚问题,我可以帮你看看。

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 5, 2017

https://github.com/mcxtzhang/SupportDemos 我看了他这个文章之后,就在他的demo中添加MultiType 的功能。意思就是:在他这个单一的itemtype中新添加一个itemtype, 并使用他demo中的diff功能。 实现的过程中,需要用到三个参数的onBindViewHolder();问题就是这个方法,应该在哪里复写?我是在MultiTypeAdapter的子类中复写的。

https://github.com/mcxtzhang/SupportDemos 我看了他这个文章之后,就在他的demo中添加MultiType 的功能。意思就是:在他这个单一的itemtype中新添加一个itemtype, 并使用他demo中的diff功能。 实现的过程中,需要用到三个参数的onBindViewHolder();问题就是这个方法,应该在哪里复写?我是在MultiTypeAdapter的子类中复写的。

@frankfancode

This comment has been minimized.

Show comment
Hide comment
@frankfancode

frankfancode Jan 5, 2017

我也在做类似的功能,把 数据存储到 ViewHolder 中,在 onBindViewHolder 时 比较一下 ViewHolder 里面保存的数据 和 item 里面传入的数据,如果相同就不刷新了。
我觉得这个diff 的功能还是比较常用的,尤其是用这个库的会有很多不同的item,估计会有很多复杂的 item,重复刷新可能滑动会比较卡。

我也在做类似的功能,把 数据存储到 ViewHolder 中,在 onBindViewHolder 时 比较一下 ViewHolder 里面保存的数据 和 item 里面传入的数据,如果相同就不刷新了。
我觉得这个diff 的功能还是比较常用的,尤其是用这个库的会有很多不同的item,估计会有很多复杂的 item,重复刷新可能滑动会比较卡。

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

@frankfancode 请问你是在哪里复写这个三个参数的onBindViewHolder ()方法的??

@frankfancode 请问你是在哪里复写这个三个参数的onBindViewHolder ()方法的??

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

如果是为了 diff,不应该覆写 onBindViewHolder,onBindViewHolder 是用于绑定数据的而不是让人来做数据筛选或处理的。

Owner

drakeet commented Jan 6, 2017

如果是为了 diff,不应该覆写 onBindViewHolder,onBindViewHolder 是用于绑定数据的而不是让人来做数据筛选或处理的。

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

其实我这句话已经说得非常清楚了,不理解的话你可以读 24 遍后再想想:

可以在 Activity 中进行 Diff,或者继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff.

若 24 遍后还不理解,待会儿我给你写个示例。

Owner

drakeet commented Jan 6, 2017

其实我这句话已经说得非常清楚了,不理解的话你可以读 24 遍后再想想:

可以在 Activity 中进行 Diff,或者继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff.

若 24 遍后还不理解,待会儿我给你写个示例。

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

这篇文章我在这儿看了两天了,只是会用了,还是不能通过他的灵活性进行功能添加。我再想想..

这篇文章我在这儿看了两天了,只是会用了,还是不能通过他的灵活性进行功能添加。我再想想..

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

@drakeet 文章里所说的diff 就是v7包下的DiffUtil吗?

@drakeet 文章里所说的diff 就是v7包下的DiffUtil吗?

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

@zhengjieAdriod 没有限定,可以是 v7 DiffUtil,也可以是其他 DiffUtil 或你自己造的 DiffUtil,文章里说了,这不属于 MultiType 的范畴,MultiType 不会去管你的数据 diff,只接受数据,这个数据可以是全量数据,也可以是你 diff 后的数据。

Owner

drakeet commented Jan 6, 2017

@zhengjieAdriod 没有限定,可以是 v7 DiffUtil,也可以是其他 DiffUtil 或你自己造的 DiffUtil,文章里说了,这不属于 MultiType 的范畴,MultiType 不会去管你的数据 diff,只接受数据,这个数据可以是全量数据,也可以是你 diff 后的数据。

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

不知道那句话你 24 遍读完了没,刚简单写了下所谓 "在 Activity 中进行 Diff" 的示例,代码如下:

public class FlexActivity extends AppCompatActivity {

    List<X> oldItems;
    MultiTypeAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flex);
        /* Init your oldItems, adapter and recyclerView ... */
        /* Fetch your data from server and call onLoadData */
    }


    void onLoadData(List<X> newItems) {
        final XDiffCallback diffCallback = new XDiffCallback(oldItems, newItems);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

        this.oldItems.clear();
        this.oldItems.addAll(newItems);
        diffResult.dispatchUpdatesTo(adapter);
    }


    static class X {
        int id;
    }


    static class XDiffCallback extends DiffUtil.Callback {

        private final List<X> oldList;
        private final List<X> newList;


        XDiffCallback(List<X> oldList, List<X> newList) {
            this.oldList = oldList;
            this.newList = newList;
        }


        @Override
        public int getOldListSize() {
            return oldList.size();
        }


        @Override
        public int getNewListSize() {
            return newList.size();
        }


        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
        }


        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            final X oldItem = oldList.get(oldItemPosition);
            final X newItem = newList.get(newItemPosition);
            return Objects.equals(oldItem, newItem);
        }
    }
}

看完这个代码后,你可以再读几遍那句话,看看是不是说得一点没错。

Owner

drakeet commented Jan 6, 2017

不知道那句话你 24 遍读完了没,刚简单写了下所谓 "在 Activity 中进行 Diff" 的示例,代码如下:

public class FlexActivity extends AppCompatActivity {

    List<X> oldItems;
    MultiTypeAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flex);
        /* Init your oldItems, adapter and recyclerView ... */
        /* Fetch your data from server and call onLoadData */
    }


    void onLoadData(List<X> newItems) {
        final XDiffCallback diffCallback = new XDiffCallback(oldItems, newItems);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

        this.oldItems.clear();
        this.oldItems.addAll(newItems);
        diffResult.dispatchUpdatesTo(adapter);
    }


    static class X {
        int id;
    }


    static class XDiffCallback extends DiffUtil.Callback {

        private final List<X> oldList;
        private final List<X> newList;


        XDiffCallback(List<X> oldList, List<X> newList) {
            this.oldList = oldList;
            this.newList = newList;
        }


        @Override
        public int getOldListSize() {
            return oldList.size();
        }


        @Override
        public int getNewListSize() {
            return newList.size();
        }


        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
        }


        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            final X oldItem = oldList.get(oldItemPosition);
            final X newItem = newList.get(newItemPosition);
            return Objects.equals(oldItem, newItem);
        }
    }
}

看完这个代码后,你可以再读几遍那句话,看看是不是说得一点没错。

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

万分感谢!!

万分感谢!!

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

又简单写了下,所谓 "继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff":

public class XDiffMultiTypeAdapter extends MultiTypeAdapter {

    private List<X> oldItems;


    public XDiffMultiTypeAdapter(@NonNull List<X> items) {
        super(items);
    }


    public void setItems(List<X> newItems) {
        final XDiffCallback diffCallback = new XDiffCallback(oldItems, newItems);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

        this.oldItems.clear();
        this.oldItems.addAll(newItems);
        diffResult.dispatchUpdatesTo(this);
    }


    static class XDiffCallback extends DiffUtil.Callback {

        private final List<X> oldList;
        private final List<X> newList;


        XDiffCallback(List<X> oldList, List<X> newList) {
            this.oldList = oldList;
            this.newList = newList;
        }


        @Override
        public int getOldListSize() {
            return oldList.size();
        }


        @Override
        public int getNewListSize() {
            return newList.size();
        }


        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
        }


        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            final X oldItem = oldList.get(oldItemPosition);
            final X newItem = newList.get(newItemPosition);
            return Objects.equals(oldItem, newItem);
        }
    }
}

好了,我已经双方面用代码解释了 "可以在 Activity 中进行 Diff,或者继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff. " 这句话,最后有没有发现我这句话已经非常言简意赅。

注意:如果你要容纳多种 item types,应该使用 ? 替代我这里的 X.

Owner

drakeet commented Jan 6, 2017

又简单写了下,所谓 "继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff":

public class XDiffMultiTypeAdapter extends MultiTypeAdapter {

    private List<X> oldItems;


    public XDiffMultiTypeAdapter(@NonNull List<X> items) {
        super(items);
    }


    public void setItems(List<X> newItems) {
        final XDiffCallback diffCallback = new XDiffCallback(oldItems, newItems);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

        this.oldItems.clear();
        this.oldItems.addAll(newItems);
        diffResult.dispatchUpdatesTo(this);
    }


    static class XDiffCallback extends DiffUtil.Callback {

        private final List<X> oldList;
        private final List<X> newList;


        XDiffCallback(List<X> oldList, List<X> newList) {
            this.oldList = oldList;
            this.newList = newList;
        }


        @Override
        public int getOldListSize() {
            return oldList.size();
        }


        @Override
        public int getNewListSize() {
            return newList.size();
        }


        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
        }


        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            final X oldItem = oldList.get(oldItemPosition);
            final X newItem = newList.get(newItemPosition);
            return Objects.equals(oldItem, newItem);
        }
    }
}

好了,我已经双方面用代码解释了 "可以在 Activity 中进行 Diff,或者继承 MultiTypeAdapter 提供接收数据方法,在方法中进行 Diff. " 这句话,最后有没有发现我这句话已经非常言简意赅。

注意:如果你要容纳多种 item types,应该使用 ? 替代我这里的 X.

@drakeet drakeet added the answered label Jan 6, 2017

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

确实非常言简意赅,对我这个新手不好理解。真是有幸膜拜到大神的代码。

XDiffCallback 并没有重写 public Object getChangePayload(int oldItemPosition, int newItemPosition) ;
该方法, 返回 一个 代表着新老item的改变内容的 payload对象。 该对象会在三个参数的onBindViewHolder ()中使用。以达到只改变item上的部分数据。

确实非常言简意赅,对我这个新手不好理解。真是有幸膜拜到大神的代码。

XDiffCallback 并没有重写 public Object getChangePayload(int oldItemPosition, int newItemPosition) ;
该方法, 返回 一个 代表着新老item的改变内容的 payload对象。 该对象会在三个参数的onBindViewHolder ()中使用。以达到只改变item上的部分数据。

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

@zhengjieAdriod 不客气 ^ ^
getChangePayload 这个方法你可以自行根据你的需要进行覆写。

Owner

drakeet commented Jan 6, 2017

@zhengjieAdriod 不客气 ^ ^
getChangePayload 这个方法你可以自行根据你的需要进行覆写。

@drakeet

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

例如哪些需要啊?

例如哪些需要啊?

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

这方法的字面意思是:一个 item 中,具体是哪些字段数据产生了变化。
它被调用的时机是:areItemsTheSame() 返回 trueareContentsTheSame() 返回 false.

When areItemsTheSame(int, int) returns true for two items and areContentsTheSame(int, int) returns false for them, DiffUtil calls this method to get a payload about the change.

另外,这个方法可以不覆写,它的返回值是 @Nullable.

Owner

drakeet commented Jan 6, 2017

这方法的字面意思是:一个 item 中,具体是哪些字段数据产生了变化。
它被调用的时机是:areItemsTheSame() 返回 trueareContentsTheSame() 返回 false.

When areItemsTheSame(int, int) returns true for two items and areContentsTheSame(int, int) returns false for them, DiffUtil calls this method to get a payload about the change.

另外,这个方法可以不覆写,它的返回值是 @Nullable.

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

这已经不属于 MultiType 的范畴了,具体内容你应该自行学习使用。经过一番努力后实在不懂,我可以再帮忙看看。

Owner

drakeet commented Jan 6, 2017

这已经不属于 MultiType 的范畴了,具体内容你应该自行学习使用。经过一番努力后实在不懂,我可以再帮忙看看。

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 6, 2017

Owner

如果你想学习这个方法,我可以给你提供一篇非常好且详尽的文章:

https://medium.com/@nullthemall/diffutil-is-a-must-797502bc1149#.l3a13i5sq

Owner

drakeet commented Jan 6, 2017

如果你想学习这个方法,我可以给你提供一篇非常好且详尽的文章:

https://medium.com/@nullthemall/diffutil-is-a-must-797502bc1149#.l3a13i5sq

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

好的, 感谢大神!

好的, 感谢大神!

@zhengjieAdriod

This comment has been minimized.

Show comment
Hide comment
@zhengjieAdriod

zhengjieAdriod Jan 6, 2017

`大神,public boolean areItemsTheSame(int oldItemPosition, int newItemPosition)方法中要做类型判断吗?拿不到id这个字段的
class DiffCallBack02 extends DiffUtil.Callback {

private final List<T> oldList;
private final List<T> newList;


DiffCallBack02(List<T> oldList, List<T> newList) {
    this.oldList = oldList;
    this.newList = newList;
}


@Override
public int getOldListSize() {
    return oldList.size();
}


@Override
public int getNewListSize() {
    return newList.size();
}


@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    T oldT = oldList.get(oldItemPosition);
    T newT = newList.get(newItemPosition);
    //这块要做bean类型的判断吗??
    return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
}


@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    final T oldItem = oldList.get(oldItemPosition);
    final T newItem = newList.get(newItemPosition);
    return Objects.equals(oldItem, newItem);
}

}`

`大神,public boolean areItemsTheSame(int oldItemPosition, int newItemPosition)方法中要做类型判断吗?拿不到id这个字段的
class DiffCallBack02 extends DiffUtil.Callback {

private final List<T> oldList;
private final List<T> newList;


DiffCallBack02(List<T> oldList, List<T> newList) {
    this.oldList = oldList;
    this.newList = newList;
}


@Override
public int getOldListSize() {
    return oldList.size();
}


@Override
public int getNewListSize() {
    return newList.size();
}


@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    T oldT = oldList.get(oldItemPosition);
    T newT = newList.get(newItemPosition);
    //这块要做bean类型的判断吗??
    return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
}


@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    final T oldItem = oldList.get(oldItemPosition);
    final T newItem = newList.get(newItemPosition);
    return Objects.equals(oldItem, newItem);
}

}`

@frankfancode

This comment has been minimized.

Show comment
Hide comment
@frankfancode

frankfancode Jan 6, 2017

@drakeet 收到,相当赞

@drakeet 收到,相当赞

@drakeet drakeet closed this Jan 7, 2017

@drakeet drakeet reopened this Jan 7, 2017

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Jan 7, 2017

Owner

@zhengjieAdriod 我不是大神。diff callback 中 id 不是必须的,你自己思考,我不能一直手把手告诉你每一步应该怎么做。

Owner

drakeet commented Jan 7, 2017

@zhengjieAdriod 我不是大神。diff callback 中 id 不是必须的,你自己思考,我不能一直手把手告诉你每一步应该怎么做。

@zhangle1

This comment has been minimized.

Show comment
Hide comment
@zhangle1

zhangle1 Jan 19, 2017

刚想问的问题 发现有好多小伙伴多问了0.0

刚想问的问题 发现有好多小伙伴多问了0.0

@drakeet

This comment has been minimized.

Show comment
Hide comment
@drakeet

drakeet Mar 14, 2017

Owner

@anson39f 我这边是可以打开的,如果打不开,你需要科学上网。

Owner

drakeet commented Mar 14, 2017

@anson39f 我这边是可以打开的,如果打不开,你需要科学上网。

@drakeet drakeet closed this Apr 3, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment