动作栏与片段导航

Soh*_*ziz 84 android android-fragments android-actionbar

我有三个选项卡的标签动作条/ viewpager布局说,,和Ç.在标签Ç标签(片段),我加入另一片段说片段d.同

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

我在DFragment的onResume中修改了操作栏以添加按钮:

ActionBar ab = getActivity().getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);
Run Code Online (Sandbox Code Playgroud)

现在在DFragment中,当我按下硬件(手机)后退按钮时,我返回到选择了CFragment的原始选项卡(ABC)布局.如何通过操作栏按钮实现此功能?

Rog*_*eto 183

实现OnBackStackChangedListener并将此代码添加到Fragment Activity.

@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 canGoBack = getSupportFragmentManager().getBackStackEntryCount()>0;
   getSupportActionBar().setDisplayHomeAsUpEnabled(canGoBack);
}

@Override
public boolean onSupportNavigateUp() {
    //This method is called when the up button is pressed. Just the pop back stack.
    getSupportFragmentManager().popBackStack();
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 关于`onSupportNavigateUp()`,"方法不会覆盖其超类中的方法". (17认同)
  • 如果你已经有一个`onOptionsItemSelected`,那么也可以检查itemId`android.R.id.home`而不是添加`onSupportNavigateUp`. (9认同)
  • 如果onBackStackChanged()没有覆盖,请确保您的活动实现FragmentManager.OnBackStackChangedListener接口. (3认同)

Soh*_*ziz 39

我知道了.只需覆盖托管活动中的onOptionsItemSelected并弹出backstack,例如

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

如下面的答案所述,打电话getActionBar().setDisplayHomeAsUpEnabled(boolean);getActionBar().setHomeButtonEnabled(boolean);进来onBackStackChanged().

  • 你还必须调用getActivity().getActionBar().setDisplayHomeAsUpEnabled(false); 弹出后堆栈后删除向上按钮 (3认同)

Dan*_*ker 18

如果您有一个父活动并希望此向上按钮用作后退按钮,则可以使用以下代码:

将其添加到主活动类中的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);
            }
        }

    });
Run Code Online (Sandbox Code Playgroud)

然后像这样添加onOptionsItemSelected:

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

我一直都在使用这个,看起来非常合法


Moa*_*had 10

你可以像按钮一样按下按钮;

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


mar*_*tom 8

我知道这个问题很老,但可能有人(像我一样)也需要它.

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

1 - 每次添加非主片段时,只需在提交片段事务后立即显示向上按钮.像这样:

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

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Run Code Online (Sandbox Code Playgroud)

2 - 然后按下UP按钮时,将其隐藏.

@Override
public boolean onSupportNavigateUp() {
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);        
    return true;
}
Run Code Online (Sandbox Code Playgroud)

而已.


ver*_*oze 6

我使用了Roger Garzon Nietosohailaziz的答案.我的应用程序只有一个MainActivity,以及加载到其中的片段A,B,C.我的"home"片段(A)实现了OnBackStackChangedListener,并检查backStack的大小; 如果小于1,则隐藏UP按钮.片段B和C总是加载后退按钮(在我的设计中,B从A启动,C从B启动).MainActivity本身只是在UP按钮点击时弹出Backstack,并有方法显示/隐藏片段调用的按钮:

主要活动:

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); }
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

fragmentB,fragmentC:

public void onCreate(Bundle savedinstanceSate) {
    // show the UP button
    ((MainActivity)getActivity()).showUpButton();

    // other fragment init stuff
    ...
}
Run Code Online (Sandbox Code Playgroud)


小智 5

这对我有用。例如,覆盖 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
}
Run Code Online (Sandbox Code Playgroud)

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

activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
Run Code Online (Sandbox Code Playgroud)

单击它可以返回上一个活动。


fad*_*a21 5

科特林:

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        supportFragmentManager.addOnBackStackChangedListener { setupHomeAsUp() }
        setupHomeAsUp()
    }

    private fun setupHomeAsUp() {
        val shouldShow = 0 < supportFragmentManager.backStackEntryCount
        supportActionBar?.setDisplayHomeAsUpEnabled(shouldShow)
    }

    override fun onSupportNavigateUp(): Boolean = 
        supportFragmentManager.popBackStack().run { true }

    ...
}
Run Code Online (Sandbox Code Playgroud)