3个与RecyclerViews相关的数据,每个都在ViewPager的一个页面中

时间:2016-06-07 16:56:45

标签: android android-viewpager android-recyclerview

我有ViewPager个标签。在每个中都有一个RecyclerView。每个RecyclerView都有自己的Adapter。我有一个名为GlobalData的单例类,在该类中,我有3个ArrayLists包含每个Adapter的数据。更具体地说,第一个标签显示个月,第二个标签显示,第三个标签显示。只能才能更改,添加或删除。 应相应调整。

一天 代表工作日。我已经实施了添加,删除和更改的逻辑以及用于调整的逻辑。但我需要一种非常有效的方式来通知Adapters数据已被更改,删除或修改。

我可以在滚动到notifyDataSetChanged()标签时调用每个适配器的ViewPager来实现此目的。

tabStrip.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        switch (position) {
            case WorkingFragmentAdapter.DAYS_PAGE:
                daysAdapter.notifyDataSetChanged();

                break;

            case WorkingFragmentAdapter.WEEKS_PAGE:
                weeksAdapter.notifyDataSetChanged();

                break;

            case WorkingFragmentAdapter.MONTHS_PAGE:
                monthsAdapter.notifyDataSetChanged();

                break;
        }
    }

但是当RecyclerView中显示大量数据并且应用程序的性能较低时,这样的代码非常耗时。

我正在考虑一种方法,我会记住的每个修改,添加和删除位置的位置,以及滚动到页面时,请通知Adapter

我遇到的第二种方法是在Adapter中存储每个GlobalData的引用,并从GlobalData通知每个适配器。

你能告诉我还是暗示我最好的解决办法是什么?提前谢谢。

1 个答案:

答案 0 :(得分:0)

我刚刚经历过这样的事情,其中​​用户操作可能会影响多达六个不同的片段以及它们各自的适配器。当用户与UI交互时,他们会轻扫视图寻呼机,并以随机方式创建/销毁片段。

在开始创建大量错误的设计之后,我重写了代码以获得正确的设计。让我分享一下我学到的东西:

  • 首先要有一个专门用于UI模型的类。在您的情况下,您班级的实例将包含月份列表,周列表和天数列表。它还会包含当前选定的月/周/日以及捕获UI当前状态的任何其他数据。

  • 我不推荐全局数据单例。相反,让Activity持有对模型对象的引用。当片段在onCreate()中时,调用getActivity()以查找模型对象的交换所很容易。这有一个很好的理由:您的模型需要在配置更改时保留并重新创建。

  • 因此,为此,您的模型类应该实现Parcelable并具有保存和恢复其状态所需的所有逻辑。然后覆盖活动的onSaveInstanceState()方法,以使用Bundle.putParcelable()保存模型。当活动在onCreate()时,检查保存的实例状态并在必要时恢复模型。

  • 对于适配器,您的模型类应提供获取数据的方法,例如getMonthList()getWeekList()getSelectedWeek()getSelectedDay()等。 。片段将在onCreateView()中调用这些方法来设置其适配器并以正确的状态显示UI。 重要提示:任何返回集合的方法,例如月/周/等的列表。应该返回一个不可变的数组,而不仅仅是对模型中列表的引用。您希望客户端对列表具有完全独立的引用,否则会出现副作用,因为模型的更改会立即影响适配器 并导致RecyclerView崩溃,因为{{1}没有被叫过。这条建议可能会让你节省大约一周的挫折感。

  • 您的模型类将是UI事件的接收器和发送器。在接收方:您将定义一些方法,如notifyDataSetChanged()selectWeek(week)等,以告知您的模型用户刚才所做的事情。该方法将使数据发生变化,然后通知所有听众,接下来将对此进行讨论。

  • 在发送方:您的模型类应该至少定义一个接口 - 我称之为selectDay(day) - 它将定义模型可以更改的所有方式的回调方法。一些示例:CalendarUIListeneronWeekSelected(week)onDaySelected(day)等。您的模型还需要通过两种方法onMonthListChanged(List<month>)addListener()维护一个侦听器列表。

  • 您的视图寻呼机片段可以实现此接口以接收事件通知。这些视图寻呼机片段应调用removeListener()中的model.addListener(this)onCreate()中的model.removeListener(this)。或者,片段可以创建匿名侦听器对象并注册/取消注册,而不是直接实现接口。

  • 现在,您的听众可以接收事件并做出相应的回应。假设您的用户选择了一个更改日期列表的周(假设您有一个onDestroy()类和一个自定义适配器)。您的代码可能如下所示:

    Day

这是本土事件总线的一个例子。您还可以使用事件总线库使所有接线更容易(即在正确的位置呼叫 @Override public void onDayListChanged(Day[] days) { if (mAdapter != null) { mAdapter.setDays(days); // this method would call notifyDataSetChanged() } } &amp; addListener())。我的特定应用程序还有一些额外的挑战,例如每当UI事件发生时从服务器检索数据,然后在请求完成时广播该数据事件。使用这种架构可以更容易地找出哪个类负责什么操作。

最后一件事:我确实遇到了配置发生变化的鸡/蛋问题,其中片段显然是在活动的removeListener()中重新创建的,这使我没有机会从保存的实例状态恢复模型活动。我编写了一个抽象基类,为我的片段实现了监听器,所以我的代码看起来像这样:

super.onCreate()