I'm using this tutorial to implement facebook login etc.
Facebook Login
I have added new fragment in this to show list of friends. Now when I press back button on my newly added fragment it takes me to the SPLASH fragment, I want same behaviour on back button on action bar. Means when I'm on my new fragment it shows me a back button on action bar. And pressing that back button takes me back to the SPLASH screen.
private void showFragment(int fragmentIndex, boolean addToBackStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
You can do that by two ways :
1. Inside your fragment
#Override
public void onDetach()
{
super.onDetach();
PUT YOUR CODE HERE
}
This will called when fragment will be finished.
2. Just add addToBackStack while you are transitioning between your fragments like below:
fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit();
if you write addToBackStack(null) , it will handle it by itself but if you give a tag , you should handle it manually.
EDITED:
for doing transactions
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
Fragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.replace(R.id.content_container, scheduleFragment, "scheduleFragment");
fragmentTransaction.addToBackStack("scheduleFragment");
fragmentTransaction.commit();
#Yawar actionbar is on activity only and this will added on activity it will be called evertime when u press actionbar home button-->
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; goto parent activity.
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
i got this code on stackoverflow after searching hard hope this may help you
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);// in on Create()
search for code onOptionsItemSelected(MenuItem item)
and edit it in this way
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// change your behaviour here
Intent intent = new Intent(this, yourclass.class);// i started new activity here
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
Related
I have a bottom navigation bar that contains 4 fragments and when a tab is selected a new instance of that fragment is loaded.
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
fragment = HomeFragment.newInstance();
break;
case R.id.navigation_cards:
fragment = CardsFragment.newInstance();
break;
case R.id.navigation_deals:
fragment = DealsFragment.newInstance();
break;
case R.id.navigation_settings:
fragment = SettingsFragment.newInstance();
break;
}
if (fragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content, fragment);
fragmentTransaction.commit();
}
return true;
}
};
Now in my HomeFragment there is a RecyclerView that On Item Select it opens a new Fragment:
myViewHolder.cardView.setOnClickListener(view -> {
System.out.println("clicked");
Fragment fragment = new TargetDetailsFragment();
FragmentTransaction ft = ((AppCompatActivity) context).getSupportFragmentManager()
.beginTransaction();
ft.replace(R.id.content, fragment).addToBackStack(null);
ft.commit();
});
I want to add a back button to the TargetDetails Fragments that takes you back to the home page when selected and I attempted doing that by implementing OnBackStackChangedListener in the Main activity
#Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0;
getSupportActionBar().setDisplayHomeAsUpEnabled(canback);
}
#Override
public boolean onSupportNavigateUp() {
//This method is called when the up button is pressed. Just the pop back stack.
getSupportFragmentManager().popBackStack();
return true;
}
}
but the problem is when I click on it its reloads the HomeFragment Again but I simply want it to go back to the saved instance of that Fragment
Here is my code that I have used for the ViewPager, the idea is to see if the current page number is 0 than to proceed super.onBackPressed(); otherwise go to the previous fragment:
#Override
public void onBackPressed() {
if(vpPager.getCurrentItem()!=0) {
vpPager.setCurrentItem(vpPager.getCurrentItem()-1, true);
} else {
super.onBackPressed();
}
}
By adding below code in your Activity.
The fragment back stack can be managed.
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
}
Hello #Bolu Okunaiya i think you should try this it will help you to manage backstack to desired fragment without loading same fragment again.
For Stop loading previous fragment you should use "add" instead of "replace" with your FragmentTransaction
Inside your MainActivity
#Override
public void onBackStackChanged() {
//shouldDisplayHomeUp();
Fragment currentFragment = getActivity().getFragmentManager()
.findFragmentById(R.id.fragment_container);
if (currentFragment instanceof TargetDetails) {
Log.v(TAG, "your current fragment is TargetDetails");
popBackStackImmediate(); //<<<< immediate parent fragment will open,which is your HomeFragement
}
}
To use popBackStackImmediate() you need to *replace FragmentA with FragmentB and use addToBackstack() before commit().
I have the following Activity code:-
public class legislator_info extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_legislator_info);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Legislator Info");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent i = getIntent();
String bioguide = i.getExtras().getString("Person");
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// click on 'up' button in the action bar, handle it here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
So basically I have a fragment which has a list view displayed in it. On click of a list Item I start this activity and I want to go back to the previous fragment on the back button click. I tried the above code but I am not able to travel back. Am pretty new at this any help is appreciated.
I have added my fragment in the following way:-
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
LegislatorFragment lf = new LegislatorFragment();
ft.replace(R.id.fragment_container,lf);
ft.addToBackStack(null);
ft.commit();
I am still not clear what you want to achieve but you can try this
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
EDIT:
case android.R.id.home:
//call onBackPressed here
onBackPressed();
return true;
You have to override onOptionsItemSelected because you are trying with Action bar's back button.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
Then override BackPressed -
#Override
public void onBackPressed()
{
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
else {
super.onBackPressed();
}
}
My PanelActivity contains a recyclerView with a list of items. Each item has a click event. This click opens DetailsActivity.
DetailsActivity has a floatingActionButton that opens a full screen dialog (my class DetailDialogFragment extends DialogFragment).
DetailDialogFragmenthas an Up/Home button with a dismiss.
The problem: If the user performs a click over the Up button, the dialog is dismissed, but also DetailsActivity disappear, and the app returns to the PanelActivity.
Possible reason: Under the Up button of the dialog is the Up button of the DetailsActivity. Is it possible to fire two click events when a dialog is over an activity and both have an Up button on the same place?
Edit: To show some code.
Open DetailsActivity from PanelActivity (clicking one item in the recyclerView).
Intent intent = new Intent(context, DetailsActivity.class);
intent.putExtra("headerCode", headerCode.getText());
context.startActivity(intent);
Up button in DetailsActivity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
Open full screen dialog in DetailsActivity.
private void showCreateDetailDialog() {
FragmentManager fragmentManager = getSupportFragmentManager();
DetailDialogFragment newFragment = new DetailDialogFragment();
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, newFragment)
.addToBackStack(null).commit();
}
And finally, Up button in DetailDialogFragment.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.save) {
validateForm();
return true;
} else if (id == android.R.id.home) {
// handle close button click here
dismiss();
return true;
}
return super.onOptionsItemSelected(item);
}
I haven't tested it but I think the problem is here, where you call dismiss(). You may need a reference to the DialogFragment first. I think technically you're just calling this.dismiss(); where this equals the Activity you're working in.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.save) {
validateForm();
return true;
} else if (id == android.R.id.home) {
// handle close button click here
dismiss(); // problem is with this call
return true;
}
return super.onOptionsItemSelected(item);
}
You could try something like this:
private DetailDialogFragment detailFragment;
private void showCreateDetailDialog() {
detailFragment = new DetailDialogFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.add(android.R.id.content, newFragment).addToBackStack(null).commit();
}
and now inside onOptionsItemSelected():
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.save) {
validateForm();
return true;
} else if (id == android.R.id.home) {
// handle close button click here
detailFragment.dismiss();
return true;
}
return super.onOptionsItemSelected(item);
}
No, I think that's not possible, maybe is a problem of your device, test it on an Android Emulator or another device. Can you please share your code to try to help you?
App has Viewpager that has four tab with fragment. Second fragment has framelayout "FL" where I put fragment with listview. And when user click listview item opened new fragment with listview in this framelayout "FL" and and so on.
I am going to do catalog with prudacts with multilevel category.
My quation: How can I implement that in second fragment when I opened fragment level 3 than by clicking Toolbar home button go back to fragment level 2 and to another click back to fragment level 1 (popBackStack) and finally when click Toolbar home button go to first Tab. Any help be usefull for me. Thanks
There is what I fecit:
I use home button for go First Tab from other Tabs:
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.this.setCurrentItem(0, true);
}
});
To replace fragment use the below code
#Override
public void replaceFragment(Fragment fragment, String title) {
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) { //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.container_body, fragment);
ft.addToBackStack(backStateName);
ft.commit();
// getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setTitle("");
}
}
Add the below mentioned code in your fragment class
Add the below line in your Fragment onCreateView
setHasOptionsMenu(true);
Use the below code to go back the previous fragment.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
return true;
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onDetach() {
super.onDetach();
if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
}
}
My app has a navigation drawer with three items linking to three fragments A, B and C
when I click on the back button from any of the Fragments, the app exits.I solved this by declaring these constants in my base activity:
public static boolean IS_FRAGMENT_A = false;
public static boolean IS_FRAGMENT_B = false;
public static boolean IS_FRAGMENT C = false;
and then in the selectView method I did this:
private void displayView(int position) {
IS_FRAGMENT_A = false;
IS_FRAGMENT_B = false;
IS_FRAGMENT_C = false;
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FragmentA();
IS_FRAGMENT_A = true;
break;
case 1:
fragment = new FragmentB();
IS_FRAGMENT_B = true;
break;
case 2:
fragment = new FragmentC();
IS_FRAGMENT_C = true;
break;
default:
break;
}
And in the overriden onBackPressed() method I did this
public void onBackPressed() {
if (IS_FRAGMENT_A) {
finish();
} else {
displayView(0);
}
}
This works fine when am navigating to these fragments from the navigation drawer.However, when I go to any of the fragments through an ActionBar button, the onBackPressed method does not work.
In Fragment A, I have an ActionBar button that takes me to Fragment B:
public boolean onOptionsItemSelected(MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.action_new:
Fragment fragmentB = new FragmentB();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, fragmentB);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
return true;
default:
return super.onOptionsItemSelected(menuItem);
}
}
When I press the back button from FragmentB after navigating to it via this method the app exits, unlike when I navigate to it through the navigation drawer.
I have tried adding this to the onCreate() method of FragmentB with no luck:
BaseActivity.IS_FRAGMENT_B = true;
My question is, how do I make the back button work in all fragments irrespective of how I got there?