首先,在内部执行此调用onViewCreated
代替onCreateView
:
sharedPrefManager = new SharedPrefManager(getActivity());
locationTrack = new LocationTrack(getActivity());
buildGoogleApiClient();
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
getUserLatLng();
setUp(view);
netWorkCall(); //this call has to be removed as explained later
为什么?因为 onCreateView 应该只返回片段 UI。之后会直接调用 OnViewCreated,这是做一些事情的地方。
不,解决你的问题。解决此问题的最佳方法是将架构组件中的 ViewModel 与 LiveData 结合使用。
您可以阅读有关此主题的更多信息here https://developer.android.com/topic/libraries/architecture/viewmodel#java.
您的实现可能如下所示(改编自链接中的示例):
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<User>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
在你的 onViewCreated 中你可以做这样的事情:
MyViewModel model = new ViewModelProvider(getViewLifecycleOwner()).get(MyViewModel.class);
model.getUsers().observe(getViewLifecycleOwner(), users -> {
// update UI
});
不要为此感到不知所措。它实际上所做的事情相对简单。 ViewModel 在配置更改后仍然存在。这意味着如果您旋转手机,将不会再次调用 loadUsers 请求 - 与在底部导航选项卡之间切换相同。当然,如果片段被销毁,ViewModel 也会被销毁(然后调用 onCleared 函数)。
LiveData 用户只是一个简单观察者的奇特名称。可变意味着你可以设置一个值,getUsers()返回一个不可变的LiveData,这意味着你只能读取它的值。当您为 LiveData 对象设置一个值时,它的订阅者将收到通知。您可以将其想象为 LiveData 是由使用 ViewModel 的 Fragment 实现的接口。一旦获取数据,就会调用此接口函数。有关处理 LiveData 的更多信息在这里解释 https://developer.android.com/topic/libraries/architecture/livedata你绝对应该检查一下。
因此,一旦您开始观察 getUsers(如果用户尚未加载),ViewModel 将调用 loadUsers。如果它们已被加载,则返回当前值。
哦,添加 LiveData 和 ViewModel ->这里有解释:) https://developer.android.com/topic/libraries/architecture/adding-components
希望这有帮助。我知道很多,但相信我,值得投入时间!