2016-11-03 10 views
1

У меня есть фрагмент с картой. Я могу открыть еще один фрагмент (назовите его listfragment) из панели действий, он отлично работает. Но если я поворачиваю экран, а затем пытаюсь открыть список, то он не загружается, вместо этого mapview мерцает вовремя (карта в представлении пуста, а затем снова появляется). Если я пытаюсь загрузить listfragment снова, нажав на Пункт в меню панели действий, то приложение падает сMapView испортил мои транзакции фрагментов?

java.lang.IllegalStateException: Фрагмент уже добавлен:

Часть MainActivity, которая загружает фрагмент :

@Override 
    protected void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     mNewTrackFragment = (NewTrackFragment) getFragmentManager() 
       .findFragmentByTag(TAG_NEW_TRACK_FRAGMENT); 
     if (mNewTrackFragment == null) { 
      mNewTrackFragment = NewTrackFragment.newInstance(); 
     } 
     FragmentManager fragmentManager = getFragmentManager(); 
     fragmentManager.beginTransaction() 
       .add(R.id.fragment_container, mNewTrackFragment) 
       .commit(); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 

     if (id == R.id.action_track_list) { 
      if (null == mTrackListFragment) { 
       mTrackListFragment = TrackListFragment.newInstance(); 
      } 
      FragmentManager fragmentManager = getFragmentManager(); 
      fragmentManager.beginTransaction() 
        .replace(R.id.fragment_container, mTrackListFragment, TAG_TRACK_LIST_FRAGMENT) 
        .addToBackStack(null) 
        .commit(); 

      return true; 
     } 

Часть NewTrackFragment с MapView:

public NewTrackFragment() { 
} 

public static NewTrackFragment newInstance() { 
    NewTrackFragment fragment = new NewTrackFragment(); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRetainInstance(true); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_new_track, container, false); 

    mTrackTitleTV = (TextView) view.findViewById(R.id.tv_track_title); 
    mDistanceTV = (TextView) view.findViewById(R.id.tv_distance); 
    mElapsedTimeTV = (TextView) view.findViewById(R.id.tv_elapsed_time); 
    mSpeedTV = (TextView) view.findViewById(R.id.tv_speed); 
    mAscentTV = (TextView) view.findViewById(R.id.tv_ascent); 
    mDescentTV = (TextView) view.findViewById(R.id.tv_descent); 
    mAltitudeTV = (TextView) view.findViewById(R.id.tv_altitude); 
    mStartStopFab = (FloatingActionButton) view.findViewById(R.id.fab_startstop); 
    mMapView = (MapView) view.findViewById(R.id.new_track_mapview); 

    setupMapView(savedInstanceState); 

    return view; 
} 

private void setupMapView(Bundle savedInstanceState) { 
    mMapView.onCreate(savedInstanceState); 
    mMapView.getMapAsync(this); 
} 

Я искал лучший вечер для получения некоторой информации об этом, но ничего не нашел.

ответ

0

Здесь несколько вещей не так. Прямо сейчас, вы не проходите TAG_NEW_TRACK_FRAGMENT в качестве тега при вызове add в пределах onCreate. Из-за этого вы добавляете экземпляр NewTrackFragment без связанного с ним тега, и поэтому вызов findFragmentByTag всегда будет возвращать null. По существу, вы создаете новый экземпляр NewTrackFragment каждый раз, когда вы поворачиваете устройство. Это нехорошо, потому что состояние FragmentManager сохраняется на всех поворотах устройства, что означает, что он все еще удерживает каждый добавленный к нему Fragment. Поскольку вы безоговорочно звоните add, FragmentManager будет содержать несколько экземпляров NewTrackFragment.

С учетом сказанного, что вы должны сделать, это добавить тег в вызове add и вызывать только add, как только вы знаете, что FragmentManager не в настоящее время проводит на экземпляре NewTrackFragment:

mNewTrackFragment = (NewTrackFragment) getFragmentManager() 
       .findFragmentByTag(TAG_NEW_TRACK_FRAGMENT); 
     if (mNewTrackFragment == null) { 
      mNewTrackFragment = NewTrackFragment.newInstance(); 
      FragmentManager fragmentManager = getFragmentManager(); 
      fragmentManager.beginTransaction() 
        .add(R.id.fragment_container, mNewTrackFragment, TAG_NEW_TRACK_FRAGMENT) 
        .commit(); 
     } 

Вы могли бы хотите сделать что-то подобное с вашим TrackListFragment:

if (id == R.id.action_track_list) { 
      FragmentManager fragmentManager = getFragmentManager(); 
      mTrackListFragment = (TrackListFragment) fragmentManager.findFragmentByTag(TAG_TRACK_LIST_FRAGMENT); 
      if (null == mTrackListFragment) { 
       mTrackListFragment = TrackListFragment.newInstance(); 
       fragmentManager.beginTransaction() 
         .replace(R.id.fragment_container, mTrackListFragment, TAG_TRACK_LIST_FRAGMENT) 
         .addToBackStack(null) 
         .commit(); 
      } 
} 
+1

Спасибо за ваш ответ, он решил мою проблему. Я испортил свои транзакции фрагмента раньше из-за других ошибок. Реализация вашего решения снова установила его :) – vokod

 Смежные вопросы

  • Нет связанных вопросов^_^