1.问题由来:项目的旧有代码中有一个Banner使用了Fragment+FragmentPagerAdapter的方式实现,当数据刷新调用adapter的NotifyDatasetChanged方法后,发现Fragment并没有重走任何生命周期方法,Fragment实例也没有重新创建,无法实现数据的刷新
2.思考:FragmentPagerAdapter中的getItem方法和initiateItem方法都没有被调用,查阅了一些资料 http://blog.youkuaiyun.com/zqs62761130/article/details/46289739 ,
文章指出了NotifyDatasetChanged方法调用后的机制
因此,对于 FragmentPagerAdapter 的解决方案就是,分别重载 getItem() 以及 instantiateItem() 。getItem() 只用于生成新的与数据无关的 Fragment;而 instantiateItem() 函数则先调用父类中的 instantiateItem() 取得所对应的 Fragment 对象,然后,根据对应的数据,调用该对象对应的方法进行数据设置。
当然,不要忘记重载 getItemPosition() 函数,返回 POSITION_NONE,这个两个类的解决方案都需要的。二者不同之处在于,FragmentStatePagerAdapter 在会在因 POSITION_NONE 触发调用的 destroyItem() 中真正的释放资源,重新建立一个新的 Fragment;而 FragmentPagerAdapter 仅仅会在 destroyItem() 中 detach 这个 Fragment,在 instantiateItem() 时会使用旧的 Fragment,并触发 attach,因此没有释放资源及重建的过程。3.解决方法:
重写getItemPosition方法,使得数据刷新后能够调用initiateItem方法,在该方法中为Fragment重新设置数据,但是这里不能使用setArgument的方式,因为FragmentPagerAdapter中Fragment不会销毁重建,而setArgument只在Fragment没有被添加到FragmentManager之前才会有效,所以需要其他方式设置数据(直接设置数据bean等)。
4.一个例子
private static class BannerAdapter extends FragmentPagerAdapter { List<ProjectBean> mData; BannerAdapter(FragmentManager fm) { super(fm); mData = new ArrayList<>(); } void update(List<ProjectBean> data) { mData.clear(); mData.addAll(data); notifyDataSetChanged(); } @Override public Fragment getItem(int position) { return BannerFragment.instance(mData.get(position)); } @Override public int getCount() { return mData.size(); } } public static class BannerFragment extends Fragment { static BannerFragment instance(ProjectBean bean) { BannerFragment fragment = new BannerFragment(); Bundle bundle = new Bundle(); bundle.putSerializable("data", bean); fragment.setArguments(bundle); return fragment; } private TextView mTitle; private TextView mIncome; private TextView mIncomeDesc; private TextView mTimeDesc; private TextView mLabel1; private TextView mLabel2; private TextView mMoneyDesc; private TextView mTime; private TextView mMoney; private ProgressBar mProgressBar; private ImageView mTag; private ConstraintLayout mLayout; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_banner, container, false); initView(rootView); initData(getArguments(), rootView); mLayout.setBackgroundResource(R.mipmap.list_bg_red); return rootView; } private void initData(Bundle arguments, View rootView) { ProjectBean item = (ProjectBean) arguments.getSerializable("data"); mTitle.setText(item.title); mIncome.setText(item.userInterest + "%"); if (item.userRaiseInterest <= 0) { mLabel1.setVisibility(View.GONE); } else { mLabel1.setText("已加" + item.userRaiseInterest + "%"); } if (TextUtils.isEmpty(item.giveoutInterestDesc)) { mLabel2.setVisibility(View.GONE); } else { mLabel2.setText(item.giveoutInterestDesc); } mTime.setText(item.duration + "天"); int remind = (int) (item.amount * (100 - item.percent) / 100); mMoney.setText(remind + "元"); mProgressBar.setProgress(((int) item.percent)); rootView.setOnClickListener(v -> Skip.toProjectDetail(v.getContext(), item.id)); switch (getLabelType(item)) { case -1: mTag.setImageResource(R.drawable.tag_full); break; case -2: mTag.setImageResource(R.drawable.tag_repayment); break; case 1: mTag.setImageResource(R.drawable.tag_1); break; case 2: mTag.setImageResource(R.drawable.tag_2); break; case 3: mTag.setImageResource(R.drawable.tag_3); break; case 4: mTag.setImageResource(R.drawable.tag_4); break; case 5: mTag.setImageResource(R.drawable.tag_5); break; case 6: mTag.setImageResource(R.drawable.tag_6); break; case 9: mTag.setImageResource(R.drawable.tag_9); break; } } private int getLabelType(ProjectBean item) { switch (item.categoryId) { case 2: return -1; case 3: return -2; default: return item.newPreferential; } } private void initView(@NonNull final View itemView) { mTitle = (TextView) itemView.findViewById(R.id.title); mLayout = (ConstraintLayout) itemView.findViewById(R.id.layout); mIncome = (TextView) itemView.findViewById(R.id.income); mIncomeDesc = (TextView) itemView.findViewById(R.id.incomeDesc); mTimeDesc = (TextView) itemView.findViewById(R.id.timeDesc); mLabel1 = (TextView) itemView.findViewById(R.id.label1); mLabel2 = (TextView) itemView.findViewById(R.id.label2); mMoneyDesc = (TextView) itemView.findViewById(R.id.moneyDesc); mTime = (TextView) itemView.findViewById(R.id.time); mMoney = (TextView) itemView.findViewById(R.id.money); mProgressBar = (ProgressBar) itemView.findViewById(R.id.progressBar); mTag = (ImageView) itemView.findViewById(R.id.tag); } }
Fragment在FragmentPagerAdapter中生命周期调用
最新推荐文章于 2024-06-24 20:04:22 发布