在 ViewModel 中加载已在 SplashActvity 中检索到的数据
Loading data in ViewModel that have been retrieved in SplashActvity
我是 ViewModel 的新手,我知道这是一种与片段通信的强大而简单的方法。
我的问题如下:如何在 mainActivity 的 ViewModel 中加载在 SplashActivity 中检索到的数据?
我的应用程序架构如下:
- SplashActivity : 通过改造检索数据并将其存储到列表中
- Main Activity : 包含两个以不同方式显示数据的片段
这里有一段代码展示了我的实现。
飞溅Activity
public class SplashActivity extends AppCompatActivity {
private final String TAG = "TAG.SplashActivity";
public static List<Toilet> toiletList = new ArrayList<>(); // HERE IS THE DATA I WANT TO
RETRIEVE IN THE MAIN ACTIVITY
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*Create handle for the RetrofitInstance interface*/
GetDataService service = ...;
// MY STUFF RETROFIT including
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("toiletList", (Serializable) toiletList);
startActivity(intent);
finish();
}
}
主要Activity
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = getClass().getName();
private List<Toilet> toiletList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= getIntent();
Serializable s = intent.getSerializableExtra("toiletList");
// Check type and cast
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
// SETTING UP FRAGMENTS
}
}
片段示例
public class MainFragment extends Fragment {
public static List<Toilet> toiletArrayList = new ArrayList<>();
private final String TAG = this.getClass().getName();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
// SETTING UP UI
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);
model.getToiletList().observe(this, new Observer<List<Toilet>>() {
@Override
public void onChanged(@Nullable List<Toilet> toilets) {
// update UI
}
});
}
}
ToiletListViewModel
public class ToiletListViewModel extends ViewModel {
private final String TAG = getClass().getName();
private MutableLiveData<List<Toilet>> toiletList;
public LiveData<List<Toilet>> getToiletList() {
if (toiletList == null) {
toiletList = new MutableLiveData<>();
loadToilets();
}
return toiletList;
}
private void loadToilets() {
// asynchronously fetch toilets
// HERE IS MY PROBLEM : How to access the toiletList retrieved
in the SplashActivity ?
toiletList.setValue(SplashActivity.toiletList);
}
@Override
protected void onCleared() {
super.onCleared();
Log.d(TAG, "onCleared() called");
}
}
我希望这很清楚。如果您想了解更多信息,请随意询问!
最佳
您可以 share 您的 ToiletListViewModel
在 MainActivity
和它的 Fragment
之间。
所以您需要为 ViewModel
提供 MainActivity
范围(这意味着您将 ViewModel
的生命周期绑定到 Activity)并调用 initToilets
然后子片段可以轻松检索此 ViewModel
并观察其 LiveData
.
ToiletListViewModel:
public class ToiletListViewModel extends ViewModel {
private MutableLiveData<List<Toilet>> toiletList = new MutableLiveData();
public LiveData<List<Toilet>> getToiletList() {
return toiletList;
}
private void initToilets(List<Toilet> toilets) {
toiletList.setValue(toilets);
}
}
主要Activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = getClass().getName();
private List<Toilet> toiletList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= getIntent();
Serializable s = intent.getSerializableExtra("toiletList");
// Check type and cast
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
ToiletListViewModel vm = ViewModelProviders.of(this).get(ToiletListViewModel.class);
vm.initToilets(toiletList);
// SETTING UP FRAGMENTS
}
}
所以,当setValue
被调用时,监听toiletList
实时数据的片段将被通知。
注:
您可以创建共享 ViewModel
而无需在 MainActivity
上提供它,而不是调用
ViewModelProviders.of(this).get(ToiletListViewModel.class);
在你的片段中做
ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);
有两个建议:
可以直接添加数据到列表(题外话):
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
用这个代替:
if (s instanceof List<?>) {
toiletList.addAll((List<Toilet>)s);
}
返回正题:
您可以使用 Activity 的 ViewModel
个实例来代替 Fragment
中的这个实例。怎么样?
取activity中的ViewModel
如下,
ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);
& for Fragment
像这样分享,
ToiletListViewModel model = ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);
这将在 activity 内的片段之间分享您的 ViewModel
并观察您的 livedata
。
为了使用视图模型,您需要在活动中存储对其实例的引用,然后与它们交互以修改数据。
首先我建议您阅读 developer guide on View Model。
当您在活动和片段中设置并存储对模型的引用时,您可以向模型添加一个方法,例如 setToilets(List<Toilet>)
,它更新视图模型中的厕所,调用loadToilets()
或存储原始厕所,以便 loadToilets()
以后可以访问它,现在可以加载哪些厕所。
然后,您可以通过编写相应的方法来访问要从其他 类 公开的所有数据,就像您使用 getToiletList(LiveData<Toilet>)
方法所做的那样。
我是 ViewModel 的新手,我知道这是一种与片段通信的强大而简单的方法。
我的问题如下:如何在 mainActivity 的 ViewModel 中加载在 SplashActivity 中检索到的数据?
我的应用程序架构如下:
- SplashActivity : 通过改造检索数据并将其存储到列表中
- Main Activity : 包含两个以不同方式显示数据的片段
这里有一段代码展示了我的实现。
飞溅Activity
public class SplashActivity extends AppCompatActivity {
private final String TAG = "TAG.SplashActivity";
public static List<Toilet> toiletList = new ArrayList<>(); // HERE IS THE DATA I WANT TO
RETRIEVE IN THE MAIN ACTIVITY
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*Create handle for the RetrofitInstance interface*/
GetDataService service = ...;
// MY STUFF RETROFIT including
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("toiletList", (Serializable) toiletList);
startActivity(intent);
finish();
}
}
主要Activity
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = getClass().getName();
private List<Toilet> toiletList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= getIntent();
Serializable s = intent.getSerializableExtra("toiletList");
// Check type and cast
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
// SETTING UP FRAGMENTS
}
}
片段示例
public class MainFragment extends Fragment {
public static List<Toilet> toiletArrayList = new ArrayList<>();
private final String TAG = this.getClass().getName();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
// SETTING UP UI
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);
model.getToiletList().observe(this, new Observer<List<Toilet>>() {
@Override
public void onChanged(@Nullable List<Toilet> toilets) {
// update UI
}
});
}
}
ToiletListViewModel
public class ToiletListViewModel extends ViewModel {
private final String TAG = getClass().getName();
private MutableLiveData<List<Toilet>> toiletList;
public LiveData<List<Toilet>> getToiletList() {
if (toiletList == null) {
toiletList = new MutableLiveData<>();
loadToilets();
}
return toiletList;
}
private void loadToilets() {
// asynchronously fetch toilets
// HERE IS MY PROBLEM : How to access the toiletList retrieved
in the SplashActivity ?
toiletList.setValue(SplashActivity.toiletList);
}
@Override
protected void onCleared() {
super.onCleared();
Log.d(TAG, "onCleared() called");
}
}
我希望这很清楚。如果您想了解更多信息,请随意询问!
最佳
您可以 share 您的 ToiletListViewModel
在 MainActivity
和它的 Fragment
之间。
所以您需要为 ViewModel
提供 MainActivity
范围(这意味着您将 ViewModel
的生命周期绑定到 Activity)并调用 initToilets
然后子片段可以轻松检索此 ViewModel
并观察其 LiveData
.
ToiletListViewModel:
public class ToiletListViewModel extends ViewModel {
private MutableLiveData<List<Toilet>> toiletList = new MutableLiveData();
public LiveData<List<Toilet>> getToiletList() {
return toiletList;
}
private void initToilets(List<Toilet> toilets) {
toiletList.setValue(toilets);
}
}
主要Activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private final String TAG = getClass().getName();
private List<Toilet> toiletList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= getIntent();
Serializable s = intent.getSerializableExtra("toiletList");
// Check type and cast
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
ToiletListViewModel vm = ViewModelProviders.of(this).get(ToiletListViewModel.class);
vm.initToilets(toiletList);
// SETTING UP FRAGMENTS
}
}
所以,当setValue
被调用时,监听toiletList
实时数据的片段将被通知。
注:
您可以创建共享 ViewModel
而无需在 MainActivity
上提供它,而不是调用
ViewModelProviders.of(this).get(ToiletListViewModel.class);
在你的片段中做
ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);
有两个建议:
可以直接添加数据到列表(题外话):
if (s instanceof List<?>) {
for (Object o : (List<?>) s) {
if (o instanceof Toilet) {
toiletList.add((Toilet) o);
}
}
}
用这个代替:
if (s instanceof List<?>) {
toiletList.addAll((List<Toilet>)s);
}
返回正题:
您可以使用 Activity 的 ViewModel
个实例来代替 Fragment
中的这个实例。怎么样?
取activity中的ViewModel
如下,
ToiletListViewModel model = ViewModelProviders.of(this).get(ToiletListViewModel.class);
& for Fragment
像这样分享,
ToiletListViewModel model = ViewModelProviders.of(getActivity()).get(ToiletListViewModel.class);
这将在 activity 内的片段之间分享您的 ViewModel
并观察您的 livedata
。
为了使用视图模型,您需要在活动中存储对其实例的引用,然后与它们交互以修改数据。
首先我建议您阅读 developer guide on View Model。
当您在活动和片段中设置并存储对模型的引用时,您可以向模型添加一个方法,例如 setToilets(List<Toilet>)
,它更新视图模型中的厕所,调用loadToilets()
或存储原始厕所,以便 loadToilets()
以后可以访问它,现在可以加载哪些厕所。
然后,您可以通过编写相应的方法来访问要从其他 类 公开的所有数据,就像您使用 getToiletList(LiveData<Toilet>)
方法所做的那样。