2016-09-13 83 views
0

我在Fragment中的后退/向上按钮有问题。 我有一个活动,我有一些片段。在我称之为“1”的片段中,我有一个列表视图。当我点击任何项目时,它会转到另一个片段“2”。 我需要的功能,使后退/向上按钮只能在片段2,但不在片段1中。片段和返回按钮

有没有办法可以做到这一点? 我在活动试过,但我不明白怎么能这样帮助:

@Override 
public void onBackPressed() { 

    int count = getFragmentManager().getBackStackEntryCount(); 

    if (count == 0) { 
     super.onBackPressed(); 
     //additional code 
    } else { 
     getFragmentManager().popBackStack(); 
    } 

} 

,当我从片段1更改为片段2我有这样的代码:

fragment = new MaterialesFragment(); 
    FragmentManager fragmentManager3 = getFragmentManager(); 
    fragmentManager3.beginTransaction().replace(R.id.frame, fragment).addToBackStack("tagMateriales").commit(); 

谢谢很多:-)

+0

从哪里你想在哪里?片段2到1?其不明确 –

+0

添加您的活动的onCreate。而你如何添加第二个片段?你使用替换?你能提供更多细节吗? – masp

+0

只需在事务中使用'.addToBackStack(null)',在提交之前切换到片段2。 – Vucko

回答

0

尝试使用FragmentTransaction对象addToBackStack()方法,你用它来代替fragment2到屏幕:

fragmentManager.beginTransaction().replace(R.id.content_frame,fragment2).addToBackStack("tagHere").commit(); 

如果你不需要实际的标签,你可以通过null作为参数。

+0

我已经添加了addToBackStack:S –

0

请使用此代码对你的“片段2”

public void showFragmentWithoutStack(Fragment fragment, String tag, int id) { 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
    transaction.add(id, fragment, tag); 
    transaction.commitAllowingStateLoss(); 
} 

tag可能是String类的名字,在活动你的根视图的ID(因为片段应该出现在顶层)。

+0

谢谢你的回答,你能告诉我请我在哪里添加这个?谢谢:) –

+0

我会创建该方法在您的活动,例如BaseActivity。在你的活动中,你应该有上述方法。在你的片段中你应该有方法'protected void showFragmentWithoutStack(Fragment fragment,String tag,int id){(BaseActivity)getActivity())。showFragmentWithoutStack(fragment,tag,id); '您应该控制活动 – Michael

0

为了使用onBackPressed()方法覆盖在活动为你的问题有,你还需要添加到您的片段:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
     // Assuming MainActivity is the Activity subclass name 
     if (getActivity() instanceof MainActivity) { 
      ((MainActivity) getActivity()).onBackPressed(); 
     } 
     return true; 
     default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

为了显示/隐藏返回按钮,添加这些方法对你的活动:

public void showUpButton() { 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
} 

public void hideUpButton() { 
    getSupportActionBar().setDisplayHomeAsUpEnabled(false); 
} 

然后,当你要显示或片段隐藏返回/向上键,调用这些方法。

在你的情况,你可以在片段1隐藏onResume()返回/向上键:

((MainActivity) getActivity()).hideUpButton(); 

然后在片段2显示它在onResume()

((MainActivity) getActivity()).showUpButton(); 
+0

中的片段,感谢您的答案,我将它添加到片段2中,但发生的情况相同(两个片段都可以返回“后退按钮”)我只是想要片段2有这个功能和片段1将有它像“封锁”。 –

+0

现在出现后退按钮箭头,但是当我点击它时出现我拥有的菜单。你能帮我在哪个部分叫片段1吗?感谢您的时间和帮助。 –

+0

@StephySamaniego听起来好像你需要在'onOptionsItemSelected()'方法中分离出这些情况。注意'case android.R.id.home',你需要这个。 –

0

有很多做这份工作的方式。在我看来,最优雅的是以下。我会隔离每个组件中的逻辑。每个片段都实现了一个接口,如“IBackHandler”,它允许活动和片段进行通信。在活动onBackPressed首先询问片段(如果它被实例化)做什么然后再行动。

接口:

public interface IBackHandler { 
    boolean doBack(); 
} 

实现该接口,并把它的逻辑来处理按下后退按钮片段:

public class YourFragment1 extends YourBaseFragment implements IBackHandler { 
     // your code 
     @Override 
     public boolean doBack() { 
      // return true means that you have done your stuff 
      //and you don't want 'super.onBackPressed()' to be called 
      return true; // this means do nothing 
     } 
} 

片段2:

public class YourFragment2 extends YourBaseFragment implements IBackHandler { 
     // your code 
     @Override 
     public boolean doBack() { 
      return false; //this means: call 'super.onBackPressed()' 
     } 
} 

您的活动:

public class YourActivity extends YourBaseActivity { 
    //your code 
    @Override 
    public void onBackPressed() { 
     Fragment currentFragment = getFragmentManager().findFragmentById(R.id.yourFragment); 
    if (currentFragment instanceof IBackHandler) { 
     if (!((IBackHandler) currentFragment).doBack()) { 
      super.onBackPressed(); 
     } 
    } else 
     super.onBackPressed(); 
    } 
} 

你可能会认为这是过度工程,但我可以向你保证,用这种方式,你将永远能够控制你的流程中发生了什么。

希望得到这个帮助!

0

我解决了这个问题,使用此代码时改变片段:

String fragmentIndexString="fragmenttwo";//or fragmentone something 
transaction.addToBackStack(); 

这是完整的代码在活动:

FirstFragment firstFragment; // my first fragment 
SecondFragment secondFragment; // my second fragment 
public static String FIRST="asfasgasg"; //first fragment index 
public static String SECOND="gsadgsagd"; //second fragment index 
... 
/* u can change fragment by using setFragment funiction */ 
public void setFragment(String page){ 
    FragmentTransaction transaction = fragmentManager.beginTransaction(); 
    switch (page){ 
     case FIRST: 
      if(firstFragment==null) firstFragment= SettingFragment.newInstance(); 
      if (!firstFragment.isAdded()) { 
       transaction.replace(R.id.fragmentcontainer, firstFragment); 
       transaction.addToBackStack(INDEX); 
       transaction.commit(); 
      } else { 
       transaction.show(firstFragment); 
      } 
      break; 
     case SECOND: 
      if(secondFragment==null) secondFragment= SettingFragment.newInstance(); 
      if (!secondFragment.isAdded()) { 
       transaction.replace(R.id.fragmentcontainer, secondFragment); 
       transaction.addToBackStack(INDEX); 
       transaction.commit(); 
      } else { 
       transaction.show(secondFragment); 
      } 
      break; 
     default: 
      setFragment(INDEX); 
    } 
} 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ 
     if(fragmentManager.getBackStackEntryCount()>1){ 
      fragmentManager.popBackStack(); 
      return true; 
     } 
    } 
    return super.onKeyDown(keyCode, event); 
} 
+0

嗨,谢谢你的回答。当我从片段1更改为片段2我有这样的代码:fragment = new MaterialesFragment(); FragmentManager fragmentManager3 = getFragmentManager(); ());();();。 –