我应该在哪里调用片段中的 Rest API
Where should I call Rest API in fragment
我正在对 3 个片段使用底部导航。在 Home-fragment 上,我请求 API 获取数据并在 recycler-view 中显示我的问题是每当我切换片段并再次回到 Home-fragment 时,它正在重新创建布局并再次从 API 我只想在应用启动时加载一次
This is where I call API in the fragment
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
// return inflater.inflate(R.layout.home_fragment, container, false);
sharedPrefManager = new SharedPrefManager(getActivity());
locationTrack = new LocationTrack(getActivity());
buildGoogleApiClient();
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
getUserLatLng();
setUp(view);
netWorkCall();
return view;
}
HomeActivity to load home-fragment by default
if (savedInstanceState == null) {
Fragment fragment = null;
fragment = new HomeFragment();
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.content_frame, fragment, "home").addToBackStack("Home");
ft.commit();
}
}
bottom-navigation click listener
private void displaySelectedScreen(int itemId) {
Fragment fragment = null;
switch (itemId) {
case R.id.action_home:
fragment = new HomeFragment();
break;
case R.id.action_profile:
if (sharedPrefManager.getAuthority()) {
fragment = new ProfileFragment();
} else {
SDConstant.switchActivity(this, LoginScreen.class);
}
break;
case R.id.action_calculator:
if (sharedPrefManager.getAuthority()) {
fragment = new CalculatorFragment();
} else {
SDConstant.switchActivity(this, LoginScreen.class);
}
break;
}
//replacing the fragment
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment, "home").addToBackStack("Home");
ft.commitAllowingStateLoss();
//ft.commitNow();
}
}
}
Please guide me solution How to solve this re-creation API call
首先,在 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 应该只是 return 片段 UI。之后直接调用 OnViewCreated,这是做一些事情的地方。
不解决你的问题。解决此问题的最佳方法是将架构组件中的 ViewModel 与 LiveData 结合使用。
您可以阅读有关此主题的更多信息 here。
您的实施可能如下所示(改编自 link 中的示例):
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 在配置更改后仍然存在。这意味着如果您旋转 phone 将不会再次调用 loadUsers 请求 - 与底部导航选项卡之间的切换相同。当然,如果片段被销毁,ViewModel 也会被销毁(然后调用函数 onCleared)。
LiveData 用户对于普通观察者来说只是一个奇特的名字。可变意味着你可以设置一个值,getUsers() return 是一个非可变的 LiveData,这意味着你只能读取它的值。当您为 LiveData 对象设置值时,它的订阅者将收到通知。你可以把它想象成 LiveData 是一个由使用 ViewModel 的 Fragment 实现的接口。一旦您获取了数据,就会调用此接口函数。有关处理 LiveData 的更多信息 is explained here 您一定要检查一下。
因此,如果尚未加载用户,一旦您开始观察 getUsers,ViewModel 将调用 loadUsers。如果已加载,则当前值为 returned。
哦,还有添加 LiveData 和 ViewModel -> it's explained here :)
希望这对您有所帮助。我知道很多,但相信我,值得投入时间!
我正在对 3 个片段使用底部导航。在 Home-fragment 上,我请求 API 获取数据并在 recycler-view 中显示我的问题是每当我切换片段并再次回到 Home-fragment 时,它正在重新创建布局并再次从 API 我只想在应用启动时加载一次
This is where I call API in the fragment
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
// return inflater.inflate(R.layout.home_fragment, container, false);
sharedPrefManager = new SharedPrefManager(getActivity());
locationTrack = new LocationTrack(getActivity());
buildGoogleApiClient();
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
getUserLatLng();
setUp(view);
netWorkCall();
return view;
}
HomeActivity to load home-fragment by default
if (savedInstanceState == null) {
Fragment fragment = null;
fragment = new HomeFragment();
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.content_frame, fragment, "home").addToBackStack("Home");
ft.commit();
}
}
bottom-navigation click listener
private void displaySelectedScreen(int itemId) {
Fragment fragment = null;
switch (itemId) {
case R.id.action_home:
fragment = new HomeFragment();
break;
case R.id.action_profile:
if (sharedPrefManager.getAuthority()) {
fragment = new ProfileFragment();
} else {
SDConstant.switchActivity(this, LoginScreen.class);
}
break;
case R.id.action_calculator:
if (sharedPrefManager.getAuthority()) {
fragment = new CalculatorFragment();
} else {
SDConstant.switchActivity(this, LoginScreen.class);
}
break;
}
//replacing the fragment
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment, "home").addToBackStack("Home");
ft.commitAllowingStateLoss();
//ft.commitNow();
}
}
}
Please guide me solution How to solve this re-creation API call
首先,在 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 应该只是 return 片段 UI。之后直接调用 OnViewCreated,这是做一些事情的地方。
不解决你的问题。解决此问题的最佳方法是将架构组件中的 ViewModel 与 LiveData 结合使用。
您可以阅读有关此主题的更多信息 here。
您的实施可能如下所示(改编自 link 中的示例):
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 在配置更改后仍然存在。这意味着如果您旋转 phone 将不会再次调用 loadUsers 请求 - 与底部导航选项卡之间的切换相同。当然,如果片段被销毁,ViewModel 也会被销毁(然后调用函数 onCleared)。
LiveData 用户对于普通观察者来说只是一个奇特的名字。可变意味着你可以设置一个值,getUsers() return 是一个非可变的 LiveData,这意味着你只能读取它的值。当您为 LiveData 对象设置值时,它的订阅者将收到通知。你可以把它想象成 LiveData 是一个由使用 ViewModel 的 Fragment 实现的接口。一旦您获取了数据,就会调用此接口函数。有关处理 LiveData 的更多信息 is explained here 您一定要检查一下。
因此,如果尚未加载用户,一旦您开始观察 getUsers,ViewModel 将调用 loadUsers。如果已加载,则当前值为 returned。
哦,还有添加 LiveData 和 ViewModel -> it's explained here :)
希望这对您有所帮助。我知道很多,但相信我,值得投入时间!