Editing Fragment UI items with AsynTask - java

I'm working on an Android application that finds the computers on local network. It using AsynTask in background to discover that devices, i'm also using fragment pages to show results. The problem is i'm not able to make AsyncTask to edit fragment items. How can i handle it

you can use interface for interaction between AsyncTask and your fragment:
interface TaskListener {
void onTaskComplete(Data data);
}
implement fragment ... TaskListener
class YourFragment implements TaskListener {
// your fragment code is here
#Override
public void onTaskComplete(Data data) {
//this method will call from AsyncTask
//update your fragment ui here
}
}
assign the TaskListener to the AsyncTask in Constructor
public AsycTask(TaskListener listener) {
this.listener = listener;
}
call the onTaskComplete in "onPostExecute" method of AsyncTask:
#Override
protected void onPostExecute(Data data) {
listener.onTaskComplete(data);
}

Only the activity which created the fragment can access the fragment. Create a function in the activity which changes the elements in the fragment. Then call that function from the AsyncTask and pass along any information the fragment will need in the parameters of the function.

Related

FragmentManager has not been attached to a host [duplicate]

I have an Actvivity with a ListView, I set an adapter
MyAdapter extends BaseAdapter
that adapter has a callback interface
OnPdfClickedListener callback;
public interface OnPdfClickedListener {
public void onPdfClicked();
}
and in the Activity
MyActvivity implements MyAdapter.OnPdfClickedListener
and
#Override
public void onPdfClicked() {
Log.d("TEST", "PDF CLICKED in ACTVIIVTY");
}
This is pretty much the same as described here, which works like charm for fragments.
When trying the same from the adapter the callback object is null.
I also tried instantiating like
OnPdfClickedListener callback = new OnPdfClickedListener() {
#Override
public void onPdfClicked() {
// TODO Auto-generated method stub
}
};
I have no errors then but the respective method in the Activity is never called.
My question is 1. why isn't the callback object null when used in a fragment, it's never instantiated
and 2. how can I callback to an Activity from an adapter?
why isn't the callback object null when used in a fragment, it's never instantiated
Your Activity most likely isn't registered as a listener, with the callback variable you created(which has nothing to do with the Activity) an instance of OnPdfClickedListener and (probably) used that when the event happened.
how can I callback to an Activity from an adapter?
Pass a reference to the Activity to your MyAdapter class, cast it to OnPdfClickedListener and use that to call onPdfClicked instead of the current callback variable.
Try adding this:
In your Activity which implements the interface:
new MyAdapter(this,....);
In your Adapter:
MyAdapter(Context context, ...){
callback = (OnPdfClickedListener)context;
}

Use Asynctask for multiple Fragments

I have 2x fragment java classes, which needs to use the same asynctask. Are there anyway i can do this, or do i have to copy/paste the same asynctask in both fragment classes? i have these 3 java classes in total:
MainActivity
dataTabelFragment
sensorOverviewFragment
The asynctask is fetching data from json URL.
Maybe it's possible to make another java class for the asynctask?
All help is appreciated!
What you say suggest you should decouple your async task code from both fragments and instead have separate worker (perhaps IntenstService would server you well here instead) that you fragments would call to have the job done. Or, depending on your code structure (you should think of this if you haven't yet :) maybe your async task code should be part of you fragments' base class that both of them would then extend.
I guess your fragments are in same Activity (MainActivity), so you can put your AsyncTask in your MainActivity.class and your fragments can communicate with your Activity with listener. Something like this:
public class YourFragment extends Fragment{
private YourListener mListener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (YourListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement YourFragment");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
interface OnSearchFilterListener {
void onItemClick(int position);
}
}

How do you programmatically set ViewPager tabs from inside a fragment?

I have a database that provides an array of Strings, accessed from within a Fragment. I want these Strings to go back to the activity attached to the Fragment and set the titles of the tabs in a ViewPager. How can I do this?
This is how I want to do it:
Database String[] → Fragment → Attached activity's ViewPager → New
tabs
Edit: Here is my entire Activity and PagerAdapter code.
Here is my Fragment code
Suppose you have array of Strings and you want to send them to your activity from Fragment, make an interface like
public class MyFragment extends Fragment {
CustomStrings mCallback;
// Container Activity must implement this interface
public interface CustomStrings {
public void onStringRecieved(String[] stringss);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (CustomStrings) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
And then simple use this when you need to send data
mCallback.onStringRecieved(yourStrings); //your data here
And then in your activity implement it
public class MainActivity extends Activity
implements MyFragment.CustomStrings{
...
public void onStringRecieved(String[] stringss) {
// Do something here to use these strings
Toast.makeText(getContext(), ""+strings, Toast.LENGTH_SHORT).show();
}
Hope this solves your problem, for more information refer this

Communication between Fragments without Using Interface

I was trying to communicate between two fragments, but I'm just a beginner so I want to know if there is any solution not using interface....
If there are Fragment A, B, and their Activity:
Sending values from Fragment A to Activity
(In here, Fragment A is a current state)
Sending values from Activity to Fragment B
I know direct communication between two fragments is almost impossible,
but I don't think that makes me to use an interface.
Also, is there any method to use like putExtra() for fragment? I only know using Serializable.
Have a look at the Android deverlopers page: http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface
Basically, you define an interface in your Fragment A, and let your Activity implement that Interface. Now you can call the interface method in your Fragment, and your Activity will receive the event. Now in your activity, you can call your second Fragment to update the textview with the received value
// You Activity implements your interface
public class YourActivity implements FragmentA.TextClicked{
#Override
public void sendText(String text){
// Get Fragment B
FraB frag = (FragB)
getSupportFragmentManager().findFragmentById(R.id.fragment_b);
frag.updateText(text);
}
}
// Fragment A defines an Interface, and calls the method when needed
public class FragA extends Fragment{
TextClicked mCallback;
public interface TextClicked{
public void sendText(String text);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (TextClicked) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement TextClicked");
}
}
public void someMethod(){
mCallback.sendText("YOUR TEXT");
}
#Override
public void onDetach() {
mCallback = null; // => avoid leaking, thanks #Deepscorn
super.onDetach();
}
}
// Fragment B has a public method to do something with the text
public class FragB extends Fragment{
public void updateText(String text){
// Here you have it
}
}
You can communicate between fragments directly by using EventBus - send ordinary or sticky events by one fragment and subscribe to that event in another one.
If don't want message to be lost, use sticky events - it work as sticky Intent in Android. It will be around until it is removed by targer fragment or because another event is pending.
Yes you can transfer data between fragments using bundle like you do in Activity using putExtra
Bundle = bundle = new Bundle();
bundle.putString("key","value");
bundle.putSerializable("serialzedKey",SerializedValue);
FragmentTransaction fts = ((BaseActivity) mContext).getSupportFragmentManager().beginTransaction();
fragment.setArguments(bundle);
fts.add(R.id.fragmentHolder, fragment);
fts.addToBackStack(fragment.getClass().getSimpleName());
fts.commit();
In other fragment you can retrieve data using getArguments()
String key = getArguments().getString("key");
SerializedModel = getArguments().getSerializable("serialzedKey");
you can call a method from the parent activity class that calls a method from fragment B like ((YourActivity)getActivity()).callMethod(T yourData)
Take a look at my Github repo on using interfaces to communicate between fragments.
This is just a really simple example but displays the key concepts.
https://github.com/stoddayy/FragmentInteractionExample

Fragment communicating with an Activity

I am confused about how communication with a Fragment and an Activity is made. For example, an interface was defined here (https://developer.android.com/training/basics/fragments/communicating.html).
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
...
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// The user clicked on a list item.
mCallback.onArticleSelected(position);
}
}
Eventually, the following method is called from the MainActivity.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// Do something
}
}
My questions are:
How does mCallback "know" which onArticleSelected method to call (as there might be other classes that have implemented OnHeadlineSelectedListener).
mCallback.onArticleSelected(position);
I wouldn't be confused if it went:
mCallback = new OnHeadSelectedListener() {
#Override
public void onArticleSelected(int position)
// Do something
}
and then mCallback is referred in some way in MainActivity to utilize the onArticleSelected method in some way. In the example code, however, the line intelligently sticks to "an" interface. How does that happen?
Also, I found that the Log I implemented onArticleSelected method from MainActivity is called previously to the one in onListItemClick method in HeadlineFragment. Is it expected?
Since you defined the OnHeadlineSelectedListener interface with only one method, and your activity implements it, there's no ambiguity in choosing the method when you use the activity as instance of this interface, 'cause all you know about activity while using it as instance of OnHeadlineSelectedListener interface is a presence of onArticleSelected(int) method in it.
It depends on when you call the logging function - before or after calling the callback method.
P.S. While this kind of communication between Activity and Fragment (or any other objects) is perfectly fine, personally I prefer the Event Bus approach, 'cause it gives us a possibility to organize code in a low coupled manner. Here are some nice implementations of Event Bus pattern:
https://github.com/greenrobot/EventBus
http://square.github.io/otto/
Take a look at them if you are interested in this approach.
Your mCallback is your activity, in the onAttach method of your fragment, you will set the activity as listener for your fragment. By this way, this is normal that the activity is notified when you call mCallback.onArticleSelected(position);
For your first part of question
You should have a look on onAttach and onDetach methods-
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement OnHeadlineSelectedListener.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
Second part-
The behavior is not expected.
You should not make your activity class static as well.

Categories

Resources