更改和删除的动画不适用于RecyclerView

更改和删除的动画不适用于RecyclerView,第1张

概述App有时会从服务器获取更新的数据集,并且需要显示更改动画.我尝试使用RecyclerView和ItemAnimator,但无法正常工作:仅调用ItemAnimator的animateAdd方法,而不调用animateChange和animateRemove.有什么主意吗?我使用RecyclerView和数据集更改模拟器制作了简单的应用程序.package

App有时会从服务器获取更新的数据集,并且需要显示更改的动画.我尝试使用RecyclerVIEw和ItemAnimator,但无法正常工作:仅调用ItemAnimator的animateAdd方法,而不调用animateChange和animateRemove.

有什么主意吗?

我使用RecyclerVIEw和数据集更改模拟器制作了简单的应用程序.

package com.tseglevskiy.recyclevIEwdevmo;import androID.app.Activity;import androID.os.Bundle;import androID.os.Handler;import androID.support.v7.Widget.DefaultItemAnimator;import androID.support.v7.Widget.linearlayoutmanager;import androID.support.v7.Widget.RecyclerVIEw;import androID.util.Log;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import java.util.ArrayList;import java.util.List;import java.util.Random;public class MainActivity extends Activity {    RecyclerVIEw rv;    List<DummyData> data;    Handler handler;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_main);        handler = new Handler();        rv = (RecyclerVIEw)findVIEwByID(R.ID.List);        rv.setItemAnimator(new MyAnimator());        linearlayoutmanager layoutManager = new linearlayoutmanager(this);        layoutManager.setorIEntation(linearlayoutmanager.VERTICAL);        layoutManager.scrollToposition(0);        rv.setLayoutManager(layoutManager);        data = new ArrayList<>();        data.add(new DummyData(1, "foo"));        data.add(new DummyData(2, "bar"));        MyAdapter adapter = new MyAdapter(copycopy());        adapter.setHasStableIDs(true);        rv.setAdapter(adapter);        loop();    }    voID loop() {        handler.postDelayed(new Runnable() {            @OverrIDe            public voID run() {                getNewDataset();                loop();            }        }, 3000);    }    List<DummyData> copycopy() {        List<DummyData> copy = new ArrayList<>();        for (DummyData f: data) {            copy.add(new DummyData(f.ID, f.what));        }        return copy;    }    voID getNewDataset() {        long Now = System.currentTimeMillis();        Log.d("foo", "getNewDataset " + Now);        // sometimes remove first        if (randInt(1, 10) > 7) {            data.remove(0);        }        // remove random        if (data.size() > 5) {            data.remove(randInt(data.size()/2, data.size()-1));        }        // add a few        int dummyID = (int)(Now % Integer.MAX_VALUE);        data.add(new DummyData(dummyID, "A" + randInt(0,1000000)));        data.add(new DummyData(dummyID + 1, "B" + randInt(0, 1000000)));        data.set(randInt(data.size()/2, data.size()-1),                new DummyData(dummyID + 2, "C" + randInt(0, 1000000)));        MyAdapter adapter = new MyAdapter(copycopy());        adapter.setHasStableIDs(true);        rv.swapAdapter(adapter, false);    }    public static int randInt(int min, int max) {        Random rand = new Random();        int randomNum = rand.nextInt((max - min) + 1) + min;        return randomNum;    }    public static class MyAdapter extends RecyclerVIEw.Adapter<MyHolder> {        private List<DummyData> items;        public MyAdapter(List<DummyData> items) {            this.items = items;        }        @OverrIDe        public MyHolder onCreateVIEwHolder(VIEwGroup vIEwGroup, int i) {            VIEw v = LayoutInflater.from(vIEwGroup.getContext())                    .inflate(androID.R.layout.simple_expandable_List_item_1, vIEwGroup, false);            return new MyHolder(v);        }        @OverrIDe        public voID onBindVIEwHolder(MyHolder myHolder, int position) {            DummyData model = items.get(position);            myHolder.text1.setText(model.what);        }        @OverrIDe        public int getItemCount() {            return items.size();        }    }    public static class MyHolder extends RecyclerVIEw.VIEwHolder {        TextVIEw text1;        public MyHolder(VIEw itemVIEw) {            super(itemVIEw);            text1 = (TextVIEw)itemVIEw.findVIEwByID(androID.R.ID.text1);        }    }    public static class DummyData {        public DummyData(int ID, String what) {            this.ID = ID;            this.what = what;        }        public int ID;        public String what;        @OverrIDe        public String toString() {            return what;        }    }    public static class MyAnimator extends DefaultItemAnimator {        @OverrIDe        public boolean animateAdd(RecyclerVIEw.VIEwHolder holder) {            Log.d("foo", "animateAdd");            return super.animateAdd(holder);        }        @OverrIDe        public boolean animateChange(RecyclerVIEw.VIEwHolder oldHolder, RecyclerVIEw.VIEwHolder newHolder, int fromX, int fromY, int toX, int toY) {            Log.d("foo", "animateChange");            return super.animateChange(oldHolder, newHolder, fromX, fromY, toX, toY);        }        @OverrIDe        public boolean animateMove(RecyclerVIEw.VIEwHolder holder, int fromX, int fromY, int toX, int toY) {            Log.d("foo", "animateMove");            return super.animateMove(holder, fromX, fromY, toX, toY);        }        @OverrIDe        public boolean animateRemove(RecyclerVIEw.VIEwHolder holder) {            Log.d("foo", "animateRemove");            return super.animateRemove(holder);        }    }}

解决方法:

每当使用setHasStableIDs(true)时,都需要重写适配器的getItemID(position)方法.

它应该返回一个真正唯一的值,而不是仓位的直接函数.在您的示例中,它应该类似于:

@OverrIDepublic long getItemID(int position){    return items.get(position).ID;}

当然,您还需要在数据更新时调用adapter.notifyDataSetChanged()

总结

以上是内存溢出为你收集整理的更改和删除的动画不适用于RecyclerView全部内容,希望文章能够帮你解决更改和删除的动画不适用于RecyclerView所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1078752.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存