1

I wonder which one of the following two approaches is the best way to load a fragment with the data coming from a web service. Here is the scenario: In Fragment 1, when a button is clicked, Fragment 2 comes to screen and the views in Fragment 2 are filled with the data coming from a web server.

1st approach: Make a request to web service as soon as button is clicked at Fragment 1, keep the data coming from the service, and then pass this data to Fragment 2:

public void onClick() //Fragment 1
{
    makeRequest();
}

public void handleResponse(Response response){ //Fragment 1
    ServiceData data = (ServiceData) response;
    Fragment2 fragment2 = new Fragment2(data);
    FragmentManager fm = getSupportFragmentManager();
    fm.beginTransaction.replace(R.id.container, fragment2).commit();
}

//and 
protected void onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) //Fragment 2
{
    View v = inflater.inflate(R.layout.fragment_2_layout . . . );
    Button b = (Button) v.findViewById(. . . );
    b.setText(data.getButtonText);

    . . . 

    return v;
}

2nd approach: When button is clicked in Fragment 1, do not make a request, just start Fragment 2, then at the end of onCreateView of Fragment 2, make a request and then fill the views with data coming from service.

public void onClick() //Fragment 1
{
    FragmentManager fm = getSupportFragmentManager();
    fm.beginTransaction.replace(R.id.container, fragment2).commit();
}

protected void onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) //Fragment 2
{
    View v = inflater.inflate(R.layout.fragment_2_layout . . . );
    Button b = (Button) v.findViewById(. . . );
    . . . 

   makeRequest();
   return v;
}

public void handleResponse(Response response){  //Fragment 2
    ServiceData data = (ServiceData) response;
    b.setText(response.buttonText);
    . . . 
}

My concern with 2nd approach: Suppose service request fails, in this case views were created but not filled with data(i.e. button text is not set, imageviews's images are not loaded etc.). is that acceptable?

My concern with 1st approach: Why make a request in Fragment 1 whose data is related to Fragment 2?

So, i wonder which one of these 2 options is the best, or is there any other better way to do this?

Thanks

yrazlik
  • 10,411
  • 33
  • 99
  • 165

2 Answers2

1
public class Fragment2{

   static void loadMeIfData(Activity activity, int fragContanierId){

   //1. get data
   //2. if(data!= null) activity.getFragmentManger(), and add an instance of me.
  }
}

Advantage: method for getting data for fragment 2, kept in Fragment 2 class. If you put in Fragment 1, your code is going to be messy / non modular.

NameSpace
  • 10,009
  • 3
  • 39
  • 40
  • Do you suggest making loadMeIfData function to be public static and call it from fragment 1? In this case i may not be able to reference non-static objects in that function and may need to make every object static – yrazlik Nov 08 '14 at 13:41
  • Also cannot call getActivity() method, and may need to create a static context object, and this may cause a memory leak? – yrazlik Nov 08 '14 at 13:42
  • 1
    That's why activity is a parameter of the function, so you already have it. If you're calling this from fragment 1, you just call loadMeIfData(getActivity(), R.id.fragCongainerMain). If you have other objects you need, pass them as parameters as well, just like activity. If you have a ton of objects, pass an interface or class for retrieving them. The static function has as much available to it as a naked fragment 2 would, so assuming that was an option for you, it shouldn't be any harder to write. – NameSpace Nov 08 '14 at 13:52
  • btw where are the objects you need? On fragment 1, your activity, somewhere else? – NameSpace Nov 08 '14 at 13:59
  • oh i did not realize the activity parameter. That is a good approach thanks for the advise. – yrazlik Nov 08 '14 at 14:11
  • this is not good approach to pass Activity instance to fragment, better way is communicate with interface and implement that on Activity, for more info see http://stackoverflow.com/questions/12659747/call-an-activity-method-from-a-fragment. – Shayan Pourvatan Nov 08 '14 at 14:28
  • The accepted answer there didn't use an interface. Second, he's using it to get a fragment manager, no interface is required for that -- it's already built into activity. Third, he's not passing this to the fragment, but the function that determines whether to create the fragment. Finally, I mentioned the interface option if he needs non-inherent functionality. – NameSpace Nov 08 '14 at 14:38
0

I prefer approach 1, The fragment 2 is useless without data, so wait for the data in fragment 1 and when you have the data show fragment 2.

Because if you goes with approach 2, and if the data is not available then you will show the error in fragment 2, after that what will be the action by the user? are you going to try again? what if user wants to go back to parent screen (may be because his network is down)?

So the bottom line among the 2 approaches, approach 1 is better. On the other hand it is also possible that Activity makes a call to the service rather then the fragment. You can achieve this using callback interface. Then Activity will show Fragment 2, or the error dialog.

Ahmed
  • 636
  • 1
  • 14
  • 31