How to execute AsyncTask<> located in a fragment from its parent? - android

This seems harder than it look or I am doing it wrong. I need to update the content of UI elements in a fragment.
So, within an Activity, I start AsyncTask task like this
new MyAsyncTask().execute();
Inside "normal" Activity this async class is private so I thought that I could make it public inside the fragment class and then be able to call it from FragmentActivity parent class. Something like this:
MyFragment myFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.layout.my_fragment);
new myFragment.DoParsingAsyncTask().execute(""); //??? a silly guess
This did not work.
Can anyone help?
PS. My fragments are not <fragment> views in XML, but I deal with them via ViewPager. I have no problem displaying pages via ViewPager.
PPS. this async class starts parsing remote content and fill UI elements in the fragment.

It might not solve the problem, but create a method in your fragment and call that to create and start the async task. It will just be tidier. Here is the code.
From Fragment call the method like this.
Activity myActivity = getActivity();
if (myActivity instanceof MyActivity) {
((MyActivity) myActivity).doAsyncTaskMethod();
}
Or you can try the solution I've already proposed.
MyFragment myFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.layout.my_fragment);
myFragment.new DoParsingAsyncTask().execute("");
Which works as well.

Related

How do I get a reference to a headless fragment?

I have a headless fragment to retain my data during config changes.
rFrag = new RetainedFragment();
getSupportFragmentManager()
.beginTransaction()
.add(rFrag, MODEL)
.commit();
What is the best way to access this fragment while inside of another activity or fragment besides the original activity that the headless fragment is attached to?
Using this doesn't work:
RetainedFragment rFrag = (RetainedFragment)getSupportFragmentManager
.findFragmentByTag(model);
I did a search and I believe this is because I don't have the retained fragment added onto the backstack, but adding a headless fragment onto the backstack isn't what I want to do.
Right now I just set the retained fragment to be public and static like this:
public static RetainedFragment rFrag;
But I feel like this isn't good practice to use static variables like that.
First of all, I don't know what you mean by "headless fragment".
Secondly, I don't know what RetainedFragment() class is but I will assume that it is just a class you created that extends Fragment.
Thirdly, you can't access a Fragment through other Activity. Every fragment is attached to one Activity and when that Activity is not visible its Fragments are not accessible.
Lastly, even if you force to access by using static methods and fields and such, you are right, it is not a good practice. You can, and should, use Intent extras and Fragment arguments to pass data from one to another. You mentioned you need to retain some data, so you actually don't really need the whole Fragment, right? You can just save, load and pass around the data you need.

A fragment and 2 activity that use the fragment

I am new at developing Android App.I am try to use a dynamic fragment which is used 2 activity like (show detail activity and edit details activity).How can I understand the fragment is used by which activity in onActivityCreated() method on MyFragment class. How can I handle this issue please help me thanks in advance
Try this in your Fragment onActivityCreated() method
FragmentActivity activity = getActivity();
if(activity instanceof show detail activity){
// Your ShowDetailsActivity
}else if(activity instanceof edit details activity){
// Your EditDetailsActivity
}
Jagadesh's solution will work, but fragments should operate independent of the activity.
You might want to consider adding a static method like "getInstance" that will accept parameters and return an appropriate instance of the fragment if some functionality shoudl be custom for the calling activity.
If you want to call the activity back, then you might think about having the activities register a callback or listener that the fragment can invoke.

Simple way to replace and send data to a fragment

I simply want to replace a fragment from the current fragment and add a new one.
I have studied that Replace is Equal to removeCurrent + Add anotherFragment
But in my situation i am facing a Problem. For the first two times it is running properly but after third attempt instead of replacing . it ads the fragment on me.
My approach fails now. Now i am asking that how can i send an id to other fragment like we do in Activities. I have a listView with a ReadMore button. I simply want to show the details in another fragment and want to send the index of a List.
I listen about some Interface but don't know how to implement . or there an easy way for communication. I tried doing it by passing it in Constructor . but it will give me an error . because
how to get currentFragment and hide it?
how to add onBackPressed to fragment.
how to send data between fragments The easy way.
i know how to hide or show a fragment
getFragmentManager().beginTransaction().hide(frag[j]).commit();
getFragmentManager().beginTransaction().show(frag[0]).commit();
also know how to add or replace a fragment
getFragmentManager().beginTransaction().add(R.id.container, frag[i])
//.addToBackStack(null)
.commit();
getFragmentManager().beginTransaction().replace(R.id.container, frag[i])
//.addToBackStack(null)
.commit();
Tell me a better approach to send data and why my layout add instead of replacing.
I recommend using EventBus for Activity/Fragment/Service or any other communication.
There is a good one from Square: http://square.github.io/otto/
Or this one (also very good): https://github.com/greenrobot/EventBus
It makes it simplier and your code gets cleaner.
It is pretty easy to send data to fragment with constructor.
In your fragment class, add constructor like this:
public class MyFragment extends Fragment{
String id;
public MyFragment(String id)
this.id = id;
}
Then, when calling a fragment,you can easily send data like this :
getSupportFragmentManager().beginTransaction().replace(android.r.id.container,new MyFragment("123")).commit();
You can't override onBackPressed within fragment, you can only do that in activity
You can set try set the variables in the fragment as public static then you can declare them before you instantiate your fragment to be shown.
in your onDestroy method of the fragment you can set the variables = null, so they dont take space in memory.
could be smth like this
MyFragment.theString = "A String";
getSupportFragmentManager().beginTransaction().replace(android.r.id.container,new MyFragment()).commit();
And in your fragment
public static String theString;
...
public void onDestroy(){
super.onDestroy();
theString = null;
}

Can I add a fragment to a FragmentActivity outside of whats in the viewpager?

I'm new to fragments. I have an activity that extneds FragmentActivity and uses the ViewPager to swipe between fragments.
Within one of the fragments I want to launch a new fragment that is "outside" of whats in the view pager. Is it possible to add a fragment like this or do I need to start a new activity with the fragment.
Now I have it launch a new activity but it is very slow.
Activity A
Fragment A
Fragment B
Fragment C
Activity B
Fragment D
Fragment A
So fragment A can launch acitvity B to get to fragment D but ideally it would be cool if I could just inject fragment D in Activity A
Hope that makes sense.
Yes, you can, but I strongly suggest you avoid it, unless you have a good reason to do so.
The ViewPager is (I assume) hosted in your Activity. The ViewPager obtains its views from its adapter. (A FragmentStateAdapter or similar). So you could tell the activity to change its layout (and or hide the Viewpager and show another FrameLayout) or you can simply launch another Activity that contains a single fragment. This is also fine.
Messing with the ViewPager/Adapter is usually complicated and you may waste time trying to make it work.
On the other hand, you could add the Fragment to the ViewPager's Adapter and use the getType of the adapter to return a different type of Fragment.
So you could do (pseudo code):
mPagerAdapter.addFragmentDToTheDataAtPositionZero(); //longFancyName ;)
mPagerAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(0, false);
that'd add Fragment D to the "top" of the viewpager and will switch to it.
Your Adapter then has to use an Interface to determine what type of fragment must be instantiated…
The getItem of the adapter would look like… (again, pseudocode)
#Override
public Fragment getItem(final int i) {
final FragmentTypeInterface f = yourData.get(i);
if (f.isD()) {
return FragmentD.newInstance();
} else {
return OtherFragment.newInstance();
}
}
And so forth… :)

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.

Categories

Resources