Fragment在FragmentPagerAdapter中生命周期调用

 
  

1.问题由来:项目的旧有代码中有一个Banner使用了Fragment+FragmentPagerAdapter的方式实现,当数据刷新调用adapter的NotifyDatasetChanged方法后,发现Fragment并没有重走任何生命周期方法,Fragment实例也没有重新创建,无法实现数据的刷新

2.思考:FragmentPagerAdapter中的getItem方法和initiateItem方法都没有被调用,查阅了一些资料 http://blog.csdn.net/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 mData;

        BannerAdapter(FragmentManager fm) {
            super(fm);
            mData = new ArrayList<>();
        }

        void update(List 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);
        }
    }



你可能感兴趣的:(Android)