Scene
I want to update the content of several fragments once I get the response from some HTTP requests.
My Idea
My implementation is something like this:
onCreate of activity, Bind ViewPagerAdapter to it. Then trigger the HTTP request to get data.
Once the request succeeds, update the content in Fragment.
Code
sendRequest. --> adapter.updateFragment(bundle) --> fragment.updateData(bundle);
Activity
protected void onCreate(Bundle savedInstanceState) {
Log.d("DetailedProduct-LifeCycle", "------------onCreate------------");
...
// Set ViewPager
viewPager = findViewById(R.id.view_pager);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
// Send Request
sendRequest();
...
}
public void sendRequest(){
Log.d("DetailedProduct", requestUrl);
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
requestUrl,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
LinearLayout progressView = findViewById(R.id.progressView);
progressView.setVisibility(View.GONE);
bundle.putString("detail", response.toString());
Log.d("DetailedProduct", "get data:"+response.toString());
Log.d("DetailedProduct", "final Data:" + bundle.toString());
adapter.updateFragment(bundle);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("DetailedProduct", "Cannot get detailed data");
}
});
queue.add(jsonObjectRequest);
}
Adapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
private SellerFragment sellerFragment;
private ShippingFragment shippingFragment;
private ProductSummaryFragment productSummaryFragment;
private FragmentManager fragManager;
public ViewPagerAdapter(FragmentManager fragmentManager){
super(fragmentManager);
sellerFragment = new SellerFragment();
shippingFragment = new ShippingFragment();
productSummaryFragment = new ProductSummaryFragment();
}
@NonNull
@Override
public Fragment getItem(int position) {
// ToDo:
Log.d("ViewPager", position+": ------------getItem----------");
switch (position){
case 0:
if(productSummaryFragment==null){
productSummaryFragment = new ProductSummaryFragment();
}
return productSummaryFragment;
case 1:
if(sellerFragment==null){
sellerFragment = new SellerFragment();
}
return sellerFragment;
case 2:
if(shippingFragment==null){
shippingFragment = new ShippingFragment();
}
return shippingFragment;
default:
return null;
}
}
@Override
public int getCount() {
return 3;
}
public void updateFragment(Bundle bundle){
Log.d("ViewPager", "------------updateData----------");
productSummaryFragment.updateData(bundle);
sellerFragment.updateData(bundle);
shippingFragment.updateData(bundle);
}
}
Fragment Sample
public class ShippingFragment extends Fragment {
private TextView shippingSection;
protected JSONObject data;
private AppCompatActivity mActivity;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.shipping_fragment_layout, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shippingSection = view.findViewById(R.id.shipping_info_section_content);
setData();
}
@Override
public void onAttach(@NonNull Context context) {
Log.d("ShippingFragment", "-----------onAttach----------");
super.onAttach(context);
if(context instanceof AppCompatActivity){
Log.d("ShippingFragment", "---------bind mActivity Success-------");
mActivity = (AppCompatActivity)context;
}
}
@Override
public void onDetach() {
Log.d("ShippingFragment", "-----------onDetach----------");
super.onDetach();
}
// Same for all fragments
public void updateData(Bundle bundle){
Log.d("ShippingFragment", "--------------updateData------------");
setArguments(bundle);
if(mActivity==null){
Log.e("ShippingFragment", "------------activity disappears----------");
}
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
fragmentManager.beginTransaction().detach(this).attach(this).commit();
}
}
Problem
The log shows that updateData for fragments at position 0,1 works well. but it incurs error for the fragment at position 2.
The difference I found is that the adaptor didn't call getItem for position 2, which means onAttach of shippingFragment doesn't been called. So mActivity does not exist.
Without mActivity, using getFragmentManager in shippingFragment, get this error:

My intuition tells me that the problem must from the work flow of adapter or the fragmentManager transaction. But as a beginner of Android, I have spent all day on them, no clue.
How to fix it? By the way, is there better way to implement my scene?
