【问题标题】:How to update an element in Adapter list once changes have been made to the element in a different Activity?一旦对不同活动中的元素进行了更改,如何更新适配器列表中的元素?
【发布时间】:2017-02-09 21:02:01
【问题描述】:

我正在寻找 Android 中的最佳实现模式,以在不同活动中的一个元素发生更改时更新列表。

想象一下这个用户旅程:

异步进程从 Web 服务器获取十 (10) 个联系人个人资料。这些被放置在一个数组中并通知一个适配器。十 (10) 个联系人资料现在显示在一个列表中。

用户点击联系人资料五 (5)。它会打开一个包含此联系人配置文件详细信息的活动。用户决定他们喜欢它并单击“添加到收藏夹”。这会触发对 Web 服务器的异步请求,用户已收藏联系人配置文件五 (5)。

用户点击返回。他们现在再次与列表一起呈现。问题是该列表现在已经过时,并且没有显示个人资料五 (5) 是最喜欢的。

你:

  • 异步调用 Web 服务器以获取更新的数据并通知适配器刷新整个列表。这似乎效率低下,因为调用列表可能需要几秒钟。

  • 在收藏配置文件时,将对象存储在标记为“刷新”的某处(可能在单例服务中)。 List 活动中的 OnResume 是否会嗅探变量并仅更新列表中的该元素。

  • 确保列表数组是静态可用的。从详细活动更新数组。 Activity 中的 OnResume 始终通知适配器进行刷新。

  • 确保列表数组和适配器是静态可用的。更新数组并从详细活动中通知适配器。

还有其他选择吗?最好的设计原则是什么?

【问题讨论】:

    标签: android android-activity firebase firebase-realtime-database adapter


    【解决方案1】:

    异步调用网络服务器获取更新数据并通知适配器 刷新整个列表。这似乎是低效的呼吁 列表可能需要几秒钟。

    正如你所说,它非常低效。在 Android 中创建一个对象是昂贵的。创建一个包含许多对象的列表要昂贵得多。

    在收藏配置文件时将对象存储在某处(可能在 单例服务)标记为“刷新”。 List 活动中的 OnResume 你会嗅探变量并只更新列表中的那个元素吗?

    这不是一个好的解决方案,因为在我们刷新对象之前应用程序可能会崩溃,或者应用程序被设备杀死。

    确保列表数组是静态可用的。从更新数组 详细活动。 Activity 中的 OnResume 总是通知适配器 刷新一下。

    通过静态方法或变量更新数组不是一个好的解决方案,因为它会使您的详细 Activity 与列表耦合。此外,如果您的项目变得更大,您无法确保只有更改列表的详细活动。

    确保列表数组和适配器是静态可用的。更新 数组并从详细活动通知适配器。

    同上,静态变量或对象是不行的。


    你最好使用像EventBus这样的事件总线系统。

    每当您单击'add to favourite' 详细活动时,将更新收藏夹的异步请求发送到 Web 服务器,并将事件发送到列表活动以更新特定的配置文件对象。例如,如果您的个人资料的 id 为“777”并且个人资料在详细活动中被收藏,那么您需要在您的 :

    中发送类似这样的事件
    btnFavourite.setOnClickListener(new View.OnClickListener() {
       public void onClick(View v) {               
         // Send event when click favourite.
         EventBus.getDefault.post(new RefreshProfileEvent(id, true);
       }
    });
    

    RefreshProfileEvent 是一个简单的 pojo:

    public class RefreshProfileEvent {
      private String id;
      private boolean isFavourited;
    
      public RefreshProfileEvent(String id, boolean isFavourited) {
        this.id = id;
        this.isFavourited = isFavourited;
      }
      //getter and setter
    }
    

    然后您可以在列表活动中接收事件以更新所选配置文件:

    public class YourListActivity {
      ...
      @Override
      protected onCreate() {
        ...
        EventBus.getDefault().register(this);
      }
    
      @Override
      protected onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
      }
    
      @Subscribe(threadMode = ThreadMode.MAIN)  
      public void onMessageEvent(RefreshProfileEvent event) {
        // Refresh specific profile
        // For example, your profile is saved in List<Profile> mProfiles
    
        // Search for profile by its id.
        for(int i = 0; i < mProfiles.size(); i++) {
          if(mProfiles.getId().equals(event.getId()) {
            // Refresh the profile in the adapter.
            // I assume the adapter is RecyclerView adapter named mAdapter
            mProfiles.get(i).isFavourited(true);
            mAdapter.notifyItemChanged(i);
            // Stop searching.
            break;
        }
      }
    }
    

    您无需等待服务器返回的 AsyncTask 请求结果。只需将个人资料设为首选,然后静静地等待结果。如果您的请求成功,请不要执行任何操作。但如果请求错误,则将配置文件设为不受欢迎,并发送 SnackBar 等无障碍消息通知用户。

    【讨论】:

    • 这是一个非常深入的答案。谢谢你。我之前没有听说过或使用过 EventBus,但我肯定会从现在开始使用它。
    • 不客气。还有RxJava,不过我之前没用过。
    【解决方案2】:

    第三个选项是最好的,当用户在细节活动中更改数据时应该更改数组,然后当使用返回到主活动时调用 Adapter.notifyDataSetChanged();会成功的

    【讨论】:

      【解决方案3】:

      对于 ArrayAdapter , notifyDataSetChanged 只有在适配器上使用 add() 、 insert() 、 remove() 和 clear() 时才有效。

      你可以这样做:

          @Override
      protected void onResume() {
          super.onResume();
          Refresh();
      }
      
      public void Refresh(){
           items = //response....
           CustomAdapter adapter = new CustomAdapter(MainActivity.this,items);
                 list.setAdapter(adapter);
      
             }
      

      在每个 onResume 活动上,它都会刷新列表。希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2011-03-23
        • 1970-01-01
        • 2021-11-16
        • 2023-03-18
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多