How can i get the current Fragment ID - android

I did a navigation drawer, and I’ve set some items and normally when I select an item the current fragment will be changed by a new one, it's not the case for me, the first Activity still displayed even if the fragments change. This is my onNavigationDrawerItemSelectedmethod and it's clear I change the fragment every time i click on a new one.
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
// TODO : Added
switch(position) {
/*case 0 :
fragmentManager.beginTransaction()
.replace(R.id.container, new ProfilFrgement())
.commit();
break;*/
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, new SpotFragement())
.commit();
break;
case 2:
fragmentManager.beginTransaction()
.replace(R.id.container, new SessionsFragement())
.commit();
break;
/*case 3:
fragmentManager.beginTransaction()
.replace(R.id.container, new EventsFragment())
.commit();
break;*/
}
}
I think my problem is a change always the same container. So what I need its getting the current fragment ID

Sorry for too late but I have a solution to get fragment ID. You can use name of Fragment Class as an Identifier not the ID. Use a static String variable to store class name.
public class Activity{
...
static String currentFragment = null;
...
...
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_one:
setFragment(new oneFragment());
break;
case R.id.nav_two:
setFragment(new twoFragment());
break;
}
return true;
}
public static void setFragment(#NonNull Fragment f) {
if(!f.getClass().getName().equals(currentFragment)){
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, f);
fragmentTransaction.commit();
currentFragment = f.getClass().getName();
}
...
}

What is current fragment ID here? Ur id is R.id.container which is only one rt? then what is the question about "How can i get the current Fragment ID"?
If question is to find which is the current fragment is shown to user? If yes then
Fragment ft = getSupportFragmentManager().findFragmentById(R.id.container);
if (ft instanceof SpotFragement) {
// navigation drawer item 1 and current fragment is SpotFragment.
} else if (ft instanceof SessionsFragement) {
}

Make sure that your container styling is correct.
Check following values of container once -
android:layout_width
android:layout_height

Related

Fragment replaced by another Fragment in an Activity, how to navigate?

I'm using a NavigationDrawer and one Activity where I'm replacing Fragments within the FrameLayout. Navigating through NavigationDrawer and replacing Fragments inside of the Activity is straightforward. I'm not sure how to handle when I replace a Fragment from another Fragment. Example:
I show a Fragment which is a basic List, and when the user clicks on one of the items, I show a new Fragment. Now, from this new Fragment, I may choose to show another Fragment, which results in a deeper Fragment hierarchy. I know that I can navigate through with
.addToBackStack() and in the case of Back button, call
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
from the Activity, but as deeper the Fragment hierarchy gets, the more complicated and dirty it becomes. Is there a good article, or architectural approach to handle a case like this one?
In your scenario you should use Nested Fragments.
You can embed fragments inside fragments.
To nest a fragment, simply call getChildFragmentManager() on the Fragment in which you want to add a fragment. This returns a FragmentManager that you can use like you normally do from the top-level activity to create fragment transactions. For example, here’s some code that adds a fragment from within an existing Fragment class:
Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();
From within a nested fragment, you can get a reference to the parent fragment by calling getParentFragment(). And then your parent backstack and child backstack will be separated.
This is how to do it right. The other question is maybe you should consider using intent and new activity instead of 10 nested fragments? Here is an article about child fragments.link
Stack similar question
Make Fragments tags in your Main Activity:
//----------------Fragment TAGS-----------------------\\
private final String FRAGMENT_BOOK_RIDE = "Frag Book Ride";
private final String FRAGMENT_RIDE_HISTORY = "Frag Ride History";
private final String FRAGMENT_PAYMENT = "Frag Payment";
private final String FRAGMENT_PROFILES_SETTINGS = "Frag Profile & Settings";
private final String FRAGMENT_HELP = "Frag Help";
//-----------------------------------------------------\\
Navigation item selection:
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here. \\
int id = item.getItemId();
switch (id) {
case R.id.nav_book_ride:
removeAllFragments();
getSupportActionBar().setTitle(getResources().getString(R.string.app_name));
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new BookRideFragment(getApplicationContext())
, FRAGMENT_BOOK_RIDE)
.commit();
break;
case R.id.nav_ride_history:
removeAllFragments();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new RideHistoryFragment(getApplicationContext())
, FRAGMENT_RIDE_HISTORY)
.commit();
break;
case R.id.nav_payment:
removeAllFragments();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new PaymentFragment(getApplicationContext())
, FRAGMENT_PAYMENT)
.commit();
break;
case R.id.nav_settings:
removeAllFragments();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new ProfileSettingFragment(getApplicationContext())
, FRAGMENT_PROFILES_SETTINGS)
.commit();
break;
case R.id.nav_help:
removeAllFragments();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new HelpFragment(getApplicationContext())
, FRAGMENT_HELP)
.commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
Handling backKey press:
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
backKeyMethods();
}
}
/**
* Custom back key method for managing fragment back key behavior
*/
private void backKeyMethods() {
RideHistoryFragment rideHistoryFragment = (RideHistoryFragment) getSupportFragmentManager().
findFragmentByTag(FRAGMENT_RIDE_HISTORY);
PaymentFragment paymentFragment = (PaymentFragment) getSupportFragmentManager().
findFragmentByTag(FRAGMENT_PAYMENT);
HelpFragment helpFragment = (HelpFragment) getSupportFragmentManager().
findFragmentByTag(FRAGMENT_HELP);
ProfileSettingFragment userProfileFragment = (ProfileSettingFragment) getSupportFragmentManager().
findFragmentByTag(FRAGMENT_PROFILES_SETTINGS);
if (rideHistoryFragment != null && rideHistoryFragment.isVisible()) {
navigationView.setCheckedItem(R.id.nav_book_ride);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new BookRideFragment(getApplicationContext())
, FRAGMENT_BOOK_RIDE)
.commit();
} else if (paymentFragment != null && paymentFragment.isVisible()) {
navigationView.setCheckedItem(R.id.nav_book_ride);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new BookRideFragment(getApplicationContext())
, FRAGMENT_BOOK_RIDE)
.commit();
} else if (userProfileFragment != null && userProfileFragment.isVisible()) {
navigationView.setCheckedItem(R.id.nav_book_ride);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new BookRideFragment(getApplicationContext())
, FRAGMENT_BOOK_RIDE)
.commit();
} else if (helpFragment != null && helpFragment.isVisible()) {
navigationView.setCheckedItem(R.id.nav_book_ride);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_fl, new BookRideFragment(getApplicationContext())
, FRAGMENT_BOOK_RIDE)
.commit();
} else if (getFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
/**
* Remove all fragments in Fragment BackStack
*/
private void removeAllFragments() {
FragmentManager fm = getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
}
Use addToBackStack(null) whenever you want to go deep, so when you will press backKey it will pop immediate fragment.
Hope it helps.

Replace fragments in FrameLayout layout

I have tried every tutorial on the first google page about android fragments, but I can't get anything to work.
So I have one navigation bar activity, MainActivity.
Now I'd like to change fragments on a click in the drawer.
In my content_main (default fragment in the MainActivity activity), I have a framelayout that I wish to put the fragments in. I have the following fragments: fragment_main, fragment_one and fragment_two. And I wish to show these when I click on a button in the nav drawer.
The reason I want to use fragments is so that the nav drawer will stay on top.
Thanks in advance!
Edit: Here is the function I'll use to change fragments:
It's just to test, not finished.
public void setFragment() {
android.support.v4.app.FragmentTransaction transaction;
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, new LoginFragment());
transaction.commit();
}
I solved it!
Apparently, I had to use android.support.v4.app.Fragment; instead of android.app.Fragment;.
This is the code I got it to work with:
protected void setFragment(Fragment fragment) {
android.support.v4.app.FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.fragment_container, fragment);
t.commit();
}
And to set it (from the nav bar onNavigationItemSelected(), you do this:
setFragment(new RoosterFragment());
I hope this helps others out with the same frustrating problem.
Accroding to your question,
This is FrameLayout
<FrameLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/view"
android:layout_marginTop="#dimen/medium_margin"></FrameLayout>
Now , call displayview method onCreate() of your activity,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//rest of your code here
displayView(0); // fragment at 0 position
}
displayView method, which have three fragements
public void displayView(int position) {
switch (position) {
case 0:
tvTitle.setText(getResources().getString(R.string.signin_tile));
showFragment(new LoginFragment(), position);
break;
case 1:
tvTitle.setText(getResources().getString(R.string.forgot_password_tile));
showFragment(new ForgotPasswordFragment(), position);
break;
case 2:
tvTitle.setText(getResources().getString(R.string.change_password_tile));
showFragment(new ChangePasswordFragment(), position);
break;
}
}
showFragment method called from displayView method,
public void showFragment(Fragment fragment, int position) {
FragmentTransaction mTransactiont = getSupportFragmentManager().beginTransaction();
mTransactiont.replace(R.id.main_container, fragment, fragment.getClass().getName());
mTransactiont.commit();
}
Did you try this? Click here
This link will Help you, to create fragment.
and this is what you want for navigation drawerClick here
Try this one. it is my newbie code easier to understand :)
FragmentTransaction transaction;
switch (id){
case R.id.button_fragment_one:
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, new FragmentOne());
transaction.addToBackStack(null);
transaction.commit();
break;
case R.id.button_fragment_two:
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, new FragmentTwo());
transaction.commit();
break;
default:
break;
}

Android Fragment switching from navigation drawer causes app to quit

I have the slider menu displayview method as:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
FragmentManager fm = getSupportFragmentManager();
String tag = fragment.getTag(); // instance method of a to get a tag
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
drawerListView.setItemChecked(position, true);
drawerListView.setSelection(position);
setTitle(navMenuTitles[position]);
drawer.closeDrawer(drawerListView);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
I have a fragment called home_fragment whose code behind is HomeFragment.java
When I click on this fragment first it works fine, but on clicking next from the siding menu at index 0 I get an error as:
Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim' on a null object reference
What am I doing wrong? Thanks.
This is where I'm having error:
case OP_REMOVE: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.removeFragment(f, transition, transitionStyle);
} break;
This code is present in BackStackRecord.java
You shouldn't be calling container.removeAllViewsInLayout().
The FragmentManager will handle all the view manipulation on the container when you call FragmentTransaction.replace(), including removing the current fragment view. You are probably getting an error because the FragmentManager expects a fragment's view to be in the container, but you've removed it.
All you need is this:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
// set fragment to other nav target
fragment = ...
break;
.
.
.
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
drawerListView.setItemChecked(position, true);
drawerListView.setSelection(position);
setTitle(navMenuTitles[position]);
drawer.closeDrawer(drawerListView);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
Also I noticed you are using getFragmentManager(). Please check your class imports and make sure that you have the right call.
If HomeFragment extends android.app.Fragment, use getFragmentManager().
If HomeFragment extends android.support.v4.app.Fragment, use getSupportFragmentManager().

Fragment removes when Orientation changes

I am using fragment in my application. When I change the orientation the fragment removes and my main activity gets visible from which I have added this fragment. below is the code -
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ManageDataFragment();
break;
case 1:
fragment = new DownloadFragment();
break;
case 2:
fragment = new UserInfoFragment();
break;
case 3:
fragment = new AboutAppFragment();
break;
case 4:
fragment = new ShareAppFragment();
break;
case 5:
fragment = new SettingsFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
setTitle(menutitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
I am using this fragment from navigationDrawer like in Gmail application.
What should I do that my fragment remains even I change the orientation of device?
Thanks in Advance
I don't think the accepted answer is the correct so I'm writing this one:
When replacing the fragment you should use the method replace with three arguments so you can find your fragment later:
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment, TAG_FRAGMENT).commit();
Where TAG_FRAGMENT is some string tag.
Then in onCreate if the activity was restarted you can find your fragment and add it to the container:
if(savedInstanceState != null) {
fragment = getFragmentManager().findFragmentByTag(TAG_FRAGMENT);
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment, TAG_FRAGMENT).commit();
}
I had exactly the same problem as mentioned above and I fixed it in the AndroidManifest by adding this:
<activity
...
android:configChanges="orientation|screenLayout|screenSize|layoutDirection">
Hope this helps!
Probably should save position using onSaveInstanceState() and test the bundle argument to onCreate().

Oncreate call multiple times due to fragment transaction

ffIn Main Activity,
private void navigateTo(int position) {
Log.v(TAG, "List View Item: " + position);
switch(position) {
case 0:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, new Home(), Home.TAG).commit();
break;
case 1:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame,
TabbedActivity.newInstance(),
TabbedActivity.TAG).commit();
break;
case 2:
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, History.newInstance(), History.TAG).commit();
}
}
When i navigate to my home fragment through navigation drawer(based on the method above), it run onCreate method everytime. From my understanding, fragment cycle should run oncreateview instead oncreate method when you navigate between the screen through navigation drawer(since onpause>oncreateview). Can anyone provide a solution for me that can make sure onCreate only run once?
You are creating new instances each time you call navigateTo.
You should do something like this...
FragmentManager fragManager = getSupportFragmentManager();
// try to find an existing instance
Fragment frag = fragManager.findFragmentByTag(Home.TAG);
if (frag == null) {
// if none were found, create it
frag = new Home();
}
fragManager.beginTransaction().replace(R.id.content_frame, frag, Home.TAG).commit();

Categories

Resources