I am having two fragments Frag A and Frag B which are rendered using view pager .
If user has swiped from A to B then presses back button(when in B) then user should go to A instead of coming out of view pager . How can we achieve this ?
Adding transaction to backstack does not seem to help .
Thanks
You have to override the onKeyDown() method in the Activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
myViewPager.setCurrentItem(0, true);
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
This will capture the "back" button press event and send the user to the first item in the ViewPager.
There is also ViewPager#getCurrentItem() which can be used to go back only if the user swiped. An implementation like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && myViewPager.getCurrentItem() == 1) {
myViewPager.setCurrentItem(0, true);
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
would send the user back to the previous page only if the user was on the next page. Else, it will register the "back" normally and the user will exit as expected.
You may want the case in which the user goes back to the previous page (assuming you have more than two pages). In which case, you want to implement the ViewPager.OnPageChangeListener() and save the position every time onPageSelected(int position) is called. If you implement them in a stack, then you can pop them off every time the user presses "back". Once the stack is empty, exit the app.
EDIT
As correctly stated in the comments by Jade Byfield, a slightly easier way to do this would be to use onBackPressed() in the Activity. This will only work in API levels 5+.
#Override
public void onBackPressed() {
if(i_dont_want_to_leave) {
myViewPager.setCurrentItem(0, true);
} else {
super.onBackPressed(); // This will pop the Activity from the stack.
}
}
On the Android Docs page
https://developer.android.com/training/animation/screen-slide.html#viewpager
I found an example of handling ViewPager sliding and there's a method
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
super.onBackPressed();
}
else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
This selects a previous page or exits the current activity.
I think a better approach would be to delegate the back key handling to the respective fragments. I have used a CustomFragment which supports a method to handle the back key. All the Fragments will be extending from this CustomFragment.
public abstract class BackKeyHandlingFragment extends Fragment {
public abstract boolean handleBackKey();
}
Activity can delegate the backKey processing to current Fragment. Fragments can perform required actions in their respective implementation of handleBackKey method. The method can return true to tell activity not to process the back key. To go ahead with default back key action at Activity level, the method can return false.
public void onBackPressed() {
BackKeyHandlingFragment fragment = (BackKeyHandlingFragment) mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
// Fragment should return boolean according to app requirements after processing back key
if (!fragment.handleBackKey()) {
super.onBackPressed();
}
}
Related
I've an activity and inside it a fragment.
What's the right procedure to ask for saving data (via a dialog) before exiting the activity?
User press back
Activity notify the fragment via interface onBackPressed
Fragment show dialog where user can choose to save/unsave data
User choose an option in the dialog
Fragment notify activity that calls super.onBackpressed()?
I'm not sure about point 5, because at point 2. I've to avoid default behaviour, instead at 5. I've to call super.
I need to mantain the save business logic inside the fragment.
P.S. the result is something like when FB app ask you on exit, to save or delete a post that is still a draft.
What you described works. Alternatively, for step 5, you can simply do
getActivity().finish;
if the user confirms exiting.
In the onCreateView() of the fragment, right before you return the view, add a listener to it:
v.setOnKeyListener( new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCODE_BACK){
//do your stuff
}
return false;
}
});
return v;
I am using Fragment A,Fragment B .. and so on. i want to navigate back to the previous Fragment, from the current Fragment.
I want to use Back Button in Mobile to get back navigation.
How can i do this ? OR i have to make Back button in layout xml.
i tried below code,
fTransaction.add(R.id.container, nF).addToBackStack(null).commit();
when i pressed Back Button in Mobile , it restarts the App.
To go back to previous fragment using phone's back button you should override onKeyDown() mehtod.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
getFragmentManager().popBackStack();
return true;
}
return false;
}
When replacing a fragment use replace instead of add and then addToBackStack:
fTransaction.replace(R.id.container, nF).addToBackStack(null).commit();
Try this:
fTransaction.addToBackStack(null).add(R.id.container, nF).commit();
I have an Actionbar app with fragments and a TabFragment extends Fragment class, where I customize the functionality of my fragments.
I want to be able to control what the back button does.
#Overriding onBackPressed()
won't work because I am not in an Activity,
nor will
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
//my code here
}
return super.onKeyDown(keyCode, event);
}
My goal is to hide some specific Views when I press back based on true/false value of a boolean variable. Any suggestions on how I might be able to manipulate this functionality? Thanks!
I had the same problem as you, but I realized that you had to deal with the back button in the activity where you are running your fragments from. You need to override the onBackPressed() in the activity code, not inside the fragment code. Then you can check to see which fragment is visible and do what you want accordingly.
This code is in my activity:
#Override
public void onBackPressed()
{
try
{
final LiveWorkFragment liveFragment = (LiveWorkFragment)getFragmentManager().findFragmentByTag("live_work");//LiveWorkFragment is a fragment
final NonLiveWorkFragment nonLiveFragment = (NonLiveWorkFragment)getFragmentManager().findFragmentByTag("non_live");//NonLiveWorkFragment is a fragment
final SignatureFragment signatureFragment = (SignatureFragment)getFragmentManager().findFragmentByTag("signature");//this is a Fragment too
if(liveFragment == null && nonLiveFragment == null && signatureFragment == null)
{
super.onBackPressed();
}
if(liveFragment != null)
{
if (liveFragment.isVisible())
{
//do what you want
}
}
}
}
I want to go back to the last fragment in the back stack, so I want to make the back button popback the stack. Should I do this? and if so, should I override onBackPressed() or onKeyDown()?
#Override
public void onBackPressed()
{
Intent intent = new Intent(this,ABC.class);
startActivity(intent);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
// do something on back.
return true;
}
return super.onKeyDown(keyCode, event);
}
My fragments aren't being added to the back stack properly for some reason
I am using this to try to go back to the previous fragment, but the order is acting strange. What exactly should I do to make the order proper?
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft){
if(teamsFrag !=null)
{
if(manage.getBackStackEntryCount() > 0)
manage.popBackStack(manage.getBackStackEntryAt(manage.getBackStackEntryCount()-1).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
//ft.detach(dataFrag);
}
Short answer? No.
Long answer? If you have to ask, No.
You should set your fragments up using the fragment manager so that the back button does what you want. You shouldn't override the back button instead of implementing your stack correctly.
I want to go back to the last fragment in the back stack, so I want to make the back button popback the stack.
This is the default behavior when you use FragmentTransaction#addToBackStack() while adding new Fragments with the FragmentManager.
I have a main activity. It's main purpose is to handle Tab menu. If a user click a tab it'll load another activity as a sub-activity, still showing the tab menu. I am using Intent to do this:
setContent(new Intent(this,B.class))
This sub-activity has an onclick function as well. If the user clicks one of the links it'll load xml layout file using setContentView command:
setContentView(R.layout.B1);
Now, when the back button is pressed while xml file is loaded, it'll close the entire application. Is there a way to prevent this, say, return to the sub-activity or the main activity?
thanks for all your help.
You should override the onBackPressed method in your activity or sub activity:
#Override
public void onBackPressed() {
//TODO Do your task here
}
In your sub activity you should override the fallowing:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) //Override Keyback to do nothing in this case.
{
return true;
}
return super.onKeyDown(keyCode, event); //-->All others key will work as usual
}