操作条向上导航与片段

我有一个带有三个选项卡的选项卡式的Actionbar / viewpager布局, 如ABC. 在选项卡C选项卡(片段),我添加另一个片段说片段D。

DFragment f= new DFragment(); ft.add(android.R.id.content, f, ""); ft.remove(CFragment.this); ft.addToBackStack(null); ft.commit(); 

我修改DFragment的onResume中的操作栏添加button:

 ActionBar ab = getActivity().getActionBar(); ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); ab.setDisplayHomeAsUpEnabled(true); ab.setDisplayShowHomeEnabled(true); 

现在在DFragment中,当我按下硬件(手机)“后退”button时,我将selectCFragment返回到原始选项卡式(ABC)布局。 如何使用操作栏向上button来实现此function?

实现OnBackStackChangedListener并将此代码添加到您的Fragment活动。

 @Override public void onCreate(Bundle savedInstanceState) { //Listen for changes in the back stack getSupportFragmentManager().addOnBackStackChangedListener(this); //Handle when activity is recreated like on orientation Change shouldDisplayHomeUp(); } @Override public void onBackStackChanged() { shouldDisplayHomeUp(); } public void shouldDisplayHomeUp(){ //Enable Up button only if there are entries in the back stack boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0; getSupportActionBar().setDisplayHomeAsUpEnabled(canback); } @Override public boolean onSupportNavigateUp() { //This method is called when the up button is pressed. Just the pop back stack. getSupportFragmentManager().popBackStack(); return true; } 

我知道了。 只需在托pipe活动中覆盖onOptionsItemSelected并popupbackstack,例如

 public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: FragmentManager fm = getSupportFragmentManager(); if (fm.getBackStackEntryCount() > 0) { fm.popBackStack(); } return true; default: return super.onOptionsItemSelected(item);; } } 

调用getActionBar().setDisplayHomeAsUpEnabled(boolean);getActionBar().setHomeButtonEnabled(boolean);onBackStackChanged()中解释下面的答案。

如果您有一个家长活动,并希望这个向上button作为后退button,您可以使用此代码:

把它添加到你的主要activity类的onCreate中

 getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { int stackHeight = getSupportFragmentManager().getBackStackEntryCount(); if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment) getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } else { getSupportActionBar().setDisplayHomeAsUpEnabled(false); getSupportActionBar().setHomeButtonEnabled(false); } } }); 

然后添加onOptionsItemSelected像这样:

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

我一直都在使用这个,看起来很合理

你可以返回button像后退button;

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

我知道这个问题很老,但也许是某个人(像我)也需要它。

如果您的Activity扩展了AppCompatActivity ,则可以使用更简单的(两步)解决scheme:

1 – 每当你添加一个非家庭片段,只需显示向上button,在提交片段事务之后。 喜欢这个:

  // ... add a fragment // Commit the transaction transaction.commit(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

2 – 然后当按下UPbutton时,将其隐藏。

 @Override public boolean onSupportNavigateUp() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); return true; } 

而已。

我用了Roger Garzon Nieto和sohailaziz的答案。 我的应用程序有一个单一的MainActivity,并加载到它的碎片A,B,C。 我的“家”片段(A)实现OnBackStackChangedListener,并检查backStack的大小; 如果小于1,则隐藏UPbutton。 碎片B和C总是加载后退button(在我的devise中,B从A启动,而C从B启动)。 MainActivity本身只是popupUPbutton点击后台,并有方法显示/隐藏片段调用的button:

主要活动:

 public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: getSupportFragmentManager().popBackStack(); return true; } return super.onOptionsItemSelected(item); } public void showUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } public void hideUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); } 

fragmentA(实现FragmentManager.OnBackStackChangedListener):

 public void onCreate(Bundle savedinstanceSate) { // listen to backstack changes getActivity().getSupportFragmentManager().addOnBackStackChangedListener(this); // other fragment init stuff ... } public void onBackStackChanged() { // enable Up button only if there are entries on the backstack if(getActivity().getSupportFragmentManager().getBackStackEntryCount() < 1) { ((MainActivity)getActivity()).hideUpButton(); } } 

fragmentB,fragmentC:

 public void onCreate(Bundle savedinstanceSate) { // show the UP button ((MainActivity)getActivity()).showUpButton(); // other fragment init stuff ... } 

这是一个非常好的和可靠的解决scheme: http : //vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/

这个人做了一个抽象的片段来处理backPress行为,并使用策略模式在活动片段之间切换。

对于你们中的一些人来说,在抽象类中可能有一点缺点…

不久之后,链接的解决scheme如下所示:

 // Abstract Fragment handling the back presses public abstract class BackHandledFragment extends Fragment { protected BackHandlerInterface backHandlerInterface; public abstract String getTagText(); public abstract boolean onBackPressed(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(!(getActivity() instanceof BackHandlerInterface)) { throw new ClassCastException("Hosting activity must implement BackHandlerInterface"); } else { backHandlerInterface = (BackHandlerInterface) getActivity(); } } @Override public void onStart() { super.onStart(); // Mark this fragment as the selected Fragment. backHandlerInterface.setSelectedFragment(this); } public interface BackHandlerInterface { public void setSelectedFragment(BackHandledFragment backHandledFragment); } } 

并在活动中使用:

 // BASIC ACTIVITY CODE THAT LETS ITS FRAGMENT UTILIZE onBackPress EVENTS // IN AN ADAPTIVE AND ORGANIZED PATTERN USING BackHandledFragment public class TheActivity extends FragmentActivity implements BackHandlerInterface { private BackHandledFragment selectedFragment; @Override public void onBackPressed() { if(selectedFragment == null || !selectedFragment.onBackPressed()) { // Selected fragment did not consume the back press event. super.onBackPressed(); } } @Override public void setSelectedFragment(BackHandledFragment selectedFragment) { this.selectedFragment = selectedFragment; } } 

这对我有效。 覆盖onSupportNavigateUp和onBackPressed,例如(在Kotlin中的代码);

 override fun onBackPressed() { val count = supportFragmentManager.backStackEntryCount if (count == 0) { super.onBackPressed() } else { supportFragmentManager.popBackStack() } } override fun onSupportNavigateUp(): Boolean { super.onSupportNavigateUp() onBackPressed() return true } 

现在在片段中,如果显示向上的箭头

 activity.supportActionBar?.setDisplayHomeAsUpEnabled(true) 

点击它会使您恢复以前的活动。