I have an app (Java) which loads a fragment (Fragment A). This fragment has a recyclerView which in turn loads a second fragment (Fragment B). I want Fragment B to have a back arrow that can return to Fragment A, but I don't want the back arrow in Fragment A.
I added this code to the Main Activity:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
But this causes the back arrow to appear in every fragment.
How can I have the back arrow appear only on second level fragments (like B)?
you can hide the button on the wanted fragment like this
#Override
public void onResume() {
super.onResume();
((AppCompatActivity)getActivity()).getSupportActionBar(). setDisplayHomeAsUpEnabled(false);
}
#Override
public void onStop() {
super.onStop();
((AppCompatActivity)getActivity()).getSupportActionBar(). setDisplayHomeAsUpEnabled(true);
}
Related
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();
}
I have 3 tabs with lists of different video.In first tab when I click the item of my lyst the new activity started and play the video,this activity have parent my main activity with lists and this mainactivity have 1tab as main tab.But when I click in item in 2 tab,thid videoplayer started too,but back arrow go to main activity and main activity have 1 tab main,not second.It's very hard,but Im trying to explain:-)
How can I change this behavior,to go to 2 tab when click back arrow?
If when you have a toolbar then just add the following code in the onCreate. What this will do, it will work as the Back key of the smartphone. so it will close the current activity, and bring you back to what ever was on.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { finish(); } });
}
I have two Fragments in my ViewPager as Tabs. These share a toolbar. You get to the SettingsActivity by clicking an Icon on the toolbar.
So you can access the SettingsActivity while either Fragment A is the visible one, or Fragment B is the visible one.
When I navigate back from the SettingsActivity to the fragments, by clicking the Up Button in the toolbar (actionBar.setDisplayHomeAsUpEnabled(true);), I want to have the fragment visible, that I had visible when I accessed SettingsActivity.
Without any special code (= current state) it seems to always return to the first Fragment in the ViewPager (i.e. the most left one).
Parent Activity for the Up Navigation is MainActivity, where I have the ViewPager with the 2 Fragments as Tabs.
Use the state saving callback to save the state of your MainActivity:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("SELETED_TAB_INDEX", mSelectedTabIndex);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) { // so the activity is being restarted
pager.setCurrentItem(savedInstanceState.getInt("SELETED_TAB_INDEX"));
}
}
save your fragment to backstack. This way, back button for fragments would work same as it runs for activities.
Here: http://developer.android.com/training/implementing-navigation/temporal.html
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.
Is it possible to always navigate to main fragment on back button click?
I tried something like this
#Override
public void onBackPressed() {
super.onBackPressed();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStackImmediate();
}
It doesn't works.
So basically every time someone click the back button it should display Launcher Fragment and if user is already at Laucner fragment it should exit the app