首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在对其他活动中的元素进行更改后更新Adapter列表中的元素?

如何在对其他活动中的元素进行更改后更新Adapter列表中的元素?
EN

Stack Overflow用户
提问于 2017-02-08 16:52:43
回答 3查看 734关注 0票数 2

我正在寻找Android中最好的实现模式来更新一个列表,当其中一个元素在不同的活动中发生变化时。

想象一下这个用户之旅:

异步进程从web服务器获取10 (10)个联系人配置文件。它们被放置在数组中,并通知适配器。现在,10 (10)个联系人配置文件显示在列表中。 用户单击联系人配置文件5 (5)。它打开了一个包含此联系人配置文件详细信息的活动。用户决定他们喜欢它,并点击‘添加到宠儿’。这将触发用户最喜欢的联系人配置文件5 (5)对web服务器的异步请求。 用户单击“后退”。他们现在又收到了这份名单。问题是列表现在已经过时了,并且没有显示出profile 5 (5)是最受欢迎的。

你是否:

  • 异步调用web服务器获取更新的数据,并通知适配器刷新整个列表。这似乎效率低下,因为对列表的调用可能需要几秒钟。
  • 在选择配置文件时,将对象存储在标记为“refresh”的某个地方(也许是在单例服务中)。列表活动中的OnResume是否嗅到变量并只更新列表中的元素。
  • 确保列表数组是静态可用的。从detail活动中更新数组。活动中的OnResume总是通知适配器进行刷新。
  • 确保列表数组和适配器是静态可用的。更新数组并从detail活动中通知适配器。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-09 13:02:01

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

就像你说的,它效率很低。在Android中创建对象是很昂贵的。创建多个对象的列表要昂贵得多。

在选择配置文件时,将对象存储在标记为“refresh”的某个地方(也许是在单例服务中)。列表活动中的OnResume是否嗅到变量并只更新列表中的元素。

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

确保列表数组是静态可用的。从detail活动中更新数组。活动中的OnResume总是通知适配器进行刷新。

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

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

与上述相同,静态变量或对象是“否”。

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

每当您单击'add to favourite'详细活动时,发送异步请求以更新web服务器上的宠儿,并向列表活动发送事件以更新特定的配置文件对象。例如,如果您的配置文件有id "777“,并且该概要文件在详细活动中最受欢迎,那么您需要在您的文件中发送类似于以下内容的事件:

代码语言:javascript
复制
btnFavourite.setOnClickListener(new View.OnClickListener() {
   public void onClick(View v) {               
     // Send event when click favourite.
     EventBus.getDefault.post(new RefreshProfileEvent(id, true);
   }
});

RefreshProfileEvent是一个简单的pojo:

代码语言:javascript
复制
public class RefreshProfileEvent {
  private String id;
  private boolean isFavourited;

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

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

代码语言:javascript
复制
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 )通知用户。

票数 0
EN

Stack Overflow用户

发布于 2017-02-08 17:01:14

第三个选项是最好的,当用户详细地更改数据时,数组应该被更改,然后当使用返回到主活动调用Adapter.notifyDataSetChanged();就可以了。

票数 0
EN

Stack Overflow用户

发布于 2017-02-08 17:10:41

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

你可以这样做:

代码语言:javascript
复制
    @Override
protected void onResume() {
    super.onResume();
    Refresh();
}

public void Refresh(){
     items = //response....
     CustomAdapter adapter = new CustomAdapter(MainActivity.this,items);
           list.setAdapter(adapter);

       }

在每个onResume活动中,它都会刷新列表。希望它能帮到你。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42119091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档