【发布时间】:2020-06-25 06:16:16
【问题描述】:
场景
一旦我得到一些 HTTP 请求的响应,我想更新几个 fragments 的内容。
我的想法
我的实现是这样的:
onCreate 的活动,绑定 ViewPagerAdapter 到它。然后触发HTTP请求获取数据。
请求成功后,更新 Fragment 中的内容。
代码
sendRequest。 --> adapter.updateFragment(bundle) --> fragment.updateData(bundle);
活动
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);
}
适配器
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);
}
}
片段样本
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();
}
}
问题
日志显示updateData 用于位置 0,1 的片段效果很好。但它会导致位置 2 的片段出错。
我发现的区别是适配器没有为位置2调用getItem,这意味着shippingFragment的onAttach没有被调用。所以mActivity 不存在。
没有mActivity,在shippingFragment中使用getFragmentManager,得到这个错误:
我的直觉告诉我,问题一定出自适配器的工作流程或fragmentManager事务。但是作为一个Android的初学者,我花了一整天的时间,一点头绪都没有。
如何解决?顺便问一下,有没有更好的方法来实现我的场景?
【问题讨论】:
标签: android android-fragments android-adapter