I'm starting to work with fragments and ran into a problem. I have file viewing fragments(more than one) and a search fragment. To make things easier I add my file viewing fragment to backstack whenever I go to search so I could easily pop it back if I decide to just close it. Now the problem is that when I press on file in the search fragment so that I travel to the specific fragment in which that file is, the onCreateView of the first fragment(which was in backstack) always gets called even though I replaced it(?) and I don't want that. Here are things I do to change the fragments on search file press:
1.I call pop to get to previous fragment
#Override
public boolean onSearchViewClose() {
if (getActivity() != null) {
getActivity().getSupportFragmentManager().popBackStack();
return true;
}
return false;
}
2. Then I replace the remaining fragment
public void setFragment(Fragment fragment, String tag, boolean clearBackStack, boolean addToBackStack) {
// Insert the fragment by replacing any existing fragment
hideLoadingProgress();
FragmentManager fragmentManager = getSupportFragmentManager();
if (clearBackStack) {
clearBackStack(fragmentManager);
}
FragmentTransaction transaction = fragmentManager.beginTransaction().replace(R.id.content_frame, fragment, tag);
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
while clearing backstack:
public void clearBackStack(FragmentManager fragmentManager) {
for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) {
fragmentManager.popBackStack();
}
}
Even if I don't clear backstack the problem persists.Thanks for your answers in advance.
The answer was simple - I should've just used getActivity().getSupportFragmentManager().popBackStackImmediate(); when exiting search view as the earlier method didn't work because it waited for program to return to its event loop (asynchronous).
Related
Im trying with no success to disable the back key only in one fragment, in the first one.
I did the override of the onBackPressed method on the Activity that contains the fragment with this:
#Override
public void onBackPressed() {
if (this.fragmentManager.getBackStackEntryCount() > 1) {
//getFragmentManager().popBackStack();
super.onBackPressed();
} else {
//super.onBackPressed();
}
}
So, it works perfectly. BUT when i finish all the path of fragments, at the final fragment i have a button that take me back to the first fragment. I will paste the code where i load this fragment again.
for (Fragment fragment1:getSupportFragmentManager().getFragments()) {
getSupportFragmentManager().beginTransaction().remove(fragment1).commit();
}
MontoFragment montoFragment = new MontoFragment();
cargarFragment(montoFragment);
And here the "cargarFragment()" method
public void cargarFragment(Fragment fragment){
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.animation_slide_in,R.anim.animation_slide_out);
fragmentTransaction.replace(R.id.layoutContenedorFragments,fragment);
fragmentTransaction.addToBackStack(null).commit();
}
After i complete all the fragments and i go back to the first one with that, my onBackPressed method doesnt work anymore, because this.fragmentManager.getBackStackEntryCount() > 1 now is 5 or 6 i dont remember now. And this make the back key enable.
So i dont know what to do.
Thanks!
I just achieve it with this code
#Override
public void onBackPressed() {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.layoutContenedorFragments);
if (currentFragment instanceof MontoFragment){
}else{
super.onBackPressed();
}
}
i got the current fragment and if this one is an instanceOf That Fragment just do nothing but if not just do the normal onBackPressed.
I look that it works great
try to use popBackStack, replace code block:
for (Fragment fragment1:getSupportFragmentManager().getFragments()) {
getSupportFragmentManager().beginTransaction().remove(fragment1).commit();
}
MontoFragment montoFragment = new MontoFragment();
cargarFragment(montoFragment);
by
void popFragments(int number) {
for (int i = 0, i < number, i++) {
supportFragmentManager.popBackStackImmediate()
}
}
number here is the number of fragments you want to remove, ex: we have fragment 1,2,3,4, so when we are in fragment 4 and want to back to fragment 1, so the number will be 3.
When the map fragment opens for the first time it calls onMapReady and it adds a marker in there and zooms towards with animation.
I want if user click a button on the map, the map will restart as if its open like the begining with zoom and whatnot.
I tried using the method below which I call when I click the button, but it only recreate the map but it didn't call onMapReady because it didn't add maker or anything.!
public void reLoadFragment(Fragment fragment) {
Fragment currentFragment = fragment;
if (currentFragment instanceof MapTransportFragment_BusDriver) {
FragmentTransaction fragTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();
}
}
Edit #1
I call the method using all three ways belowa and it gives me the same error.
/*1*/ reLoadFragment(this);
/*2*/ reLoadFragment(MyMap.this);
/*3*/ reLoadFragment(new MyMap()); // MyMap is the name of the current fragment.
However, If you want just to restart your fragment it means you want to create new fragment. calling detach and attach doesn't destroy fragment.So try below code
public void reLoadFragment(Fragment fragment) {
Fragment currentFragment = fragment;
if (currentFragment instanceof MapTransportFragment_BusDriver) {
FragmentTransaction fragTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragTransaction.replace(R.id.YourFragmentContainer,currentFragment,"TAG");
fragTransaction.commit();
}
}
my fragment transition is happened very weirdly. I am trying to open up new fragment upon back button is pressed:
//removed code
Then, when I am at home fragment, without me back press again, it will close the apps:
// removed code
I don't understand why switching from one fragment to another shares the same onKey? As in isn't it supposed to be behave like this: I back press in fragment 2, open up home fragment, inside home fragment I back press again, then it closes the apps.
Currently it's working like this: fragment 2 back press, open up home fragment, without me touching any thing, it goes into the onKey in home fragment.
Any ideas? Thanks in advance.
Remove finish call "getActivity().finish();" then try...
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 ) {
getActivity().moveTaskToBack(true);
return true;
} else {
return false;
}
}
});
If not then try another solution...Add this method in your parent activity.
#Override
public void onBackPressed() {
FragmentManager fragmentmanager = getSupportFragmentManager();
if(fragmentmanager.getBackStackEntryCount() > 0){
fragmentmanager.popBackStack();
} else{
finish();
}
}
I'm running into trouble. I have a Fragment with an onclicklistener. The fragment calls "ClickMe" which is in my Activity that hosts the fragment. However, in order for ClickMe to not error out, ClickMe has to be static. But, Clickme can't be static because then getFragmentManager errors out. Essentially I'm trying to create a game. A click will put a new fragment over the top of the old one (as you have to do the same thing 10 times in a row in my game. Here's the code:
Fragment:
text1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(loc1 == 10 || loc2 ==10){
//Text if user wins
BlankFragment.counter ++;
BlankFragment.ClickMe(BlankFragment.counter);
Log.i("Win: ", "Yay");
}else{
//Text if user loses
Log.i("Lose: ", "Boo");
}
}
});
MainActivity:
public void ClickMe(int count){
Fragment newFragment;
counter = count;
if(counter > 5){
newFragment = new g3by3Fragment();
}else{
newFragment = new g3by3Fragment();
}
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, newFragment);
transaction.addToBackStack(null);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
Thank you for your help!
You don't have to preform FragmentTransactions from the Activity. You can just add well preform them from the Fragment. Your detour into the Activity through ClickMe is unnecessary. I know you probably do this because the logic of your game is in the Activity but that is not optimal. Let the Fragments themselves decide which Fragment comes next or implement a Singleton which takes care of your game logic.
I'm trying to get the handle on all the new ActionBar and Fragments API.
I have an main activity, and I want it to manage two different tabs.
I'm using the ActionBarSherlock in order to support older version than ICS.
Each tab contains its own Fragment (each one is a subclass of SherlockListFragment)
I got it to work basically nice, but I have a problem that I'm sure that is stupid, but I can't figure it out yet:
On the first time each Fragment is shown, everything is OK, the list is populated and so the MenuItems in the ActionBar.
But the second time you see a tab (After swicth and switch-back), Neither the list get populated, nor the ActionBar MenuItems.
This is how I'm switching the tabs:
#Override
public void onTabSelected(Tab tab, FragmentTransaction transaction) {
SherlockListFragment toAttach = // Find the right fragment here...
if (toAttach != null) {
if (toAttach.isAdded() == false) {
transaction.add(R.id.tab_placeholder, toAttach,
REMINDER_FRAGMENT_TAG);
} else {
transaction.attach(toAttach);
}
}
}
And onTabUneselect I'm detaching the Fragment:
#Override
public void onTabUnselected(Tab tab, FragmentTransaction transaction) {
SherlockListFragment toDetach = // Find the right fragment
if (toDetach != null) {
transaction.detach(toDetach);
}
}
I'm populating the lists and the ActionBar menu in onResume:
#Override
public void onResume() {
super.onResume();
setHasOptionsMenu(true);
fillRemindersList();
}
I also tried it in onStart and onCreateView but it didn't help...
So what am I missing here?
And if there are others issues in my code that I'm unaware of, please do tell.
Thanks!
EDIT:
I just confirmed that onResume dosen't get called after I switch tabs, which is definetly wrong since I'm detaching and re-attaching them...
Am I switching tabs the wrong way?
Try using transaction.remove(fragment) in onTabUnselected and transaction.replace in onTabSelected.
Doing the beginTransaction() and commit() outside of this code I assume or did you forget?
You can see a trick used here from the samples as well:
https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabs.java