When I press the back button to come back from a fragment, my activity shows a blank page.
What can I do to show the previous state of activity?
I use back stack in my project.
This is my code for pressing the back button:
public void onBackPressed()
{
if ( manager.getBackStackEntryCount() > 0 )
{
manager.popBackStack();
}
else
{
super.onBackPressed();
}
}
});
and this is for the fragment:
public void addFragmentA()
{
FragmentA a = new FragmentA();
getSupportFragmentManager().beginTransaction().replace(R.id.container, a,"fraga").addToBackStack("fraga").commit();
}
The code for the listener is:
manager.addOnBackStackChangedListener(this);
I want to work with a listener.
How can I do that?
You can use your Fragments View to move to any other Fragment or Activity.
In your Fragment.xml -> onCreateView() method
view.requestFocus();
view.setFocusableInTouchMode(true);
view.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
//Write you code here to go back to any activity or fragment
return true;
}
return false;
}
});
I have a fragment with several views in it. I want to catch the back button on it, so if a specific views in it is selected, just omit the button press and if that specific view is not selected, like any back button press do its job. I used the below code to catch the back button:
View v = inflater.inflate(R.layout.home_page, paramViewGroup, false);
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (fab.isSelected()) {
hideMenu();
fab.setSelected(!fab.isSelected());
}
// else
// How back button do its habitual job?
//
return true;
} else {
return false;
}
}
});
How can I change the code that the back button does its habitual job?
With current code, the back button never terminates the app in home page.
You should override the onBackPressed() method in the activity scope and call it from your onOptionsItemSelected method.
#Override
public void onBackPressed()
{
super.onBackPressed();
// Do your things.
}
public void method()
{
onBackPressed();
}
If you want to add some complex logic in the onBackPressed method, just create another one with parameters.
public void myOnBackPressed(int param1, String param2)
{
// Do your complex logic.
onBackPressed();
}
public void method()
{
myOnBackPressed(myInt, myString);
}
In your codes, you set return true. It means you process back button, you don't want emit the back button ouside.
You can call onBackPressed() in onKey() method to emit back button outside. Or you can process back button in onBackPressed() of fragment.
I am able to detect when the back button is pressed by using:
#Override
public void onBackPressed() {
//Do my thing
}
But now I want to detect when the back button is released. How can I do that? I'm unable to find any method like onBackReleased() which I can override to do my thing.
There is no method that specifically detects the back button release, but you could use the onKeyDown() and onKeyUp() methods. Check to make sure the key is the back button, and do your stuff in the method. Here is something you could do:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// do your stuff for when the back button is initially pressed
return true;
} else {
return false;
}
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// do your stuff for when the back button is released
return true;
} else {
return false;
}
}
If you wanted to override the default back press, you could just use the onBackPressed() method, like so:
#Override
public void onBackPressed() {
// Prevents the user from clicking the back button and returning to the parent activity
}
These methods can be implemented directly in your class. Hope it helps!
Question: How do I enable my back button to return to my previous hosting activity/fragment?
Situation: My launcher activity hosts a fragment while also contains a FAB. Clicking on the FAB launches a second activity which hosts another fragment. When the latter fragment is shown, a searchView is automatically expanded with focus on it. Pressing back closes the keypad. However, pressing back again does not return me to my launcher activity.
Things I've tried:
In my hosting activity
fm.beginTransaction().add(R.id.fragment_container, fragment).addToBackStack(null).commit();
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DOWN) {
return true;
}
return false;
}
In fragment
frag.getView().setFocusableInTouchMode(true);
frag.getView().setOnKeyListener( new OnKeyListener(){
#Override
public boolean onKey( View v, int keyCode, KeyEvent event ){
if( keyCode == KeyEvent.KEYCODE_BACK ){
return true;
}
return false;
}
} );
Also I've noticed that pressing the back button doesn't call either onBackPressed nor onKeyDown.
My application has an activity with so many fragments. I want to disable the back button press in some fragment. I tried with the below code. But it doesn't work.
In the main activity:
#Override
public void onBackPressed() {
super.onBackPressed();
OrderFragment.onBackPress();
}
In the fragment,
public static void onBackPressed()
{
Log.d(TAG,"It listen");
}
I have the log message but, how can I disable the back button from my fragment.
You should keep a reference to the fragment you want to disable/handle back press event on your main activity:
class MainActivity{
OrderFragment mOrderFragment;
#Override
public void onBackPressed() {
if(mOrderFragment.isVisible())
mOrderFragment.onBackPressed();
else
super.onBackPressed();
}
}
In OrderFragment:
public void onBackPressed() {
//handle back press event
}
In your oncreateView() method you need to write this code and in KEYCODE_BACk return should true then it will stop the back button option for particular fragment
View v = inflater.inflate(R.layout.xyz, container, false);
//Back pressed Logic for fragment
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
}
return false;
}
});
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCODE_BACK ) {
// leave this blank in order to disable the back press
return true;
} else {
return false;
}
}
});
I think you have to Override onResume method in fragments which you need to disable the back press.Tryout the following code.
#Override
public void onResume() {
super.onResume();
this.getView().setFocusableInTouchMode(true);
this.getView().requestFocus();
this.getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
return false;
}
});
}
Have you tried like this, Actually it works for me before.
you can set listener for Back key. if you add it, i guess it works.
youfragment.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return false;
}
}
);
super.onBackPressed in the activity is the default implementation. Remove this if you don't want it.
I know this is an old question and because of navigation components and new ways this situation rarely occurs, still, maybe my answer helps someone.
I came across a similar situation where I needed the back button to be disabled and I couldn't change the activity as well. So in a fragment, I added this code block.
Language: Kotlin
override fun onResume() {
super.onResume()
this.requireView().isFocusableInTouchMode = true
this.requireView().requestFocus()
this.requireView().setOnKeyListener { _, keyCode, _ ->
keyCode == KeyEvent.KEYCODE_BACK
}
}
This will disable your back press on that specific fragment
#Override
public void onBackPressed() {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof YourFragment) {
currentFragment.onBackPressed();
} else
super.onBackPressed();
}
override fun onBackPressed() {
val currentFragment = findNavController(R.id.nav_host_fragment).currentDestination?.id
if (currentFragment == R.id.YourFragment) {
return
}
super.onBackPressed()
If you don't want your fragment to be in the backstack you can do so, by not adding it to the backstack in the transaction. So do NOT call FragmentTransaction.addToBackStack(); on the fragments you do not want in your backstack.
onBackPressed works like this:
public void More onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
Thus when you call super.onBackPressed() you pop the BackStack before finishing the activity. The best way to sort this out is to make sure you do not add the fragments to the BackStack. It is normally done like this:
fragmentTransaction.addToBackStack(TAG);
An alternative solution, but uglier since you have still useless code left, would be making onBackPressed() directly call finish() to end the activity.
I would strongly advise you not use getView().setOnKeyListener(...) since it is code smell.
Try this
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}else{
super.onBackPressed();}
}