0

У меня есть ActivityA есть FragmentA. В FragmentA есть EditText, который, если сфокусирован, добавляет FragmentB (ниже). Трассировка стека начинается с onDestroy в ActivityA, которая вызывает onFocusChange, который срабатывает popBackStack. isRemovingOrPartOfRemovalChain() должен возвращать true в этот момент, но он иногда возвращает false, вызывая popBackStack, следовательно исключение. Есть ли ошибка в этом методе?Не удается выполнить это действие после onSaveInstanceState (изменение фокуса EditText)

editText.setOnFocusChangeListener(new OnFocusChangeListener(){ 
     @Override 
     public void onFocusChange(View view, boolean hasFocus) { 
      if(hasFocus){ 
       FragmentManager fragmentManager = getChildFragmentManager(); 

       Fragment fragment = fragmentManager.findFragmentByTag(FRAGMENT_B); 

       if(fragment == null){ 
        FragmentB fragmentB = FragmentB.newInstance(); 

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
        fragmentTransaction.add(R.id.fragment_b, fragmentB, FRAGMENT_B); 
        fragmentExploreSearchListTransaction.addToBackStack(null); 
        fragmentExploreSearchListTransaction.commit(); 
      } 
      else{ 
       if(!isRemovingOrPartOfRemovalChain()){ 
        getChildFragmentManager().popBackStack(); 
       } 

      } 
     } 

    }); 

public boolean isRemovingOrPartOfRemovalChain(){ 

    if(isRemoving()){ 
     return true; 
    } 

    Fragment fragment = this.getParentFragment(); 

    if(fragment != null){ 
     if(((MainFragment) fragment).isRemovingOrPartOfRemovalChain()){ 
      return true; 
     } 
     else{ 
      return false; 
     } 
    } 

    else{ 
     return(getActivity().isFinishing()); 
    } 

} 

/** 
* Return true if this fragment is currently being removed from its 
* activity. This is <em>not</em> whether its activity is finishing, but 
* rather whether it is in the process of being removed from its activity. 
*/ 
final public boolean isRemoving() { 
    return mRemoving; 
} 
+0

Не могли бы вы опубликовать реализацию метода isRemoving() '? –

+0

@GeorgeD 'isRemoving()' находится в классе Fragment Android. Я добавил его в конец сообщения. – ono

+0

Почему бы просто не пометить действие заднего стека, а затем использовать [findFragmentByTag()] (https://developer.android.com/reference/android/support/v4/app/FragmentManager.html#findFragmentByTag%28java.lang.String% 29)? Таким образом, вы можете быть на 100% уверенным, что фрагмент все еще находится в стеке. – CurlyCorvus

ответ

0

ваша проблема из-за состояния деятельности потеряна.

попробовать это fragmentExploreSearchListTransaction.commit()

в

fragmentExploreSearchListTransaction.commitAllowingStateLoss() 

но это не является хорошим решением, so i refer you read this blog, этот блог о фрагменте транзакции после сохранения активности Instance, я надеюсь, что моя информация поможет вам.

0

Существует не достаточно кода, чтобы обеспечить с полным решением, но в этом случае:

  1. Это лучше использовать Fragment#isRemoving(), чтобы проверить, если фрагмент удаляется от деятельности;
  2. Если фокус изменился ожидать от взаимодействия пользователя с экраном, что лучше установить/удалить слушатель следующих способов:
    • onCreateView()/onDestroyView();
    • onResume()/onPause();

Если есть какая-либо причина, что эти решения не работают, не стесняйтесь уточнить. Удачи!

+0

Когда я проверяю '! IsRemoving()' и вызываю dialogFragment. show (...), снова возникает исключение. – CoolMind

0

При фиксации фрагмента после onSavedInstanceState(Bundle outState) обратного вызова (например onDestroy()), то состояние Фрагмент фиксации никому будет потеряна (Becase Fragment.onSaveInstanceState(Bundle) не будет называться в этой ситуации).

В этом случае, когда воссоздается Activity, зафиксированный фрагмент не будет присутствовать в Activity'sFragmentManager и поэтому не будет восстановлен. Это считается государственной потерей.

Это поведение может привести к повреждению или повреждению пользовательского интерфейса и считается непреднамеренным и исключительным, поэтому инфраструктура Android предупреждает вас об этом путем исключения исключения :-) Лучше сохранить, чем сожалеть, верно?

В случае, если кто-то знает, что делает (что почти всегда не так :-)), можно придерживаться .commitAllowingStateLoss(), но я категорически против этого, так как он привнесет в ваше приложение легальную болтовню.

Только не совершайте фрагменты после того, как стало известно, что ваша активность разрушает: например,

... 

boolean fieldActivityIsDestroying; 

.... 

public void onSaveInstanceState(Bundle out){ 
    super.onSaveInstanceState(out); 
    fieldActivityIsDestroying = true; 
} 

и проверить значение поля при фиксации фрагмента.

Также вы можете использовать FragmentManager.executePendingTransactions() для выполнения любых транзакций фрагментов сразу после их передачи менеджеру (по умолчанию commit является асинхронным).

0

Почему бы вам просто не установить onFocusedChangeListener в OnResume() и удалить его в OnPause()? Это должно препятствовать его срабатыванию, когда ваша деятельность заканчивается.

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

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