在fragment中我应该在哪里调用Rest API

问题描述 投票:0回答:1

我在使用Bottom-navigation,有3个片段,在Home-fragment上,我请求API获取数据并显示在recycler-view中。在Home-fragment上,我请求API获取数据并显示在recycler-view中,我的问题是,每当我切换fragment并再次来到Home-fragment时,它就会重新创建布局,并再次从API获取数据,我希望在应用程序启动时只加载一次。

这是我在片段中调用API的地方。

  @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默认加载主页片段。

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();
            }
        }

底部导航点击监听

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();
            }
    }
    }

请指导我解决如何解决这个再创API调用的问题

java android android-fragments fragment retrofit2
1个回答
1
投票

首先,在里面执行这个调用 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结合。

你可以阅读更多关于这个主题的内容 此处.

你的实现可以是这样的(改编自链接中的例子)。

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用户只是一个简单的观察者的花名。Mutable意味着你可以设置一个值,getUsers()返回一个不可变的LiveData,这意味着你只能读取它的值。当你给LiveData对象设置一个值时,它的订阅者会被通知。你可以把它想象成LiveData是你的Fragment植入的一个接口,而Fragment是使用ViewModel的。而这个接口的功能是在你取到数据后调用的。更多关于处理LiveData的信息 在此说明 你一定要检查一下。

所以,如果Users还没有被加载,一旦开始观察getUsers,ViewModel将调用loadUsers。如果他们已经被加载,则返回当前值。

哦,要添加LiveData和ViewModel-&gt.,在这里有解释:)。这里有解释:)

希望这对你有帮助。我知道这是一个很大的问题,但相信我,这是值得投入时间的!我知道这是一个很大的问题,但相信我,这是值得投入时间的。

© www.soinside.com 2019 - 2024. All rights reserved.