将实际数据保留在应用程序中的最佳方式

Best way to keep actual data in application

我在应用程序中遇到了一些数据相关性问题。

在我们的应用程序中,我们有 1 个 activity 和许多片段。

例如,我们有 1 个片段,其中包含用户列表和点赞按钮(具有 3 种状态:none/like/favorite)。 在下一页中,我们也有用户和喜欢按钮的完整描述。 如果我们在 userList 中按下 like 按钮,就不会有问题,在详细信息屏幕中我们会看到正确的 like 状态。但是如果我们在用户详细信息中单击喜欢按钮并返回列表,这里仍然有过去的数据。

我们不能使用 activityForResult 因为片段。

我们使用 rx,也许有一些方法可以轻松解决这个问题?

为了重用 Fragment UI 组件,您应该将每个组件构建为一个完全独立的模块化组件,定义自己的布局和行为。然后每个 Fragment 可以向 Activity 发送数据,并且 Activity 也可以向 Fragment 发送数据。

在您的情况下,Activity 可以保存实际数据。当用户在细节 Fragment 中修改某些内容时,Fragment 应该将其告知 ActivityActivity,然后依次通知列表Fragment.

实际上,您可以对片段使用 onActivityResult() 方法。这种模式我在不同的项目中见过几次,由你决定它是否适合你。

假设您的左侧片段是 AFragment,您的右侧片段是 BFragment,思路如下。

(1) 在 AFragment 中,在提交从 A 到 B 的事务之前设置目标片段:

Fragment bFragment = new BFragment();
bFragment.setTargetFragment(this, 42); // `this` is your AFragment instance
// transact here

(2) 提供onActivityResult():

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // your logic here
}

(3) 在 BFragment 中,在 onDetach() 中准备数据并在目标上调用 onActivityResult()

@Override
public void onDetach() {
    super.onDetach();

    if (getTargetFragment() != null) {
        Intent data = new Intent();
        // pass your data here

        getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, data);
    }
}

这样,每当 BFragment 弹出时,您的 AFragment 就有机会处理它的数据。

我在我的应用程序中处理这种情况的方法是使用中央 "repository" SharedPreferences 跨多个屏幕存储序列化数据。然后,每次创建或恢复新的 Activity(或者在您的情况下为 Fragment)时,它都会进入序列化数据存储库以填充其共享数据。

这就是我想象的在您的情况下会起作用的方式。要使用您的 "user" 示例,我将创建一个 SharedPreferences 文件来存储我的用户数据对象列表。所以我会有一个 class 来存储我需要了解的有关用户的所有信息——他们的信息、他们的 "like" 状态等。

假设我在某处的列表中有用户,我将使用 Gson 对其进行序列化,并将序列化数据保存到我创建的 SharedPreferences 中。然后,每个 Fragment 只需轮询序列化数据即可获取用户的当前状态。如果进行了某些更改,每个 Fragment 会将数据保存回同一个 SharedPreferences 文件,以便其他 Fragment 可以使用它来实例化它们的视图。

这是一些伪代码...

//Some kind of data class for User
class MyUser {
    String name;
    String location;
    String likeStatus;
    //... whatever else
}

然后,假设您在某处有一个用户列表,我将序列化该列表并将其存储在全局 SharedPreferences 文件中,如下所示...

//ArrayList<MyUser> users <- defined somewhere
Gson gson = new Gson();
String usersJson = gson.toJson(users);
SharedPreferences userPrefs = getSharedPreferences("users_storage", MODE_PRIVATE);
SharedPreferences.Editor editor = userPrefs.edit();
editor.putString("users_data_key", usersJson);
editor.apply();

然后当一个新的 Fragment 被加载并且它需要知道用户的当前状态时,它只需打开 SharedPreferences 文件并获取所有内容的当前状态,就像这样...

SharedPreferences userPrefs = getSharedPreferences("users_storage", MODE_PRIVATE);
String usersJson = userPrefs.getString("users_data_key", null);

Type collectionType = new TypeToken<ArrayList<MyUser>>(){}.getType();
ArrayList<MyUser> users = gson.fromJson(usersJson, collectionType);

明确一点,这种方法将全部在您的 Activity 中完成,当您开始一个新的 Fragment 时,您只需传入正确实例化所需的数据。然后,如果一个Fragment需要保存数据,它会简单地调用你的Activity的方法并将需要保存的数据传递给它,你的Activity会执行上面的代码来保存它.