How to intercept the fragment call to popBackStack() in MainActivity? - android

In my Application, i'm transitioning to a DetailsFragment when the user clicks on a list item. and there are TWO options to be back at the main Fragment (the List Fragment).
Press the back button. (no problem here, because I handle this in onBackPressed() in MainActivity)
Press the Toolbar back arrow (Here is my problem).
When the user presses the toolbar back arrow, I call the following
getActivity().getSupportFragmentManager().popBackStack();
how can I intercept this event in MainActivity?
(There are some manipulations I am doing in MainActivity when the List Fragment is visible to the user.

Just put this code
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});

Related

Fragment not attached to Activity when back pressed

I have an implementation of fragment as explained here. I have expanded the BaseFragment class to handle navigation icon onClickListener. The code for that looks like this,
private void onBackButtonPressed(int tag)
{
switch (tag)
{
case Global.DISPLAY_STORE:
{
setTitle("Loyalty Cards",Color.BLACK);
setToolBar(getResources().getColor(R.color.white), Global.ADD_CARD,R.drawable.add_round_btn);
break;
}
case Global.ADD_CARD:
{
setTitle("Wallet", Color.WHITE);
setToolBar(getResources().getColor(R.color.colorPrimary), Global.DISPLAY_STORE,R.drawable.icon_shopping);
getFragmentManager().popBackStack();
break;
}
case Global.CARD_DETAILS:
{
setTitle("Loyalty Cards",Color.BLACK);
setToolBar(getResources().getColor(R.color.white), Global.ADD_CARD,R.drawable.add_round_btn);
getFragmentManager().popBackStack();
break;
}
}
}
I am using this block of code to change the ToolBar icons and colors when back button is pressed.This code resides in BaseFragment.
Here is how I implement the code to handle back press,
I have my fragment extending the BaseFragment
public class CardDetailsFragment extends BaseFragment
Now inside the BaseFragment onCreate I have this code,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = (MainActivity) getActivity();
ImageButton righBarButton = (ImageButton) mainActivity.getToolbar().findViewById(R.id.btn_ToolBarRightBtn);
righBarButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onRighBarButtonClicked(Integer.parseInt(v.getTag().toString()));
}
});
mainActivity.getToolbar().setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackButtonPressed(BACK_BUTTON_TAG);
}
});
getFragmentManager().addOnBackStackChangedListener(this);
shouldDisplayHomeUp();
}
By this every fragments back button press and the right bar button item click in toolbar are handled.
Consider the scenario I have three fragments A , B and C.
From Fragment A I open Fragment B and Then Fragment C. Now From fragment C I click the back button to reach fragment B. The back button event is handled by above code and it works fine.
Now from Fragment B, I click the back button to reach Fragment A. But when I click back button I am getting exception
java.lang.IllegalStateException: Fragment CardDetailsFragment{d8b35b5} not attached to Activity
at android.support.v4.app.Fragment.getResources(Fragment.java:636)
here the CardDetailsFragment is the FragmentC, but I am clicking the
back button from Fragment B
The first time the user presses the back button, Fragment C is no longer necessary and thus it is detached from the activity. The problem lies in the fact that even though Fragment C is detached, it is still registered as a listener for back stack change events.
The second time the user presses the back button, your onBackStackPressed() method is called in Fragment C. When getResources() is executed, there is no activity attachment so getResources() fails.
Something like this in your fragment should fix it:
#Override
public void onDestroy() {
getFragmentManager().removeOnBackStackChangedListener(this);
super.onDestroy();
}

Is it possible to set different actions for floating action button in differet fragments?

I am working or an app where I have 4 fragments in viewpager and floating action button (fab). When I click on fab there appear 3 subfabs. Each of them start different activities where user can search data from different fragments. Is it possible to set fab so that if I click on it while I'm in first fragment it'll open an activity for searching inside this fragment, onClick inside second - search for second and etc. The issue is that now clicking on sub fab while I'm in some fragment I can search data from another fragment too and it's a bit weird. I understand question is kinda strange, if something is unclear I'll explain further
You can make FAB button public and implement onClick listener in each fragment.
You should override setUserVisibleHint and put your code onResume so getActivity() will not return null. Fab button will have different actions in different fragments.
Here's an example, inside each fragment when you want Fab click listener:
#Override
public void setUserVisibleHint(boolean visible)
{
super.setUserVisibleHint(visible);
if (visible && isResumed())
{
onResume();
}
}
#Override
public void onResume()
{
super.onResume();
if (!getUserVisibleHint())
{
return;
}
MainActivity mainActivity = (MainActivity)getActivity();
mainActivity.fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you want
}
});
}
You can check in onclick method of floating action button which fragment is currently opened and calling it.
Call findFragmentById() on FragmentManager and determine which fragment is in your R.id.frameTitle container.

Replace fragment of one viewpager with fragment of another viewpager in the same activity back key pressed

I have 2 viewpagers: swipeViewPager and nonSwipeViewPager in MainActivity
In swipeableViewPager, I have fragments: homeFragmentFirst and homeFragmentSecond
In nonSwipeableViewPager, I have fragments: AppleFragment , MangoFragment, GrapesFragment and CherryFragment
First I want swipeableViewPager to be viewed in MainActivity. So I have set setVisibility of nonSwipeableViewPager as GONE.
After selecting an item from the drawer, I setVisibility of swipeableViewPager as GONE and of nonSwipeableViewPager as Visible.
By this, I open AppleFragment
Situation:
Suppose, I selected Grapes from drawer, GrapesFragment opens.
I do my some stuff there. And then when I press back button, the app closes i.e. the MainActivity closes.
What I want is when back button is pressed, I want to again bring back homeFragmentFirst from swipeableViewPager.
I have tried below code in GrapesFragment
#Override
public void onBackPressed() {
super.onBackPressed();
// Do some operations here
MainActivity mainActivity = new MainActivity();
mainActivity.swipeHomeViewPager.setVisibility(View.VISIBLE);
mainActivity.nonSwipeHomeViewPager.setVisibility(View.GONE);
}
I solved it myself. I added following in MainActivity:
#Override
public void onBackPressed() {
if (nonSwipeHomeViewPager.getVisibility() == View.VISIBLE) {
nonSwipeHomeViewPager.setVisibility(View.GONE);
swipeHomeViewPager.setVisibility(View.VISIBLE);
swipeHomeViewPager.setCurrentItem(0,true);
} else if (swipeHomeViewPager.getVisibility() == View.VISIBLE){
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
You can implement backstack for the fragments (while adding / replacing fragment) add it to backstack. the back press will automatically take you to previous fragment.
otherwise you need to override OnBackPressed method to handle with your own logic.

BackButton in the Fragment cannot be disabled

I have a mainActivity with viewPager and three tabs, each tab has its respective fragment. i want when this mainActivity is launched and the backButton is pressed, nothing to happen.
to achieve this, i override onBackPressed() inside the mainActivity the one has viewPager with tabs, but when the mainActivity ia launched one of the tabs, which represents Fragment, by default appears, and when i press the backButton, i go back, which means the Backbuton is not disabled.
that is it, in the mainActivity, i have:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Log.w(TAG, "#onBackPressed().");
}
and he backbutton is not disabled in the Fragment, each time i press it, the logCat displays the message in the onBackPressed and i go back, and i do not want this, i want while i am in the Fragment "any one of the tabs", the backButton should has no effect.
please let me know how to achieve this?
Try not calling
super.onBackPressed();
Although the log will still print because the method will be called, this will stop Android performing it's logic and going back.
If you want the fragment tabs to do nothing, but the viewpager to handle it, do something like this
#Override
public void onBackPressed() {
if (getCurrentTab == 0) {
super.onBackPressed();
} else {
//This will stop the fragment tabs from doing anything when back is pressed
}
}
If you need avoid the back button, comment the super call //super.onBackPressed();

In Android, override a method using Button onClick

I've got a Main Activity which is a search interface, when the user clicks a result in the list, the result details are displayed in a Fragment. The Main Activity has an Action Bar, but in the details Fragment, the Action Bar is hidden. To hide the Action Bar in the Fragment, I'm calling a method in the Main Activity from the Fragment Activity like this: ((SearchInterface)getActivity()).hideABar();. Then when the user clicks the back button, they go back to the search interface and the Action Bar reappears. Doing that is a bit more complex than simply calling a method. I set up an Interface in the Main Activity and override the method in the Fragment like this:
Main Activity:
public interface Callback {
public void onBackPressedCallback();
}
#Override
public void onBackPressed() {
super.onBackPressed();
if(fragBackPressed != null)
fragBackPressed.onBackPressedCallback();
checkActionBarState();
}
...
public void checkActionBarState(){
bar_AB = getSupportActionBar();
boolean barVisible = bar_AB.isShowing();
if(barVisible){
Toast.makeText(getApplicationContext(),"ActionBar WAS Visible",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(),"ActionBar WAS NOT Visible",Toast.LENGTH_LONG).show();
bar_AB.show();
}
}
Fragment:
#Override
public void onBackPressedCallback() {
Log.d("SSIVideoFrag", "checking action bar state");
}
So now, when the user presses the Back button while in the Details Fragment, they go back to Main Activity and the Action Bar reappears. Now I'd like to add a button in the Details Fragment that does what clicking the Back button does, but I can't figure out how to do it. I don't know how to override the onBackPressedCallback() method from within the onClick of a Button:
back_BTN.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
//--- what to do here?
}
});
simple:
getFragmentManager().popBackStack();
https://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()
ps.: that's not an actual back press, your onBackPressed will not be called. But the fragment will be removed, just like in a back press.

Categories

Resources