Android 带片段的actionbar向上导航
我有一个选项卡式的Actionbar/viewpager布局,有三个选项卡,分别是a、B和C。在tabCtab(fragment)中,我添加了另一个片段,比如fragmentD。与Android 带片段的actionbar向上导航,android,android-fragments,android-actionbar,Android,Android Fragments,Android Actionbar,我有一个选项卡式的Actionbar/viewpager布局,有三个选项卡,分别是a、B和C。在tabCtab(fragment)中,我添加了另一个片段,比如fragmentD。与 DFragment f= new DFragment(); ft.add(android.R.id.content, f, ""); ft.remove(CFragment.this); ft.addToBackStack(null); ft.commit(); 我修改了DfFragment的onResu
DFragment f= new DFragment();
ft.add(android.R.id.content, f, "");
ft.remove(CFragment.this);
ft.addToBackStack(null);
ft.commit();
我修改了DfFragment的onResume中的actionbar以添加按钮:
ActionBar ab = getActivity().getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);
现在在DFragment中,当我按下hardware(phone)Back按钮时,我将返回到选择了CFragment的原始选项卡(ABC)布局。如何使用actionbar up按钮实现此功能?我知道了。只需覆盖托管活动中的onOptionsItemSelected,并弹出backbackback,例如
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);
}
调用
getActionBar().setDisplayHomeAsUpEnabled(布尔值)代码>和getActionBar().setHomeButtonEnabled(布尔值)代码>在onbackbackchanged()
中,如下面的回答所述。实现onbackbackbackchangedListener
并将此代码添加到片段活动中
@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;
}
如果您有一个父活动,并且希望此“向上”按钮用作“后退”按钮,则可以使用以下代码:
将其添加到主活动类中的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);
}
}
});
然后添加选项ItemSelected,如下所示:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
....
}
我通常一直都在使用它,而且似乎非常合法这是一个非常好且可靠的解决方案:
这个家伙制作了一个抽象片段来处理backPress行为,并使用策略模式在活动片段之间切换
对于你们中的一些人来说,抽象类可能有一点缺陷
很快,链接的解决方案如下所示:
// 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;
}
}
您可以像后退按钮一样使用向上按钮返回
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
我使用了和答案的组合。我的应用程序只有一个MainActivity和加载到其中的片段a、B、C。我的“主”片段(A)实现OnBackbackChangedListener,并检查Backbackback的大小;如果小于1,则隐藏向上按钮。片段B和C总是加载后退按钮(在我的设计中,B从A启动,C从B启动)。MainActivity本身只是在点击按钮时弹出backbackback,并具有显示/隐藏按钮的方法,片段调用该按钮:
main活动:
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); }
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();
}
}
public void onCreate(Bundle savedinstanceSate) {
// show the UP button
((MainActivity)getActivity()).showUpButton();
// other fragment init stuff
...
}
fragmentA(实现FragmentManager.onbackbackchangedListener):
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); }
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();
}
}
public void onCreate(Bundle savedinstanceSate) {
// show the UP button
((MainActivity)getActivity()).showUpButton();
// other fragment init stuff
...
}
我知道这个问题由来已久,但可能有人(像我一样)也需要它
如果您的活动扩展了AppCompatActivity,则可以使用更简单(两步)的解决方案:
1-无论何时添加非主片段,只要在提交片段事务之后显示up按钮即可。像这样:
// ... add a fragment
// Commit the transaction
transaction.commit();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
2-然后当按下“向上”按钮时,将其隐藏
@Override
public boolean onSupportNavigateUp() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
return true;
}
就这样。这对我很有效。覆盖onSupportNavigateUp和onBackPressed,例如(Kotlin中的代码)
现在在片段中,如果显示向上箭头
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
单击它将返回上一个活动。Kotlin:
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 }
...
}
类MyActivity:AppCompatActivity(){
重写创建时的乐趣(savedInstanceState:Bundle?){
...
supportFragmentManager.AddOnBackbackChangedListener{setupHomeAsUp()}
setupHomeAsUp()
}
私人娱乐设置HomeAsup(){
val shouldShow=0
您还必须调用getActivity().getActionBar().setDisplayHomeAsUpEnabled(false);要在弹出后堆栈后移除向上按钮,这不是正确的方法。它保持向上按钮处于启用状态。您应该将该代码放入带有caseandroid.R.id.home
的switch
语句中。关于onSupportNavigateUp()
,“方法不会从其超类重写方法”。如果您已经选择了onoptionItem
,还可以检查itemIdandroid.R.id.home
而不是添加onSupportNavigateUp
。如果API版本>=14,则使用onNavigateUp而不是onSupportNavigateUp@Override公共布尔值onNavigateUp(){//当按下向上按钮时调用此方法。只调用弹出堆栈。getFragmentManager().popBackStack();返回true;}是否应该在操作栏中的应用程序图标旁边显示一个向上插入符号?
?我在执行此代码时没有看到。我只能单击图标,但它没有任何作用。Android 4.0+。如果OnBackbackChanged()不要覆盖,请确保您的活动实现FragmentManager.OnBackbackChangedListener接口。虽然此链接可以回答问题,但最好包含答案的基本部分并提供链接供参考。如果链接页面发生更改,则仅链接的答案可能无效。顺便说一句:如果您发现重复,请se将它们标记为这样。thx.在onStart中设置SelectedFragment是否重要?我在我的活动
中尝试准确地使用此代码,希望它会返回到它开始的片段。当我转到我的活动
时,后退按钮出现在我的应用程序图标附近,但我单击图标,什么也没有发生(应该返回到片段)。知道为什么吗?谢谢。@Daniel您的代码是合法的。它确实有效。您可能只想使用try-catch选项对其进行排序,以防万一。您知道如何防止任何不可预见的异常和应用crashing@NoniA.这只会返回到以前的片段(例如,片段B->片段a),如果您在新活动中膨胀1个片段,则不会返回到以前的活动。可能重复