Ok here is the issue, the native Android Fragment is deprecated.
This will be use in an Unity Android native plugin.
In the old ways you simply create a Fragment class like this:
public class UnityAndroidNativeplugin extends Fragment
{
public static void Init()
{
instance = new UnityAndroidNativePlugin
UnityPlayer.currentActivity.
getFragmentManager().
beginTransaction().add(instance, UnityAndroidNativeplugin.LOG_TAG).commit();
}
}
That works fine but I still don't get, if this is deprecated we should use the support fragment library. Ok I will update this.
So when I change to the new version it should be something like this.
public class UnityAndroidNativeplugin extends android.support.v4.app.Fragment
{
public static void Init()
{
instance = new UnityAndroidNativePlugin
FragmentManager fragMan = UnityPlayer.currentActivity.getSupportFragmentManager();
//This Fails
}
}
I already know that my main Activity should be a FragmentActivity.
Cannot call getSupportFragmentManager() from activity Check here.
So it's not possible to use android.support.v4.app.FragmentManager while using Android Activity (android.app.Activity)?
One solution is to override the Unity Main activity but that could have problems when using other plugins. Or maybe using something else than a fragment.
So it's not possible to use android.support.v4.app.FragmentManager while using Android Activity (android.app.Activity)
Correct.
if this is deprecated we should use the support fragment library
Or, better yet, the AndroidX one, as the Support Library one will become obsolete before long.
Related
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
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.
This may be rather obvious, but I cannot get it.
I am trying to use the suggested way of creating dialogs, by extending DialogFragment. Now, the problem is, I don't know how to invoke it. Documentation states:
DialogFragment newFragment = new FireMissilesDialogFragment();
newFragment.show(getSupportFragmentManager(), "missiles");
but my Activity does not extend FragmentActivity (and due to the design of my application, it cannot extend it), so getSupportFragmentManager() cannot be invoked.
Any workaround for this?
I would like to skip the deprecated way of creating a dialog.
The answer is no.
The FragmentActivity (and it's variants) are the ones that support the FragmentManager and the Fragments.
Common solutions to what you might believe "and due to the design of my application, it cannot extend it"
If you're using a ListActivity, just put a list in your layout.
If you're using a MapActivity, switch to the new map API.
If you're using a TabActivity, that's deprecated, you should use Fragments.
For example you can create a class that extend DialogFragment and invoke it like this:
_dialogFiltre = FragmentDialog.newInstance(R.string.tle_dialog_filter, this);
_dialogFiltre.setValidDialogListener(this);
_dialogFiltre.setCancelable(false);
_dialogFiltre.show(getSupportFragmentManager(), null);
The method new instance :
public static DialogFilter newInstance(int title, Context context) {
FragmentDialog dialog = new FragmentDialog();
Bundle args = new Bundle();
args.putInt("title", title);
dialog.setArguments(args);
dialog._context = context;
return dialog;
}
If you are not in a FragmentActivity i don't see any solution. Why does your application design does not let you use FragmentActivity ?
well you can directly invoke getSupportFragmentManager(); on FragmentActivity but not on Fragment itself. So to invoke getSupportFragmentManager(); what you can do is first get FragmentActivity and on that call getSupportFragmentManager();. So as you're getting FragmentActivity, you can call this function like:
getActivity().getSupportFragmentManager();
here getActivity() returns FragmentActivity associated with your Fragment.
what you have done is
1. First you have created instance of your custom DialogFragment class.
2. you're showing that dialog.
Now as you've already created an instance of custom DialogFragment why not use that to retrieve support for fragment manager. So what you can do is:
DialogFragment newFragment = new FireMissilesDialogFragment();
newFragment.show(newFragment.getActivity().getSupportFragmentManager(), "missiles");
what this will do is you're getting FragmentActivity associated with newFragment and on that FragmentActivity you're calling getSupportFragmentManager();.
Unfortunately I have not tested it but this might work. Try it and let us know.
I'm trying to bring up a DialogFragment when I tap a Preference in a PreferenceFragment. Unfortunately, when I call getFragmentManager() in DialogFragment.show() I receive the following error:
Cannot resolve method 'show(android.app.FragmentManager, java.lang.String)'
The problem is that I can't seem to refernece android.support.v4.app.FragmentManager from this fragment. The activity in charge of this fragment extends from FragmentActivity, but obviously that's not enough. I tried calling getSupportFragmentManager() as well, but that gave me this error:
Cannot resolve method 'getSupportFragmentManager()'
How can I make this work?
Here's some code:
gPrefAcknowledgements.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener()
{
#Override
public boolean onPreferenceClick(Preference preference)
{
DialogAcknowledgements dialogAck = new DialogAcknowledgements();
dialogAck.show(getFragmentManager(), "acknowledgements");
return true;
}
});
Building on Steve's answer, I also need to set up the DialogFragment to import from android.app.DialogFragment (instead of android.support.v4.app.DialogFragment). The show() function in that library asks for an android.app.FragmentManager, which I can provide via a call to getFragmentManager() as I did within the code I posted in the question.
Try this:
dialogAck.show(getActivity().getFragmentManager(), "acknowledgements");
You can always call the Activity which holds the Fragment equal of which type it is.
EDIT:
I was wrong, the PreferenceFragment isn't included in the Support Library and is only available in Android 3.0 and higher. This post could help to deal with this scenario.
I need to create a free and paid version of the app and therefore I am using a library project with the common activities and resources in. However I was wondering how you would go about organising this:
A shared (library) activity MyActivity.java launches a DialogFragment when a user clicks a buttons. The DialogFragment will be different for the free and paid apps. For the free app we will launch FreeDialog.java and for paid we will launch PaidDialog.java. These two dialog fragments will not be in the library project as they are not shared; they will be in the free and paid projects separately.
The only thing I can think is to make MyActivity.java abstract and to extend it in the free and paid projects. The extensions will launch their respective DialogFragments.
Another way could be to overload the Fragments in each of the projects. However, I am not sure if this is possible.
Theoretically, you could make MyActivity abstract, and subclass it in both paid and free app projects. But, Activity classes are a little different than normal Java classes, which complicates this. They are listed in AndroidManifest.xml, and then also are not created by simply newing them up. They're normally created with Intents. So, I think I would stay away from making the Activity an abstract class.
I think what you really want is to use is something like the Factory pattern to create an instance of DialogFragment, where your common library does not know which DialogFragment will be created. You can get pretty fancy with a factory, and you can read all about that elsewhere, but a simple one might work for you:
public class FragmentFactory {
private static String _dialogFragmentClassName;
public static void registerFragment(String className) {
// you might choose to assert if _dialogFragmentClassName != null
_dialogFragmentClassName = className;
}
public static DialogFragment createFragment() {
try {
return (DialogFragment) Class.forName(_dialogFragmentClassName).newInstance();
} catch (Exception e) {
return null;
}
}
}
Then, in your free and paid app project code, you would issue calls like this at startup (e.g. in a main Activity):
FragmentFactory.registerFragment(com.mycompany.free.FreeDialogFragment.class.getName());
and
FragmentFactory.registerFragment(com.mycompany.paid.PaidDialogFragment.class.getName());
Finally, in the common library code, you can create an instance of the fragment by calling
DialogFragment fragment = FragmentFactory.createFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_content, fragment);
ft.commit();