美文网首页
FragmentPagerAdapter类文件可动态修改Frag

FragmentPagerAdapter类文件可动态修改Frag

作者: songjk | 来源:发表于2021-03-30 15:53 被阅读0次
    public class BaseFragmentPagerAdapter extends FragmentPagerAdapter {
        
            private List<Fragment> mFragmentList;
            private FragmentManager mFragmentManager;
            /**下面两个值用来保存Fragment的位置信息,用以判断该位置是否需要更新*/
            private SparseArray<String> mFragmentPositionMap;
            private SparseArray<String> mFragmentPositionMapAfterUpdate;
        
            public BaseFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
                super(fm);
                mFragmentList = fragments;
                mFragmentManager = fm;
                mFragmentList = fragments;
                mFragmentPositionMap = new SparseArray<>();
                mFragmentPositionMapAfterUpdate = new SparseArray<>();
                setFragmentPositionMap();
                setFragmentPositionMapForUpdate();
            }
        
        
            /**
             * 保存更新之前的位置信息,用<hashCode, position>的键值对结构来保存
             */
            private void setFragmentPositionMap() {
                mFragmentPositionMap.clear();
                for (int i = 0; i < mFragmentList.size(); i++) {
                    mFragmentPositionMap.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
                }
            }
        
            /**
             * 保存更新之后的位置信息,用<hashCode, position>的键值对结构来保存
             */
            private void setFragmentPositionMapForUpdate() {
                mFragmentPositionMapAfterUpdate.clear();
                for (int i = 0; i < mFragmentList.size(); i++) {
                    mFragmentPositionMapAfterUpdate.put(Long.valueOf(getItemId(i)).intValue(),  String.valueOf(i));
                }
            }
        
           /**
            * 在此方法中找到需要更新的位置返回POSITION_NONE,否则返回POSITION_UNCHANGED即可
            */
            @Override
            public int getItemPosition(Object object) {
                int hashCode = object.hashCode();
                //查找object在更新后的列表中的位置
                String position = mFragmentPositionMapAfterUpdate.get(hashCode);
                //更新后的列表中不存在该object的位置了
                if (position == null) {
                    return POSITION_NONE;
                } else {
                    //如果更新后的列表中存在该object的位置, 查找该object之前的位置并判断位置是否发生了变化
                    int size = mFragmentPositionMap.size();
                    for (int i = 0; i < size ; i++) {
                        int key = mFragmentPositionMap.keyAt(i);
                        if (key == hashCode) {
                            String index = mFragmentPositionMap.get(key);
                            if (position.equals(index)) {
                                //位置没变依然返回POSITION_UNCHANGED
                                return POSITION_UNCHANGED;
                            } else {
                                //位置变了
                                return POSITION_NONE;
                            }
                        }
                    }
                }
                return POSITION_UNCHANGED;
            }
        
            /**
             * 将指定的Fragment替换/更新为新的Fragment
             * @param oldFragment 旧Fragment
             * @param newFragment 新Fragment
             */
            public void replaceFragment(Fragment oldFragment, Fragment newFragment) {
                int position = mFragmentList.indexOf(oldFragment);
                if (position == -1) {
                    return;
                }
                //从Transaction移除旧的Fragment
                removeFragmentInternal(oldFragment);
                //替换List中对应的Fragment
                mFragmentList.set(position, newFragment);
                //刷新Adapter
                notifyItemChanged();
            }
        
            /**
             * 将指定位置的Fragment替换/更新为新的Fragment,同{@link #replaceFragment(BaseFragment oldFragment, BaseFragment newFragment)}
             * @param position    旧Fragment的位置
             * @param newFragment 新Fragment
             */
            public void replaceFragment(int position, Fragment newFragment) {
                Fragment oldFragment = mFragmentList.get(position);
                removeFragmentInternal(oldFragment);
                mFragmentList.set(position, newFragment);
                notifyItemChanged();
            }
        
            /**
             * 移除指定的Fragment
             * @param fragment 目标Fragment
             */
            public void removeFragment(Fragment fragment) {
                //先从List中移除
                mFragmentList.remove(fragment);
                //然后从Transaction移除
                removeFragmentInternal(fragment);
                //最后刷新Adapter
                notifyItemChanged();
            }
        
            /**
             * 移除指定位置的Fragment,同 {@link #removeFragment(BaseFragment fragment)}
             * @param position
             */
            public void removeFragment(int position) {
                Fragment fragment = mFragmentList.get(position);
                //然后从List中移除
                mFragmentList.remove(fragment);
                //先从Transaction移除
                removeFragmentInternal(fragment);
                //最后刷新Adapter
                notifyItemChanged();
            }
        
            /**
             * 添加Fragment
             * @param fragment 目标Fragment
             */
            public void addFragment(Fragment fragment) {
                mFragmentList.add(fragment);
                notifyItemChanged();
            }
        
            /**
             * 在指定位置插入一个Fragment
             * @param position 插入位置
             * @param fragment 目标Fragment
             */
            public void insertFragment(int position, Fragment fragment) {
                mFragmentList.add(position, fragment);
                notifyItemChanged();
            }
        
            private void notifyItemChanged() {
                //刷新之前重新收集位置信息
                setFragmentPositionMapForUpdate();
                notifyDataSetChanged();
                setFragmentPositionMap();
            }
        
            /**
             * 从Transaction移除Fragment
             * @param fragment 目标Fragment
             */
            private void removeFragmentInternal(Fragment fragment) {
                FragmentTransaction transaction = mFragmentManager.beginTransaction();
                transaction.remove(fragment);
        //        transaction.commitNow();
                transaction.commitNow();
            }
        
            /**
             * 此方法不用position做返回值即可破解fragment tag异常的错误
             */
            @Override
            public long getItemId(int position) {
                // 获取当前数据的hashCode,其实这里不用hashCode用自定义的可以关联当前Item对象的唯一值也可以,只要不是直接返回position
                return mFragmentList.get(position).hashCode();
            }
        
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }
        
            @Override
            public int getCount() {
                return mFragmentList.size();
            }
        
            public List<Fragment> getFragments() {
                return mFragmentList;
            }
        }

    相关文章

      网友评论

          本文标题:FragmentPagerAdapter类文件可动态修改Frag

          本文链接:https://www.haomeiwen.com/subject/cmrghltx.html