当前位置: 首页 > 知识库问答 >
问题:

如何在用户可见的情况下加载一个片段数据,并在加载一次后保留数据

陆洛城
2023-03-14

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

我已经检查了从下面提到的链接堆栈溢出的索洛。

请帮我做这个。我总共有5个碎片。在每个片段中,我都在fragment的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);

        }
    }
}

共有1个答案

戴靖
2023-03-14

试试这个:

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;
            }
        }
    }
 类似资料:
  • 我可以使用将显示为选项卡。 null 附言。这项功能存在于Twitter和Facebook的Android应用程序中。

  • 在我的应用程序中,我有一个ViewPager,里面有很多可滑动的标签,里面有碎片。我使用方法检测何时出现在屏幕上。当用户在选项卡之间滑动时,这非常有效,但它在第一次加载时不起作用。要运行该方法中的代码,我必须向左滑动,然后返回到第一个,因为方法是在方法之前调用的。 你有任何想法,我如何运行这段代码后,第一个片段是可见的吗?中有方法吗?

  • 场景我试图实现的目标: 使用两个框架容器加载活动(用于项目列表和详细信息) 在应用程序启动时,在listFrame中添加listFragment,在detailsFrame容器中添加一些初始infoFragment 在列表项中导航,而不将每个细节事务添加到后堆栈中(只希望在堆栈中保留infoFragment) 一旦用户点击后退按钮(向后导航),他就会返回到初始信息片段,即在启动时添加的信息片段 如

  • 我正在制作一个使用Kotlin和Firebase产品的Android应用程序。我与Firestore建立了成功的连接,并且可以成功地检索到我想要的数据,但是我很难在RecolyerView中显示它。 当应用程序加载并在用户登录之后,我的Firestore查询使用用户的UID来获取其分配的列表。使用日志,我可以看到,当主屏幕加载时,这种情况没有问题。在主屏幕片段中,我为RecyclerView绑定了

  • 本文向大家介绍js怎么控制一次加载一张图片,加载完后再加载下一张相关面试题,主要包含被问及js怎么控制一次加载一张图片,加载完后再加载下一张时的应答技巧和注意事项,需要的朋友参考一下 参考回答: (1)方法1 alert('图片的宽度为:'+obj.width+';图片的高度为:'+obj.height); (2)方法2    

  • 我使用了和。 但它一次加载两个页面。 有什么方法可以在viewpager中只加载一个页面吗?