如何在用户可见时加载一个片段数据并在加载一次后保留数据

How to load one fragment data when it is visible to user and keep the data after loading once

我使用了 setUserVisibleHint() 方法来加载数据,但是这个方法在 oncreateview 之前调用,所以我得到了 NPE。

我已经从下面提到的链接中检查了堆栈溢出的解决方案。

setUserVisibleHint called before onCreateView in Fragment

setUserVisibleHint with Fragments for android

我想在片段对用户可见时加载数据,我想在加载后保持数据原样once.It滑动到下一个片段后不应清除。

请帮我解决这个问题。 我总共有5个片段。 在每个片段中,我在 fragment.Here 的 onCreateView 方法中进行服务器调用是一个片段的样本。

    package com.geelani.sestoauto.list;


import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.example.taha.myapplication.backend.model.pricesApi.model.Prices;
import com.example.taha.myapplication.backend.model.specsPricesApi.SpecsPricesApi;
import com.example.taha.myapplication.backend.model.specsPricesApi.model.CollectionResponseSpecsPrices;
import com.example.taha.myapplication.backend.model.specsPricesApi.model.SpecsPrices;
import com.geelani.sestoauto.MainActivity;
import com.geelani.sestoauto.R;
import com.geelani.sestoauto.async.GenericAsyncTaskList;
import com.geelani.sestoauto.async.ResponseListener;
import com.geelani.sestoauto.utils.Constants;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.json.gson.GsonFactory;

import java.util.ArrayList;
import java.util.HashMap;


/**
 * A simple {@link Fragment} subclass that shows a list of featured lists a user can see.
 * Use the {@link SpecsFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class SpecsFragment extends Fragment implements ResponseListener {

    private String title;
    private String location;
    private ProgressBar mProgBar;
    private SpecsAdapter mAdapter;
    private CollectionResponseSpecsPrices specs;
    private ArrayList<SpecsPrices> items = new ArrayList();
    private ArrayList<Prices> items1 = new ArrayList();
    private Context mContext;
    private ImageView handler;
    ListView listView;
    SharedPreferences getPrefs;
    private boolean isViewShown = false;


    public SpecsFragment() {
        /* Required empty public constructor */
    }


    /**
     * Create fragment and pass bundle with data as it's arguments
     */
    public static SpecsFragment newInstance(String title, String location) {
        SpecsFragment fragment = new SpecsFragment();
        Bundle args = new Bundle();
        args.putString(Constants.TITLES, title);
        args.putString(Constants.LOCATION, location);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getView() != null) {
            isViewShown = true;
            // fetchdata() contains logic to show data when page is selected mostly asynctask to fill the data
            listSpecs();
        } else {
            isViewShown = false;
        }
    }

    /**
     * Initialize instance variables with data from bundle
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            title = getArguments().getString(Constants.TITLES);
            location = getArguments().getString(Constants.LOCATION);
            //       Log.d("location",location.toString());
            if (!isViewShown) {
                listSpecs();
            }

        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mContext = getContext();
        View mView = inflater.inflate(R.layout.fragment_specifications, container, false);
        getPrefs = PreferenceManager
                .getDefaultSharedPreferences(mContext);
        if (getPrefs.getString(Constants.CITY, null) == null) {

            searchCitiesList();

        }
        RecyclerView mRecy = (RecyclerView) mView.findViewById(R.id.rv_ff);
        mProgBar = (ProgressBar) mView.findViewById(R.id.prog_bar_ff);
        handler = (ImageView) mView.findViewById(R.id.handler);
        mRecy.setLayoutManager(new LinearLayoutManager(getContext()));


        mAdapter = new SpecsAdapter(mContext);
        mRecy.setAdapter(mAdapter);
        listSpecs();
        return mView;
    }

    private void listSpecs() {

        mProgBar.setVisibility(View.VISIBLE);
        SpecsPrices specs = new SpecsPrices();
        SpecsPricesApi api = new
                SpecsPricesApi(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null
        );
        GenericAsyncTaskList<SpecsPricesApi, SpecsPrices, SpecsFragment> asyncTask = new GenericAsyncTaskList<SpecsPricesApi, SpecsPrices, SpecsFragment>(
                api,
                specs,
                this,
                getActivity(),
                null,
                title,
                "make",
                "basemodel",
                "Mumbai",
                Constants.LIST_SPECSPRICES,
                "false"
        );
        asyncTask.execute();

    }


    public void searchCitiesList() {
        final Dialog dialog = new Dialog(mContext);
        dialog.setContentView(R.layout.select_city);
        dialog.setTitle("Select City");
        listView = (ListView) dialog.findViewById(R.id.list1);

        String[] values = new String[]{"Mumbai", "New Delhi", "Bangalore", "Pune", "Chennai", "Kolkata", "Hyderabad", "Ahmedabad", "Chandigarh", "Gurgaon"
                , "Noida", "Navi-Mumbai", "Thane", "Cochin", "Faridabad", "Ghaziabad"};
        dialog.show();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,
                R.layout.listcity, R.id.city1, values);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                int itemPosition = position;
                String itemValue = (String) listView
                        .getItemAtPosition(position);
                SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
                SharedPreferences.Editor editor = settings.edit();
                editor.putString(Constants.CITY, itemValue);
                editor.commit();
                // Show Alert
                Toast.makeText(
                        mContext,
                        "selected" + itemValue, Toast.LENGTH_LONG).show();
                dialog.cancel();

            }

        });
    }

    /**
     * Updates the order of mListView onResume to handle sortOrderChanges properly
     */
    @Override
    public void onResume() {
        super.onResume();


    }

    /**
     * Cleanup the adapter when activity is paused.
     */
    @Override
    public void onPause() {
        super.onPause();
    }


    @Override
    public void processlistener(String type, Object result) {
        if (type.contentEquals(Constants.LIST_SPECSPRICES)) {
            specs = (CollectionResponseSpecsPrices) result;
            items = (ArrayList<SpecsPrices>) specs.getItems();
            mProgBar.setVisibility(View.GONE);
            mAdapter.addItems(items, items1, title);
            //listprices();
        } else {
            handler.setVisibility(View.VISIBLE);
            mProgBar.setVisibility(View.GONE);

        }
    }
}

试试这个:

private boolean _hasLoadedOnce = false; // your boolean field

    @Override
    public void setUserVisibleHint(boolean isFragmentVisible_) {
        super.setUserVisibleHint(true);

        if (this.isVisible()) {
            // we check that the fragment is becoming visible
            if (isFragmentVisible_ && !_hasLoadedOnce) {
                if (global.isNetworkAvailable()) {

                    listSpecs();

                }
                _hasLoadedOnce = true;
            }
        }
    }