片段在彼此之上显示两次

时间:2015-02-23 08:25:46

标签: android android-activity android-fragments fragment

我在我的活动中显示片段,但似乎有些片段正在显示(实例化)两次。我仔细检查我的代码,但在我看来一切都应该没问题。问题是当我向片段显示它没问题时,但是在显示另一个片段并显示相同的片段之后,就像重新加载再次调用相同的片段一样,它显示更新的数据 - 尽管没有进行数据更新。

这就是我称之为片段的方式:

public void showFragment(Fragment fragment, Bundle bundle) {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        fragment.setRetainInstance(true);
        //TODO animation
        if (!fragment.isVisible()) {
            //  ft.setCustomAnimations(R.anim.slide_in, R.anim.slide_out, R.anim.slide_in, R.anim.slide_out);
            fragment.setArguments(bundle);
            ft.replace(R.id.main_frag_container, fragment);
            ft.commit();
        }
        dismissLoading();
    }

这是我的一个片段:

import android.app.Fragment;
public class ProductFragment extends Fragment implements AdapterView.OnItemClickListener, AdapterView.OnItemSelectedListener {
        private final String TAG = ProductFragment.class.getSimpleName();

        private View view;

        private int index = -1;
        private int top = 0;

        private Spinner categorySpinner;
        private ListView listView;
        private ArrayAdapter<CharSequence> cityAdapter, categoryAdapter;
        private ArrayList<Product> items;
        private ProductsAdapter adapter;


        private OnProductSelected productSelectedListener;

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if (activity != null) {
                productSelectedListener = (OnProductSelected) activity;
            }
        }

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            super.onCreateView(inflater, container, savedInstanceState);
            view = inflater.inflate(R.layout.fragment_products, container, false);
            Log.d(TAG, "PROducts frag started " + getArguments().getSerializable(ActivityConstants.PRODUCT_ITEMS));
            listView = (ListView) view.findViewById(R.id.products_listView);

            if (getArguments().getSerializable(ActivityConstants.PRODUCT_ITEMS) != null) {
                loadList((ArrayList<Product>) getArguments().getSerializable(ActivityConstants.PRODUCT_ITEMS));
            }

            initWidgets(view);
            return view;
        }

        public void loadList(ArrayList<Product> data) {
            items = data;
            adapter = new ProductsAdapter(getActivity(), items);
            Log.d(TAG, "ITEMS SIZE" + items.size());
            listView.setAdapter(adapter);

        }

        @Override
        public void onPause() {
            super.onPause();
            try {
                index = listView.getFirstVisiblePosition();
                View v = listView.getChildAt(0);
                top = (v == null) ? 0 : v.getTop();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        @Override
        public void onResume() {
            super.onResume();

    //        setListAdapter(mAdapter);
            if (index != -1) {
                listView.setSelectionFromTop(index, top);
            }


        }

        /**
         * Initialize fragment widgets
         */
        private void initWidgets(View view) {
            categorySpinner = (Spinner) view.findViewById(R.id.products_spinner_cat);
            getActivity().invalidateOptionsMenu();
            ((MainActivity) getActivity()).initActionBar(true);
            listView.setOnItemClickListener(this);

            //set citySpinner adapter
            cityAdapter = ArrayAdapter.createFromResource(getActivity(),
                    R.array.cities, android.R.layout.simple_spinner_item);
            cityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

            //set categorySpinner adapter
            categoryAdapter = ArrayAdapter.createFromResource(getActivity(),
                    R.array.categores, android.R.layout.simple_spinner_item);
            categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            categorySpinner.setAdapter(categoryAdapter);
            categorySpinner.setOnItemSelectedListener(this);

            categorySpinner.setSelection(0);
            ((MainActivity) getActivity()).dismissLoading();
            Log.d(TAG, "Fragment inited");
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Log.d(TAG, "onItemClick " + position);
            productSelectedListener.onProductSelected(items.get(position));
        }

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Log.d(TAG, "POSITION " + position);

            if (position == 0) {
                position += 1;
            }
            getListing(getResources().getStringArray(R.array.categores)[position].toLowerCase());


        }


        private void getListing(String category) {
            AppHttpClient.getInstance();
            String serverURL = ServerUtil.SERVER_BASE_URL + ServerUtil.PRODUCTS + category;
            Log.d(TAG, "Server url: " + serverURL);
            AppHttpClient.executeMethod(ServerUtil.METHOD_GET_PRODUCTS, serverURL, null, getActivity());
        }


        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            Log.d(TAG, parent.getId() + " ");
        }

    }

有人可以帮我解决这个问题吗? 谢谢!

2 个答案:

答案 0 :(得分:1)

首先将视图设为静态,然后将代码粘贴到片段中的onCreateView中。

private static View view=null;

if (view == null) {
            view = inflater.inflate(R.layout.fragment_movies, container, false);

            //code here for first time initialization
        } else if (view != null) {
            //your code here
        }

答案 1 :(得分:0)

如果您使用您发布的代码从一个片段切换到另一个片段,我会说它可能来自您如何获得传递给showFragment()方法的片段。如果在将新片段传递给showFragment()之前创建新片段,则通常会创建新片段并将其添加到其他片段之上。

你应该使用getFragmentManager()。findFragmentByTag(String Tag)来获取已经存在的片段并将其重新添加到Fragment堆栈之上。