Почему вызываются фрагменты onCreateView, onCreate, onActivityCreated

у меня есть приложение, которое имеет дело с фрагментами и ViewPager. У меня есть три фрагмента на видовом экране. Когда вы переключаетесь между ними, это всегда заставляет другие два фрагмента вызывать свои методы onCreateView. Как это сделать только один раз, только когда создается FragmentActivity??? Я прочитал несколько вопросов и попробовал решения, но фрагменты все еще имеют одинаковое поведение.

ListFragment onCreate вызывается дважды
onCreate() и onCreateView() вызывает намного больше, чем требуется (фрагменты)

вот код, если он вам поможет, ребята:

MainActivity:

public class StartingActivity extends FragmentActivity implements View.OnClickListener {
ViewPager viewPager;
    CirclePageIndicator pageIndicator;

    Button discount;
    Button qrCode;
    Button pay;
    TabHost tabHost;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.starting_layout);
        viewPager = (ViewPager) findViewById(R.id.pager);

        if (savedInstanceState == null) {

            Fragment firstPage = Fragment.instantiate(this, FindTovarFragment.class.getName());
            Fragment secondPage = Fragment.instantiate(this, MainWindowActivity.class.getName());
            Fragment thirdPage = Fragment.instantiate(this, MapActivity.class.getName());

            if ((firstPage != null && !firstPage.isDetached())|| (secondPage != null && !secondPage.isDetached()) || (thirdPage != null && !thirdPage.isDetached())) {

            List<Fragment> viewPagerFragments = new ArrayList<Fragment>();
            viewPagerFragments.add(firstPage);
            viewPagerFragments.add(secondPage);
            viewPagerFragments.add(thirdPage);


            PageAdapter pageAdapter = new PageAdapter(getSupportFragmentManager(), viewPagerFragments);

            viewPager.setAdapter(pageAdapter);

            pageIndicator = (CirclePageIndicator) findViewById(R.id.circle);
            pageIndicator.setViewPager(viewPager);
            pageIndicator.setCurrentItem(pageAdapter.getCount() - 2);
            }
        }

}

MapActivity:

public class MapActivity extends Fragment implements OnMyLocationListener {

    //Тэг для логов
    private static final String TAG = "MapActivity";
    List<Address> addressList;
    private static final String STRING_LOCATION = "";

    ArrayList<TorgCentr> randomTorgCentr;
    ArrayList<String> torgCentrNames;

    Context context;
    AutoCompleteTextView searchTorgCentr;
    OverlayManager overlayManager;
    MapController mapController;
    TextView textView;
    double longitude;
    double latitude;
    double itemLongitude;
    double itemLatitude;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "MapActivity onCreateView");


        View view = (LinearLayout) inflater.inflate(R.layout.map_layout, container, false);
        final MapView mapView = (MapView) view.findViewById(R.id.map);
        textView = (TextView) view.findViewById(R.id.searchlocation);
        searchTorgCentr = (AutoCompleteTextView) view.findViewById(R.id.autoCompleteTextView);

        mapView.showBuiltInScreenButtons(true);
        mapController = mapView.getMapController();
        context = getActivity();
        return view;
    }

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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "MapActivity onCreate");

    }

    public void onActivityCreated(Bundle savedInstanceState) {
        Log.d(TAG, "MapActivity onActivityCreated");
        context = getActivity();

        SetRightMapDisplayAddress rightMapDisplayAddress = new SetRightMapDisplayAddress();
        rightMapDisplayAddress.execute(STRING_LOCATION);

        DownloadSuperMarketsArray superMarketsArray = new DownloadSuperMarketsArray();
        superMarketsArray.execute();

        overlayManager = mapController.getOverlayManager();
        overlayManager.getMyLocation().setEnabled(false);

        super.onActivityCreated(savedInstanceState);
    }

Второй Фрагмент:

public class MainWindowActivity extends Fragment {

    private static final String TAG = "MainWindowActivity";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "MainWindowActivity onCreateView");
        View view = (RelativeLayout) inflater.inflate(R.layout.main_window_layout, container, false);
        if (container == null) {
            return null;
        }
        return view;
    }
}

третий:

public class FindTovarFragment extends Fragment {

    private static final String TAG= "FindTovarFragment";

    Context context;
    ArrayList<Category> categories;
    Spinner categoryContainer;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "FindTovarFragment onCreateView");

        View view = (LinearLayout) inflater.inflate(R.layout.find_tovar_main_layout, container, false);
        categoryContainer = (Spinner) view.findViewById(R.id.category);

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "FindTovarFragment onActivityCreated");
        DownloadCategory downloadCategory = new DownloadCategory();
        downloadCategory.execute();
    }

журналы для MapActivity:

06-20 11:06:37.709: DEBUG/MapActivity(1290): MapActivity onCreate
06-20 11:06:37.709: DEBUG/MapActivity(1290): MapActivity onCreateView
06-20 11:06:38.509: DEBUG/MapActivity(1290): MapActivity onActivityCreated

потом снова и снова:

06-20 11:07:53.239: DEBUG/MapActivity(1290): MapActivity onCreate
06-20 11:07:53.239: DEBUG/MapActivity(1290): MapActivity onCreateView
06-20 11:07:53.429: DEBUG/MapActivity(1290): MapActivity onActivityCreated
06-20 11:08:23.029: DEBUG/MapActivity(1290): MapActivity onCreate
06-20 11:08:23.039: DEBUG/MapActivity(1290): MapActivity onCreateView
06-20 11:08:23.269: DEBUG/MapActivity(1290): MapActivity onActivityCreated

большое спасибо заранее.

3 ответов


Я бы изменил вашу архитектуру для этого в документации разработчика android:

http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html

но я бы изменил некоторые вещи...

1-я бы изменил этот метод:

/**
     * The Fragment's UI is just a simple text view showing its
     * instance number.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
        View tv = v.findViewById(R.id.text);
        ((TextView)tv).setText("Fragment #" + mNum);
        return v;
    }

для чего-то вроде этого, где мы решаем, какой фрагмент вы заполняете в зависимости от положения viewPager:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);

SupportFragmentManager ft = getChildFragmentManager().beginTransaction();

String tag = "";
Fragment fragment = null;

  switch (mNum) {
  case 0:
    fragment = new MyFragmentZero();
    tag = FragmentTags.TAG_0;
    break;
  case 1:
    fragment = new MyFragmentOne();
    tag = FragmentTags.TAG_3;
    break;
  case 2:
    fragment = new MyFragmentTwo();
    tag = FragmentTags.TAG_2;
    break;
  default:
    break;
  }

/*OPTIONAL We can pass arguments to the fragments
Bundle args = new Bundle();
args.putInt(Arguments.ARG_POSITION, mNum);
fragment.setArguments(args);*/

//Place the fragment in the container
ft.replace(R.id.fragment_container fragment, tag);
ft.commit();

//You need a base layout for all fragment and use nested fragments later or you can define the layout for each position(mNum) inside the switch.
return inflater.inflate(R.layout.fragment_layout_default_for_all_views, container,
    false);
}

Как это вы имейте хорошую архитектуру, и как только она будет работать, как это должно быть хорошо.

в любом случае вы должны знать, как работает viewPager, заполняя фрагмент в разных положениях.

когда вы начинаете на позиции 0, то фрагмент на позиции 0 и один из позиции 1 создаются.

затем, когда вы проводите пальцем по позиции 1, создается фрагмент на позиции 2, поэтому теперь у вас есть три фрагмента, созданные на разных позициях (0,1,2..если у вас есть только 3 страницы на viewPager).

мы проведите к позиции 2, Последний, и фрагмент на первой позиции (0) получить уничтожить, так что теперь у нас есть фрагменты на позициях 2 и 3.

Я надеюсь, что это помогло и дайте мне знать, если у вас есть какие-либо проблемы. Ура!--3-->


ViewPager сохранить в памяти 1 страницу по умолчанию, с обеих сторон текущей страницы. Таким образом, он не будет повторно создавать эти страницы при прокрутке 1 страницы влево/вправо от текущей страницы. Но когда проведите пальцем более 1 страницы влево / вправо, он снова создаст эту страницу, поэтому называется OnCreateView(), OnCreate().

Если приложение использует несколько страниц 3, Вы можете увеличить количество страниц для сохранения, позвонив,

mViewPager.setOffscreenPageLimit(2);

описал здесь


наконец-то я смог это понять. Просто нужно переопределить метод destroyItem, чтобы он не уничтожал объекты. Надеюсь, это кому-то пригодится.

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    Log.d(TAG, "destroy!");
}