2015-06-19 3 views
4

Я работаю над приложением, которое имеет поддержку FragmentSearchView с виджетом и RecyclerView представить результаты поиска, которые отправляют пользователь на FragmentActivity, чтобы отобразить информацию о выборе. Все это прекрасно работает, но я вижу противоречивое поведение между эмулятором Nexus 6 и фактическим устройством по отношению к backstack. В эмуляторе все работает так, как я ожидал, когда пользователь будет возвращен к фрагменту результатов поиска, если нажать кнопку «Назад», а на деталях FragmentActivity. На реальной Nexus 6 устройства, пользователь берется весь путь обратно к AppCompatActivity, который содержит меню моего приложения (это деятельность использует поддержку FragmentManager, который добавляет фрагменты, которыми он управляет к backstack):Различного поведение backstack между Nexus 6 устройством и эмулятором

private void replaceFragment(Fragment supportFragment) { 
    String fragmentName = supportFragment.getClass().getSimpleName(); 
    supportFragmentManager.beginTransaction() 
      .addToBackStack(fragmentName) 
      .replace(R.id.frame_menu_container, supportFragment, fragmentName) 
      .commit(); 
} 

код для отправки пользователя из фрагмента в FragmentActivity только умысел с массовкой:

Intent intent = new Intent(getActivity(), PlayerDetailsActivity.class); 
intent.putExtra(TransientPlayer.BUNDLE_KEY, transientPlayer); 
startActivity(intent); 

Я не делаю ничего особенного с backstack (еще) - это с поведением по умолчанию.

В чем может быть проблема? Я сделал некоторые чтения в backstack, и я еще ничего не видел, когда вручную добавлял что-то в backstack, когда вы возвращаетесь из FragmentActivy в фрагмент, где вы не используете FragmentManager.

EDIT 1: Вот макет XML, где frame_menu_container определяется:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:gravity="center" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
     app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 

    <FrameLayout 
     android:id="@+id/frame_menu_container" 
     android:layout_below="@id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     tools:layout="@layout/fragment_home"> 
    </FrameLayout> 

</RelativeLayout> 

EDIT 2: OK, вот текстовое описание моей деятельности на высоком уровне и фрагменты:

NavigationMenuActivity, который проходит AppCompatActivity. Здесь все фрагменты меняются местами и при необходимости, и используется SupportFragmentManager и где у меня есть метод replaceFragment().

У меня есть следующие фрагменты, все из которых отображают статическую информацию, делают вызовы REST для извлечения и отображения данных или позволяют пользователю отправлять обратную связь. Все расширение android.support.v4.app.Fragment, и ни один из них не имеет других фрагментов или действий, к которым пользователь может перейти.

  • HomeFragment
  • CalendarFragment
  • StandingsFragment
  • PlayerSearchFragment (смотри ниже)
  • AboutFragment
  • FeedbackFragment

Единственное исключение в функциональности этих фрагментов является PlayerSearchFragment, который также e xtends android.support.v4.app.Fragment. Этот фрагмент содержит RecyclerView, который отображает результаты вызова REST, когда пользователи хотят искать игроков. Когда результаты возвращаются и пользователь выбирает элемент из списка, они отправляются на номер PlayerDetailsActivity, который продлевает FragmentActivity.

PlayerDetailsActivity использует вид FragmentTabHost, который содержит различные виды информации о игроке, который можно просмотреть. Это «конец строки» по этому пути - нет других фрагментов или действий, к которым пользователь может перейти. Вот в чем проблема.Когда я нажимаю кнопку «Назад» во время этой операции, я хочу, чтобы пользователь вернулся к фрагменту PlayerSearchFragment (результаты поиска), которые в этом случае выполняются, если я в эмуляторе Nexus 6 , но они вернитесь к действию NavigationMenuActivity, если я нахожусь на своем фактическом устройстве Nexus 6 .

У меня есть следующий метод в PlayerDetailsActivity, который вызывается при нажатии кнопки Back, но он всегда показывает нулевые записи:

@Override 
public void onBackPressed() { 

    FragmentManager fragmentManager = getSupportFragmentManager(); 
    int count = fragmentManager.getBackStackEntryCount(); 
    Log.i(TAG, "Backstack : There are " + count + " entries"); 
    for (int i = 0; i > count; i++) { 
     FragmentManager.BackStackEntry backStackEntry = fragmentManager.getBackStackEntryAt(i); 
     Log.i(TAG, String.format("Backstack : id=%d, name=%s, shortTitle=%s, breadcrumbTitle=%s", 
       backStackEntry.getId(), 
       backStackEntry.getName(), 
       backStackEntry.getBreadCrumbShortTitle(), 
       backStackEntry.getBreadCrumbTitle())); 
    } 

    super.onBackPressed(); 
} 

Моя надежда состоит в том, чтобы иметь опыт быть одинаковым для всех устройств, будь то аппаратное обеспечение или эмулятор.

+0

Опубликовать макет, содержащий frame_menu_container. Я думаю, что это не может быть подходящим элементом пользовательского интерфейса для фрагмента. –

+0

Я добавил его выше – TheIcemanCometh

+0

Поиск - фрагментная активность? & результаты - фрагмент? почему вы используете намерения btw Извините, если im wrong – Elltz

ответ

1

Хотя я до сих пор нет ответа на вопрос, почему я не могу получить эту работу как я надеялся, у меня есть обходной путь, и он хорошо работает для того, что мне нужно делать. В принципе, я переопределяю обратные вызовы Up и Back в PlayerDetailsActivity и использую намерение (с данными), чтобы явным образом отправить пользователя обратно NavigationMenuActivity.Данные я отправляю в намерении в основном только булево, который говорит мне, если я иду от PlayerDetailsActivity, и если да, то покажите, что фрагмент, а не дома фрагмента, как так:

@Override 
public void onBackPressed() { 
    sendBackToMenu(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      sendBackToMenu(); 
      finish(); 
      return true; 
    } 
    return false; 
} 

private void sendBackToMenu() { 
    Intent backToMenuIntent = new Intent(this, NavigationMenuActivity.class); 
    backToMenuIntent.putExtra("FROM_PLAYER_DETAILS", true); 
    startActivity(backToMenuIntent); 
} 

Вышеуказанные изменения были после того, как я изменил класс простираться от AppCompatActivity и добавил следующее в PlayerDetailsActivity.onCreate() активировать ActionBar для навигации вверх:

ActionBar actionBar = getSupportActionBar(); 
assert actionBar != null; 
actionBar.setTitle(R.string.player_details); 
actionBar.setDisplayHomeAsUpEnabled(true); 

Кроме того, в NavigationMenuActivity.onCreate() я делаю это:

if (getIntent().getBooleanExtra("FROM_PLAYER_DETAILS", false)) 
    replaceFragment(new PlayerSearchFragment()); 
else   
    replaceFragment(new HomeFragment()); 

Я не знаю, является ли это наиболее «подходящим» способом для этого, но он работает хорошо и делает то, что мне нужно, на нескольких аппаратных устройствах и эмуляторах Nexus 4/5/6.

1

Я думаю, вы хотите addToBackStack(fragmentName), вызванный после replace(R.id.frame_menu_container, supportFragment, fragmentName).

Сообщите мне, что произойдет.

+0

К сожалению, это не исправило мою проблему - она ​​все еще демонстрирует то же поведение. – TheIcemanCometh

+1

вы фактически вызываете addToBackStack перед заменой, поэтому вы должны удалить его и принести его под заменой @TheIcemanCometh или это то, что вы сделали? – Elltz

+0

@ Elltz Это то, что я делал изначально, да. Сделать предлагаемое изменение/переключатель, похоже, не помогло. Рассмотрение других предложений. – TheIcemanCometh

1

Первое, что в соответствии с вашим сценарием, вам не нужно добавлять транзакцию в BackStack, поскольку она используется только при навигации между фрагментами в одном и том же действии.

Теперь, когда вы возвращаетесь, вы не получаете свой фрагмент, вы нажимаете два раза. один клик удаляет второе действие, а другой удаляет фрагмент, который добавляется в вашу заднюю часть. Что касается вашей информации Фрагмент не имеет обратного вызова обратного вызова, они полагаются на активность onbackPressed() method

Я попытался запустить этот код, и он работает правильно на моем устройстве Nexus 5. Хотя Я прилагаю код, что я использую

public class MainActivity extends FragmentActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    replaceFragment(new FragmentA()); 


} 
private void replaceFragment(Fragment supportFragment) { 

    getSupportFragmentManager().beginTransaction() 
      .replace(R.id.frame_menu_container, supportFragment 
      .commit(); 
} 

}

Fragmenta здесь:

public class FragmentA extends Fragment { 
    @Nullable 
    @Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_a, null); 

    view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(getActivity(), AnotherActivity.class); 
      startActivity(intent); 
     } 
    }); 
    return view; 
} 

}

И Другая деятельность, как:

public class AnotherActivity extends Activity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.another_act); 

} 

}

Я не думаю, что вы столкнулись с какой-либо проблемой.

Если вы все еще сталкиваетесь с проблемой, сообщите мне свое имя устройства и приложите сюда код, чтобы я мог протестировать и сообщим вам.

+0

Я добавил дополнительную информацию в EDIT 2 – TheIcemanCometh

+0

Я удалил вызов 'addToBackStack()', но он не имел никакого эффекта. – TheIcemanCometh

1

хорошо попробуйте это, надеюсь, вытащит вас из этой дыры.

Этот ответ дает вам обходной путь, но не то, что на самом деле происходит

@Override 
public void onBackPressed() { 

FragmentManager fragmentManager = getSupportFragmentManager(); 
int count = fragmentManager.getBackStackEntryCount(); 
Log.i(TAG, "Backstack : There are " + count + " entries"); 
if(count > 0){ 
    fragmentManager.popBackStack(); //or popBackStackImmediate(); 
    for (int i = 0; i > count; i++) { 
     FragmentManager.BackStackEntry backStackEntry = fragmentManager.getBackStackEntryAt(i); 
     Log.i(TAG, String.format("Backstack : id=%d, name=%s, shortTitle=%s, breadcrumbTitle=%s", 
      backStackEntry.getId(), 
      backStackEntry.getName(), 
      backStackEntry.getBreadCrumbShortTitle(), 
      backStackEntry.getBreadCrumbTitle())); 
    } 
}else{ 
super.onBackPressed(); 
} 

}

+0

Это все еще возвращает ноль для подсчета записей в стопке. – TheIcemanCometh

+0

действительно? попробуйте разделить вызов addtobackstack и вызов замены, и вызовите comit для каждого и посмотрите. @ TheIcemanCometh – Elltz

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