Fragment Transaction not working when using AppCompatActivity or FragmentActivity - android

I have a typical application. An activity which has a FrameLayout and in this layout I want to switch between fragments. This is typically and easily done with:
getFragmentManager().beginTransaction()
.replace(R.id.ac_container, new FrOverview())
.addToBackStack(null)
.commit();
The problem is, that even if I use .addToBackStack(null) (And I know it's been added 'cause the stack count increases) when I press back I exit the application. I have been trying a lot of different code stuff and checked most threads here on Stackoverflow but I can't get it to work with code (method calls etc.).
But! I can get it to work, by changing the extended class of my activity class. If my class extends Activity, it works fine. But if I use AppCompatActivity (which in turn extends FragmentActivity) then it has the bad behaviour as explained earlier.
Feels like this has to be an error on Androids part, I am not doing anything wrong to my knowledge.
Does anyone have any suggestions on how to solve this? i.e. get the back functionality and keep the ActionBar!

AppCompatActivity uses the SupportFragmentManager, you need
to switch to SupportFragment and SupportFragmentManager

Related

Android viewpager in fragment

Dear ladies and gents,
First of all, please do not mark my question down. If you think that my question is too stupid please let me know and i will edit it or remove.
So my actual question is that I have an activity (extends Activity). In that activity's layout I created FrameLayout where I then attach different four fragments(so each of them extends Fragment. So in one of that fragments I would like to implements swipeable tabs(see screenshot).
I know that it is usually done by implementing viewPager and FragmentPagerAdapter, but I can not do this as if I'm calling getSupportFragmentManager in my fragment it gives my an error. If i am using getActivity().getFragmentManager() it gives me error that android.support.v4.app.fragmentmanager cannot be applied to android.app.fragmentmanager. I have to use android.support.v4.app.fragment in my fragment, because otherwise I will not be able to implement my activity's view(described at the beggining).
Any ideas or suggestions would be very appreciated.screenshot
Make sure you are using Fragment class that you extends your fragments comes from support library. You also need to use FragmentActivity to call method getSupportFragmentManager();
On the other hand, viewpager which is in your fragment need to implemented as usual that you can find on internet except getChildSupportFragmentManager();
This one called "nested fragments".
PS: I am not sure but you can also use AppCompatActivity instead of FragmentActivity. FragmentActivity and ActionBarActivity must be deprecated.
Good luck
You can use getChildFragmentManager() when using Fragments inside other Fragments.
New version of Support Library v4 (Android 4.2) resolve this problem. For do this, simply do constructor of your custom FragmentPagerAdapter like this:
public CustomFragmentPagerAdapter(android.support.v4.app.Fragment fragment)
{
super(fragment.getChildFragmentManager());
// write your code here
}
This work because new Android version approve using nested Fragments

How to use both Android.App.Fragment and Support V4 library

I want to use a Support library to add a new L-styled ActionBar to my app. So I changed my activity to an ActionBarActivity. Now I have both getFragmentManager() and getSupportFragmentManager().
I use getFragmentManager() to work with fragments and they are rendered OK.
But there is a problem when I add transaction to backstack ((mTransaction.addToBackStack("blabla"))). Backstack remains empty so if I call mTransaction.commit() and right after getFragmentManager().getBackStackEntryCount() latter will return 0 no matter how many transaction I commit. As a result my app will be closed at first "bacK" press without navigation to previous fragment.
Why I don't use Fragments from Support Library?
App is targeted to API 15 and newer so I don't care about <11 and there is lot of code to migrate. Also if use Support Library i won't be able to use objectAnimator for transition. It isn't disaster, but I just don't want to degrade one part of app to improve another.
So the question - is it possible to fix back stack or i should migrate all fragment-related code to support-v4?
EDIT: I was posting too fast before reading your question carefully.
I've looked through the source code of FragmentActivity and Activity and I highly recommend to use getSupportFragmentManager() if using ActionBarActivity.
The reason is that the FragmentManager implementation mFragments is shadowed in FragmentActivity and is used all over the activity life cycle. If using getFragmentManager() the super classes implementation will be accessed. And you will have to rely on FragmentActivity to make the super calls at appropriate times, else the life cycle might get messed up. With onBackPressed() you've already discovered a case where FragmentActivity fails to call super.
Another solution would be to migrate to Toolbar. But you'd loose some of the goodies of ActionBarActivity e.g. widget-tinting and ChildFragmentManager.
I'd just stick with the support implementation.
This is the original answer and doesn't really apply here:
Committing a fragment transaction, does not immediately add/replace your fragment. Therefore your back stack will still be empty. You can call getFragmentManager().executePendingTransactions() if this is really necessary.
Btw: Why would using the support library prevent you from using ObjectAnimator ?
OK, after few more test I found that actually back stack is filled but it is not handled by activity.
Adding following code solved my problem but i'd like to keep this question open since I still don't know why it isn't handled by ActionBarACtivity internally as it is done in Activity
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}

Illegalstateexception activity has been destroyed fragmenttransaction.commit()

I have seen a few versions of this question before, but the reasons for this exception were different than my own it seems.
What I am trying to do:
-Main Activity class has a toolbar at the bottom, clicking the buttons will display a series of fragments, one after another.
- A class EditItemFragmentManager, which is instatiated on a button click, and has methods that display specific fragments based on the toolbar button clicked.
I would like to use this manager class I created because it cleans my code up significantly and will make adding more features later helpful.
Here is my EditItemFragmentManager class, I am not sure if extending Activity is a good idea or not, I think that it will put my MainActivity on pause
public class EditItemFragmentManager extends Activity{
//instance variables
public EditItemFragmentManager(){
// initialization of some variables
}
public void editItem(){
editItemSequence();
}
private void editItemSequence(){
EditNameFragment enf = new EditNameFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(editNameFragment, EDIT_FRAG_TAG);
fragmentTransaction.addToBackStack(EDIT_FRAG_TAG);
fragmentTransaction.commit();
}
}
So it blows up when commit(); is called, giving me
java.lang.IllegalStateException: Activity has been destroyed
This is how I am trying to get this fragment from my MainActivity,
#Override
public void onClick(View view) {
EditIteFragmetManager manager = new EditIteFragmetManager();
manager.editItem();
}
I am still learning about the Acvtivity lifecycle in Android. I think my problem is something due to this class extending Activity, which puts my Main on pause, and the FragmentTransaction has nothing to commit to? If so, I need to get the existing instance of my main activity and call it on that? This is where I'm a bit lost, if anyone who understands the lifecycle of Activities/Fragments explain how I could go about implementing this while still having a helper class such as this?
If you're using the SupportFragmentManager, then you need to extend from FragmentActivity, and not just Activity. Also make sure that you imported the Fragment from the v4 support library, and not android.app.
Other than that, you seem to be instantiating a subclass of Activity with "new", which is terrible. Create activities only using Intents.
I solved this issue by moving my manager class to become a private inner class of my main, since they are so tightly coupled. No fragment issues now.

Where to place application logic in new Activity code generated by ADT 22.6.2

In the latest versions of eclipse (ADT v22.6.2) the create android application now generates an activity_main.xml and a fragment_main.xml. It generates only a single activity class
but this now has an embedded inner static fragment class that is created by the activity in its onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
....
public static class PlaceholderFragment extends Fragment
My confusion is how to port old code/examples where there was only 1 activity and the main application
logic is usually put in the Activity onCreate method i.e. stuff like findViewById. Listeners
etc
The way I have approached it is that I put all my user created views as members of the static PlaceHolderFragment class. Then I call this in the fragment onCreateView. I still have some logic in the activity and it stores a pointer to the fragment. It updates the views members by calling getters on the fragment. Is this correct or should all logic be moved to the fragment now ?
All the tutorials/examples use the old approach where logic is placed in the activity
so there is no reference documentation for how to use the new files that Eclipse generates for an Android application. Any help appreciated ?
Don't worry about the files that Eclipse generate automatically: You can do whatever that you want!!!
Fragment is a element between an Activity and a container.That's mean that you can put the logic of your code inside of one fragment with not problems.
In theory, fragments are used when you want to manage screens using different modules, containers. It's a fragment, a module, part of one screen (but also can be used in a full screen looking as an activity and with the same behaviour than one activity.) For example, imagine that you have for mobile phone screens, one list of news in one screen, and when you click, your app go to the next screen for show the content of the news, right? Ok, so you can use for these 2 screens: 2 activities for each one or one parent activity with 2 fragments...whatever that you want...
Imagine the same case, for a tablet version of your app, now the left part of the screen you should show the list of news and in the right part of the screen, the contain of each news clicked, right? In that case, would be completly necessary to use one activity parent with two fragments...in that case, we could reuse almost the same case for the mobile phones or tablet.
And now, focus in your question: if you don't want complicate the life (not too much, because work with fragment is easy too) I will recomend you to use only activities for your app.
But, like your question, you want to port, there isn't any problem. Now imagine that your activity is going to be only the class where you are going to manage the fragments. The logic for each screen has to be in each fragment. Use the activity only for replace fragments, or share information between fragments, etc. The activity will be like the orchestra director.
From each fragment, you can access to methods or public variables of your activity using ((NameOfActivity)getActivity()).
Is it clear for you?
One more stuff, in fragment, normally the method that we used for initialize stuffs is onCreateView (and not onCreate like activities).

Communication fragments/activities

In my existing app I am porting two activities to fragments. The case is the classic dual panel mode with a list on the left and the content on the right.
The doc says that I should avoid to manipulate fragments within fragments, passing instead through the host activity. Said that I am using callbacks to the activity.
The first doubt (maybe banal) I have is:
How to avoid to duplicate the same code in the activity that hosts the
2 fragments and into the activity that wraps the fragment when not in
dual mode?
I'll try to explain. So I have:
ListFragment and ListFragmentActivity
ContentFragment and ContentFragmentActivity
because both fragments can live independently from each other, then:
HostActivity
that implements a listener invoked from ListFragment for adding/replacing the ContentFragment
My question is: when ListFragment is instead hosted from ListFragmentActivity, how to avoid to duplicate the code present in the HostActivity into ListFragmentActivity.
Guess I am missing something, thanks in advance.
Get rid of ListFragmentActivity. Have HostActivity handle the case where there is either one or both fragments. Then, by definition, there is no code duplication. See: https://github.com/commonsguy/cw-omnibus/tree/master/LargeScreen/EU4You

Categories

Resources