web-dev-qa-db-fra.com

Pourquoi les fragments onCreateView, onCreate, onActivityCreated du fragment sont-ils appelés

J'ai une application qui traite des fragments et ViewPager. J'ai trois fragments dans un ViewPager. Lorsque vous basculez entre eux, les deux autres fragments appellent toujours leurs méthodes onCreateView. Comment le faire une seule fois, uniquement lorsque FragmentActivity est créé ??? J'ai lu quelques questions et essayé les solutions, mais les fragments ont toujours le même comportement.

ListFragment onCreate appelé deux fois
onCreate () et onCreateView () invoque beaucoup plus que nécessaire (Fragments)

Voici du code, si cela peut vous aider, les gars:

Activité principale:

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

Deuxième fragment:

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

Et le troisième:

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

Journaux pour 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

Encore et encore:

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

Merci beaucoup d'avance.

26
PAcan

Je changerais votre architecture pour celle-ci dans la documentation du développeur Android:

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

mais je changerais certaines choses ...

1-Je changerais cette méthode:

/**
     * 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;
    }

Pour quelque chose comme ça où nous décidons quel fragment vous remplissez en fonction de la position du 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);
}

Comme ça, vous aurez une bonne architecture et une fois que cela fonctionnera, ça devrait aller.

Quoi qu'il en soit, vous devez savoir comment fonctionne le viewPager en remplissant le fragment dans les différentes positions.

Lorsque vous démarrez sur la position 0, alors le fragment sur la position 0 et celui de la position 1 sont créés.

Ensuite, lorsque vous glissez vers la position 1, le fragment sur la position 2 est créé, vous avez donc maintenant les trois fragments créés sur les différentes positions (0,1,2..en supposant que vous n'avez que 3 pages sur le viewPager).

Nous glissons vers la position 2, la dernière, et le fragment sur la première position (0) est détruit, nous avons donc maintenant les fragments sur les positions 2 et 3.

J'espère que cela a aidé et faites-moi savoir si vous avez un problème. À votre santé

12
jpardogo

ViewPager conserve en mémoire 1 page par défaut, de part et d'autre de la page en cours. Ainsi, il ne recréerait pas ces pages lorsque vous balayez 1 page à gauche/à droite de la page actuelle. Mais lorsque vous balayez plus de 1 pages vers la gauche/la droite, cela recréerait ces pages à nouveau, d'où le nom de OnCreateView (), OnCreate ().

Si l'application utilise peu de pages 3, vous pouvez augmenter le nombre de pages à conserver en appelant,

mViewPager.setOffscreenPageLimit(2);

Décrit ici

15
Annada

Enfin, j'ai pu le comprendre. Il suffit de remplacer la méthode destroyItem afin qu'elle ne détruise pas les objets. J'espère que cela va être utile pour quelqu'un.

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