安卓Fragment各种嵌套

/**
 * @author xt on 2019/11/12 9:46
 */
public class CommonFragment extends Fragment {
}
/**
 * @author xuti on 2017/8/7.
 * 使用场景:add hide show进行fragment切换的时候,支持fragment嵌套
 * 1、Activity+BaseFragment
 * 2、Activity+BaseFragment+BaseFragment
 * 3、Activity+ViewPager+BasePageFragment
 * 4、Activity+BaseFragment+ViewPager+BasePageFragment
 */

public abstract class BaseFragment extends CommonFragment {
    private static final String TAG = BaseFragment.class.getSimpleName();
    protected            View   mRootView;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (needInflateRootView()) {
            mRootView = inflater.inflate(getLayoutId(), container, false);
            initViews(mRootView);
            initData();
        }
        return mRootView;
    }

    protected boolean needInflateRootView() {
        return mRootView == null;
    }

    protected abstract int getLayoutId();

    protected void initViews(View view) {

    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();
        //未嵌套fragment
        if (!isHidden()) {
            updateData();
            {
                //处理fragment嵌套的关键逻辑
                List<Fragment> fragments = getChildFragmentManager().getFragments();
                if (!fragments.isEmpty()) {
                    for (Fragment fragment : fragments) {
                        fragment.setUserVisibleHint(fragment.getUserVisibleHint());
                        /*if (fragment instanceof BasePageFragment) {
                            if (fragment.getUserVisibleHint()) {
                                ((BasePageFragment) fragment).updateData();
                            }
                        }*/
                    }
                }
            }
        }
    }

    /**
     * 使用场景:add hide show进行fragment切换的时候
     * 使用add hide() show()方法切换fragment  不会走任何的生命周期
     *
     * @param hidden
     */
    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            updateData();

            //处理fragment嵌套的关键逻辑
            List<Fragment> fragments = getChildFragmentManager().getFragments();
            if (!fragments.isEmpty()) {
                for (Fragment fragment : fragments) {
                    fragment.onHiddenChanged(fragment.isHidden());
                    fragment.setUserVisibleHint(fragment.getUserVisibleHint());
                    /*if (fragment instanceof BasePageFragment) {
                        if (fragment.getUserVisibleHint()) {
                            ((BasePageFragment) fragment).updateData();
                        }
                    }*/
                }
            }
        }


    }

    /**
     * 第一次显示才调用
     */
    protected abstract void initData();

    /**
     * 每一次显示都调用
     */
    protected abstract void updateData();
}

 

/**
 * @author xt on 2019/8/19 13:05
 * ViewPager+BasePageFragment
 */
public abstract class BasePageFragment extends CommonFragment {
    private static final String  TAG = BasePageFragment.class.getSimpleName();
    protected            View    mRootView;
    private              boolean isInitData;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (mRootView == null) {
            mRootView = inflater.inflate(getLayoutId(), container, false);
            initViews(mRootView);
            loadDataLogic();
        }
        return mRootView;
    }

    protected abstract int getLayoutId();

    protected abstract void initViews(View view);

    /**
     * 使用场景:当fragment结合viewpager使用的时候 这个方法会调用
     * 这个方法是在oncreateView之前使用 不要使用控件
     *
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (mRootView == null) {
            return;
        }
        loadDataLogic();
    }

    private void loadDataLogic() {
        if (getUserVisibleHint()) {
            if (!isInitData) {
                isInitData = true;
                initData();
            }
            updateData();
        }
    }

    /**
     * 第一次显示才调用
     */
    public abstract void initData();

    /**
     * 每一次显示都调用
     */
    public abstract void updateData();
}
/**
 * @author xt on 2019/8/19 16:09
 * Activity+BaseFragment
 */
public class FragmentListSampleActivity extends AppCompatActivity {

    private List<Class<? extends Fragment>> mFragmentClassList;
    private View                            mFragmentContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_list_sample);

        mFragmentContainer = findViewById(R.id.fragmentContainer);
        findViewById(R.id.btn0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(0);
            }
        });
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(1);
            }
        });
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(2);
            }
        });

        mFragmentClassList = new ArrayList<>();
        mFragmentClassList.add(SampleFragment.class);
        mFragmentClassList.add(SampleFragment.class);
        mFragmentClassList.add(SampleFragment.class);

        showFragment(0);
    }

    private void showFragment(int position) {
        Bundle args = new Bundle();
        args.putInt("position", position);
        MyUtils.FragmentUtils.showFragment(this, getSupportFragmentManager(), mFragmentContainer, position, mFragmentClassList, args);
    }
}

 

/**
 * @author xt on 2019/8/19 16:09
 * Activity+BaseFragment+BaseFragment
 */
public class FragmentNestListSampleActivity extends AppCompatActivity {

    private List<Class<? extends Fragment>> mFragmentClassList;
    private View                            mFragmentContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_list_sample);

        mFragmentContainer = findViewById(R.id.fragmentContainer);
        findViewById(R.id.btn0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(0);
            }
        });
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(1);
            }
        });
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(2);
            }
        });

        mFragmentClassList = new ArrayList<>();
        mFragmentClassList.add(Fragment1.class);
        mFragmentClassList.add(Fragment2.class);
        mFragmentClassList.add(Fragment3.class);

        showFragment(0);
    }

    private void showFragment(int position) {
        Bundle args = new Bundle();
        args.putInt("position",position);
        MyUtils.FragmentUtils.showFragment(this, getSupportFragmentManager(), mFragmentContainer, position, mFragmentClassList, args);
    }
}
/**
 * @author xt on 2019/11/6 11:18
 */
public class SampleFragment extends BaseFragment {
    private static final String TAG = SampleFragment.class.getSimpleName();

    @Override
    protected int getLayoutId() {
        return com.xt.common.R.layout.fragment_my;
    }

    /**
     * 第一次显示才调用
     */
    @Override
    protected void initData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%s%d%s", "初始化", TAG, getArguments().getInt("position"), "数据"));
    }

    /**
     * 每一次显示都调用
     */
    @Override
    protected void updateData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%s%d%s", "刷新", TAG, getArguments().getInt("position"), "数据"));
    }

 

/**
 * @author xt on 2019/8/19 16:50
 */
public class Fragment1 extends SampleFragment {
    private List<Class<? extends Fragment>> mFragmentClassList;
    private View                            mFragmentContainer;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_1;
    }

    @Override
    protected void initViews(View view) {
        super.initViews(view);
        mFragmentContainer = view.findViewById(R.id.fragmentContainer);
        view.findViewById(R.id.btn0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(0);
            }
        });
        view.findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(1);
            }
        });
        view.findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(2);
            }
        });
    }

    @Override
    protected void initData() {
        super.initData();
        mFragmentClassList = new ArrayList<>();
        mFragmentClassList.add(ChildFragment.class);
        mFragmentClassList.add(ChildFragment.class);
        mFragmentClassList.add(ChildFragment.class);

        showFragment(0);
    }

    private void showFragment(int position) {
        Bundle args = new Bundle();
        args.putInt("position", position);
        MyUtils.FragmentUtils.showFragment(getContext(), getChildFragmentManager(), mFragmentContainer, position, mFragmentClassList, args);
    }
}

 

/**
 * @author xt on 2019/8/19 16:50
 */
public class Fragment2 extends SampleFragment {
}

 

/**
 * @author xt on 2019/8/19 16:50
 */
public class Fragment3 extends SampleFragment {
}

 

/**
 * @author xt on 2019/8/19 16:56
 */
public class ChildFragment extends SampleFragment {
    /**
     * 第一次显示才调用
     */
    @Override
    protected void initData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%d%s", "ChildFragment初始化界面", getArguments().getInt("position"), "数据"));
    }

    /**
     * 每一次显示都调用
     */
    @Override
    protected void updateData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%d%s", "ChildFragment刷新界面", getArguments().getInt("position"), "数据"));
    }
}

 

/**
 * @author xt on 2019/8/14 10:53
 * ViewPager+BasePageFragment
 * FragmentPagerAdapter继承PagerAdapter,通过名字,我们知道它专注于任意页为Fragment的情况。通过FragmentPagerAdapter文档所述,该类中每一个生成的Fragment都将保存在内存中,所以缺点非常明显,对于存在相对较多的fragment,程序将会吃掉非常多的内容。所以FragmentPagerAdapter适合那些相数量相对较少,静态的页面。对于存在多个fragment的情况,一般推荐使用FragmentStatePagerAdapter。
 */
public class ViewPagerFragmentSampleActivity extends AppCompatActivity {
    private ViewPager                 mViewPager;
    private FragmentPagerAdapter mFragmentPagerAdapter;
    private List<Fragment>            mFragments = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager_fragment_sample);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refreshViewPager();
            }
        });
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addPage();
            }
        });
        mViewPager = findViewById(R.id.viewPager);
        //设置缓存page的个数 2*n+1;
        mViewPager.setOffscreenPageLimit(1);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        mFragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public int getCount() {
                return mFragments.size();
            }

            @Override
            public Fragment getItem(int position) {
                return mFragments.get(position);
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                return super.instantiateItem(container, position);
            }

            @Override
            public int getItemPosition(Object object) {
                return POSITION_NONE;
            }

            @Override
            public long getItemId(int position) {
                //可以来源于数据,用以刷新ViewPager
                return super.getItemId(position);
            }
        };
        mViewPager.setAdapter(mFragmentPagerAdapter);

        refreshViewPager();
    }

    /**
     * 刷新viewpager
     */
    private void refreshViewPager() {
        {
            //|FragmentPagerAdapter|清除缓存的fragment,|FragmentStatePagerAdapter|不需要此代码
            FragmentManager     supportFragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction    = supportFragmentManager.beginTransaction();
            for (Fragment fragment : mFragments) {
                fragmentTransaction.remove(fragment);
            }
            fragmentTransaction.commitAllowingStateLoss();
            supportFragmentManager.executePendingTransactions();
        }

        {
            mFragments.clear();
            mFragmentPagerAdapter.notifyDataSetChanged();
            /*if (mFragmentPagerAdapter != null) {
                mFragmentPagerAdapter.notifyDataSetChanged();
                mFragmentPagerAdapter = null;
            }*/
        }

        for (int i = 0; i < 3; i++) {
            Bundle args = new Bundle();
            args.putInt("position", i);
            mFragments.add(Fragment.instantiate(ViewPagerFragmentSampleActivity.this, SamplePageFragment.class.getName(), args));
        }
        mFragmentPagerAdapter.notifyDataSetChanged();
    }

    private void addPage() {
        Bundle args     = new Bundle();
        int    position = mFragments.size();
        args.putInt("position", position);
        mFragments.add(Fragment.instantiate(this, SamplePageFragment.class.getName(), args));
        mFragmentPagerAdapter.notifyDataSetChanged();
        mViewPager.setCurrentItem(position);
    }
}

 

/**
 * @author xt on 2019/8/19 16:09
 * Activity+BaseFragment+ViewPager+BasePageFragment
 */
public class FragmentViewPagerFragmentSampleActivity extends AppCompatActivity {

    private List<Class<? extends Fragment>> mFragmentClassList;
    private View                            mFragmentContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_view_pager_fragment_sample);

        mFragmentContainer = findViewById(R.id.fragmentContainer);
        findViewById(R.id.btn0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(0);
            }
        });
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(1);
            }
        });
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(2);
            }
        });

        mFragmentClassList = new ArrayList<>();
        mFragmentClassList.add(FragmentWithViewPager.class);
        mFragmentClassList.add(SampleFragment.class);
        mFragmentClassList.add(SampleFragment.class);

        showFragment(0);
    }

    private void showFragment(int position) {
        Bundle args = new Bundle();
        args.putInt("position",position);
        MyUtils.FragmentUtils.showFragment(this, getSupportFragmentManager(), mFragmentContainer, position, mFragmentClassList, args);
    }
}

 

/**
 * @author xt on 2019/11/6 11:10
 */
public class SamplePageFragment extends BasePageFragment {
    private static final String TAG = SamplePageFragment.class.getSimpleName();

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_my_page;
    }

    @Override
    protected void initViews(View view) {

    }

    /**
     * 第一次显示才调用
     */
    @Override
    public void initData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%s%d%s", "初始化", TAG, getArguments().getInt("position"), "数据"));
    }

    /**
     * 每一次显示都调用
     */
    @Override
    public void updateData() {
        ToastUtils.showShort(String.format(Locale.getDefault(), "%s%s%d%s", "刷新", TAG, getArguments().getInt("position"), "数据"));
    }
}
/**
 * @author xt on 2019/11/5 11:09
 */
public class FragmentWithViewPager extends SampleFragment {
    private ViewPager            mViewPager;
    private FragmentPagerAdapter mFragmentPagerAdapter;
    private List<Fragment>       mFragments = new ArrayList<>();

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_with_view_pager;
    }

    @Override
    protected void initViews(View view) {
        super.initViews(view);
        view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refreshViewPager();
            }
        });
        view.findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addPage();
            }
        });
        mViewPager = view.findViewById(R.id.viewPager);
        //设置缓存page的个数 2*n+1;
        mViewPager.setOffscreenPageLimit(1);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        mFragmentPagerAdapter = new FragmentPagerAdapter(getChildFragmentManager()) {
            @Override
            public int getCount() {
                return mFragments.size();
            }

            @Override
            public Fragment getItem(int position) {
                return mFragments.get(position);
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                return super.instantiateItem(container, position);
            }

            @Override
            public int getItemPosition(Object object) {
                return POSITION_NONE;
            }

            @Override
            public long getItemId(int position) {
                //可以来源于数据,用以刷新ViewPager
                return super.getItemId(position);
            }
        };
        mViewPager.setAdapter(mFragmentPagerAdapter);
    }

    @Override
    protected void initData() {
        super.initData();
        refreshViewPager();
    }

    @Override
    protected void updateData() {
        super.updateData();
    }

    /**
     * 刷新viewpager
     */
    private void refreshViewPager() {
        {
            //|FragmentPagerAdapter|清除缓存的fragment,|FragmentStatePagerAdapter|不需要此代码
            FragmentManager     supportFragmentManager = getChildFragmentManager();
            FragmentTransaction fragmentTransaction    = supportFragmentManager.beginTransaction();
            for (Fragment fragment : mFragments) {
                fragmentTransaction.remove(fragment);
            }
            fragmentTransaction.commitAllowingStateLoss();
            supportFragmentManager.executePendingTransactions();
        }

        {
            mFragments.clear();
            mFragmentPagerAdapter.notifyDataSetChanged();
        }

        for (int i = 0; i < 3; i++) {
            Bundle args = new Bundle();
            args.putInt("position", i);
            mFragments.add(Fragment.instantiate(getActivity(), SamplePageFragment.class.getName(), args));
        }
        mFragmentPagerAdapter.notifyDataSetChanged();
    }

    private void addPage() {
        Bundle args     = new Bundle();
        int    position = mFragments.size();
        args.putInt("position", position);
        mFragments.add(Fragment.instantiate(getActivity(), SamplePageFragment.class.getName(), args));
        mFragmentPagerAdapter.notifyDataSetChanged();
        mViewPager.setCurrentItem(position);
    }
}

 

public static final class FragmentUtils {
    public static FragmentManager getSupportFragmentManager(@NonNull FragmentActivity fragmentActivity) {
        return fragmentActivity.getSupportFragmentManager();
    }

    public static Fragment addFragment(Context context, @NonNull FragmentManager fragmentManager, Class<? extends Fragment> fragmentClass, int containerViewId, String tag, Bundle args) {
        Fragment            fragment = Fragment.instantiate(context, fragmentClass.getName(), args);
        FragmentTransaction ft       = fragmentManager.beginTransaction();
        ft.add(containerViewId, fragment, tag).commitAllowingStateLoss();
        return fragment;
    }

    private static FragmentTransaction beginTransaction(FragmentManager fragmentManager) {
        return fragmentManager.beginTransaction();
    }

    public static Fragment hideFragment(FragmentManager fragmentManager, @NonNull Fragment fragment) {
        if (fragment.isHidden()) {
            return fragment;
        }
        beginTransaction(fragmentManager).hide(fragment).commitAllowingStateLoss();
        return fragment;
    }

    private static Fragment showFragment(FragmentManager fragmentManager, @NonNull Fragment fragment) {
        if (fragment.isHidden()) {
            beginTransaction(fragmentManager).show(fragment).commitAllowingStateLoss();
        }
        return fragment;
    }


    public static void showFragment(Context context, @NonNull FragmentManager fragmentManager, View container, int position, List<Class<? extends Fragment>> fragmentClassList, Bundle args) {
        int containerViewId = container.getId();
        for (int i = 0; i < fragmentClassList.size(); i++) {
            String   tagPrefix = fragmentClassList.get(i).getSimpleName();
            Fragment fragment  = fragmentManager.findFragmentByTag(tagPrefix + i);
            if (fragment != null) {
                if (i != position) {
                    hideFragment(fragmentManager, fragment);
                }
            }
        }
        {
            String   tagPrefix    = fragmentClassList.get(position).getSimpleName();
            String   showTag      = tagPrefix + position;
            Fragment showFragment = fragmentManager.findFragmentByTag(showTag);
            if (showFragment == null) {
                showFragment = addFragment(context, fragmentManager, fragmentClassList.get(position), containerViewId, showTag, args);
            }
            showFragment(fragmentManager, showFragment);
        }
    }

    public static Fragment findFragment(int position, Class<? extends Fragment> fragmentClass, FragmentManager fragmentManager) {
        String tagPrefix = fragmentClass.getSimpleName();
        return fragmentManager.findFragmentByTag(tagPrefix + position);
    }
}
发布了61 篇原创文章 · 获赞 4 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览