Right Approach to Call Web Service(API) from Fragment class - java

I need to know, In which fragment callback method, we should call a web service by which after come back to fragment web service should not call again.
For example.
I have a fragment class MyFragment.java
public class MyFragment extends Fragment {
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container,
false);
return rootView;
}
}
I need to know which callback method I have to call webservice to update the UI of fragment. Right Now I am calling web services from onCreateView method. but I need to know what should be best way to call web service from fragment.

If I understand your problem correctly, you want to fetch some data from the server and then inform the fragment that data is prepared and redraw the fragment, is that correct? According to the documentation here:
onCreate() -
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
onCreateView()
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.
When you create a Fragment somewhere else in your application, onCreate() method is called. When fragment has to be drawn for the first time, onCreateView() is called and this method returns a created View. In your case, you could probably go with something like:
Declare an instance variable (container) for this data and adapter (if you use any).
In onCreate, initialize all this data (empty container), initialize adapter and then execute the AsyncTask.
In onCreateView, prepare the view to return - adapter etc. So now, once AsyncTask will finish, in onPostExecute it calls your_adapter.notifyDataSetChanged(). This will redraw the fragment, since adapter will be informed that data has changed (fetched from the server).

Depends on when you want to fetch the data.
Do you want it every time the app comes to the foreground?
Use onResume()
Do you want it only when the app starts for the first time?
Use onViewCreated(), which gets called after onCreateView is finished.

onCreate() is tricky.
Put everything that you want to call just once in onCreate() method.
For example your API call, list, adapter initialization.
So ideally I would do like this
public void onCreate(Bundle sis) {
getImagesFromServer(); // API Call
initialzeLists()
initializeAdapters()
}
public View onCreateView(LayoutInflater i, ViewGroup c,Bundle sis) {
recyclerView = findViewById()
setUpAdapters()
return rootView;
}
TRICKY PART
But if you really want onCreate() to be called once then reuse Fragment. (Don't create a new instance every time).
How to reuse a Fragment?
While Adding for first time use add it to backStack with a KEY like this
currentFragment = FirstFragment.getInstance();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, currentFragment, "FIRST_KEY")
.addToBackStack("FIRST_KEY")
.commit();
And when you want to add it again get the old instance with the KEY like this
currentFragment = getSupportFragmentManager().findFragmentByTag("FIRST_KEY");
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, currentFragment, "FIRST_KEY")
.addToBackStack("FIRST_KEY")
.commit();
Demo project:
Here is the link to a demo project which loads a list of images using the Volley library. It has a similar implementation.
Woof - Use fragments the right way

Related

I am trying to initialize admob ads in Fragment of a Android App

I am trying to initialize admob ads in Fragment of Android App Is this the right way to do it
#Override public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); MobileAds.initialize(getActivity()); }
and do we need to initialize in every Fragment or whether one is enough?
Tried in one fragement
It is preferred to initialize when the App starts (In Splash Screen Activity)
You need to initialize the AdMob one time only not in every Activity or Fragment (After this just load and show the Ads)
If you want it to initialize in Fragment I'll suggest you use
requireActivity() instead of getActivity() method

How to Implement multi category using tabs in an RSS feed app?

I Want to implement multi category in rss feed app, i created a method Downloader which works properly in mainactivity.
But Downloader Method not works in tab fragments.
Here is screenshot of my project and Downloader method.
click here for project screenshot
When i implement downloader method in fragment, it shows an error.
context c is not resolve here
here is code
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tab1, container, false);
recyclerview = view.findViewById(R.id.rv);
recyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
new Downloader(c,urlAddress,recyclerview).execute();
return view;
}
comment if you need any other information.
You defined in the signature of your class that the first parameter should be context. You try to pass an undefined variable called c in your code thats why c gets highlighted as error. To fix your code either define c or directly pass in an context into the constructor.
You can get the context by calling getContext()and it should work:
new Downloader(getContext(), urlAddress, recyclerview).execute();

Confused, where is onCreateView method in MainActivity?

i followed online tutorial on how to create android app.
i want to assign variable in onCreateView, but where is the method?
im using androidstudio latest btw.
please help
For an Activity the sort of equivalent method is onCreate(). You can override onCreateView() in a Fragment.
onCreateView is the method of a Fragment, rathen than an Activity.
As shown in the documentation:
onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
Confused, where is onCreateView method in MainActivity?
Nowhere. Activity does not have this method (it's Fragment's). Use onCreate() instead.
create methods in activity is
protected void onCreate(Bundle savedInstanceState) {}
create method in Fragment is
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

Parse with fragments

I am receiving the following two related errors in eclipse:
1) The method getIntent() is undefined for the type Fragment1
2) The method setDefaultPushCallback(Context, Class<? extends Activity>) in the type PushService is not applicable for the arguments (FragmentActivity, Class<Fragment1>)
Below is the portion of the code where the errors takes place:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1_layout, container,
false);
ParseAnalytics.trackAppOpened(getIntent());
// inform the Parse Cloud that it is ready for notifications
PushService.setDefaultPushCallback(getActivity(), Fragment1.class);
If you need any clarification, let me know.
1)You cannot call getIntent() inside a Fragment as it's not an Activity and so one does not inherit Activity's methods/ You should try using getActivity().getIntent() if you are really sure that this is what you are looking for.
2)This method asks you for a Context and you are passing it an Activity, and then asks you for a class that extends an activity and you are passing it a fragment. For the first argument i would call getActivity().getApplicationContext() and as a second argument getActivity().
Edit: Try casting the getActivity() like: (Activity) getActivity()
ParseAnalytics.trackAppOpened(((Activity)getActivity()).getIntent());
// inform the Parse Cloud that it is ready for notifications
PushService.setDefaultPushCallback(((Activity)getActivity()).getApplicationContext(), ((Activity)getAcitivty()));
The two problems occur because you passed wrong parameters to them. Changes as following should help you get ride of them:
ParseAnalytics.trackAppOpened(getAcitivty().getIntent());
// inform the Parse Cloud that it is ready for notifications
PushService.setDefaultPushCallback(getActivity(), getActivity());
But, whether this is what you want or not still depends on the needs of that two function.

Is it possible to save Stack<Stack<View>> in onSaveInstanceState

Is it possible to save Stack<Stack<View>> in onSaveInstanceState.
May some another way how to save some specific data to manage Activity state?
You can't save views to bundle. And you shouldn't do it anyway. If activity is recreated it will reinflate layout again (or even inflate another one if configuration has changed) and create a new view hierarchy.
You should separate business data from your UI and store it onSaveInstanceState. After activity recreation you should get that data and update new views hierarchy accordingly.
For example, if you have a TextView, that displays some text that is stored in a field mSuperText, and your activity is going down, you should save it into a bundle in onSaveInstanceState:
#Override
protected void onSaveInstanceState(final Bundle outState) {
outState.putString("supertext", mSuperText);
}
And when your activity is recreated, in your method onCreate you get an argument onCreate(final Bundle savedInstanceState) which will be the bundle you stored previously. So you can get values you need:
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mSuperText = savedInstanceState.getString("superText");
}
}
Is it possible to save Stack> in onSaveInstanceState.
No, because Stack and View doesn't have the Parcelable / Serializable interface, which is necessary to put an Object in a Bundle. A Bundle only takes Arrays/ArrayList, String, primitives and so on.
May some another way how to save some specific data to manage Activity
state?
Which data you wanna save? If you wanna save a whole View/ViewGroup you are probably on the wrong way.
E.g to indicate that a TextView was visible set a boolean to true and put it in the Bundle. Check the boolean in onCreate() and set the View to visible. If the TextView had some text too, save it as String and set the text to the TextView, which you made visible.

Categories

Resources