Android learning (5) - Fragment

Fragment

Fragment was originally designed for junior high school to adapt to large-screen tablet computers. Now our ordinary mobile phone development will also add this Fragment. We can understand it as a small Activity, but it must be nested in an Activity, so we You can understand him according to the literal translation - a "fragment" of Activity. Although fragment has its own life cycle, it will still be affected by the host activity.

The life cycle

write picture description here

FragmentManager

Let me talk about it here. There are currently two kinds of fragments, one is the fragment of the v4 package, and the other is the native fragment, so there are two ways to obtain the fragmentManager:

  • getSupportFragmentManager() is used for v4 package to get fragmentManager
  • getFragmentManager() Get Fragmentmanager for Fragment of app package

FragmentManager is used to handle part of the fragment's operations

  • Use the findFragmentById() or findFragmentByTag() methods to get the fragments existing in the Activity, and you can also judge whether the fragments sent in the Ativity are empty.
  • popBackStack(): Pops the last fragment transition in the back stack. Returns false if there is nothing to pop from the stack.

FragmentTransaction

This is a class that specifically handles Fragment transactions. It can perform operations such as adding, deleting, replacing, and hiding fragments.

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();

transaction.add(R.id.fragment_container, newFragment);//添加一个fragment
transaction.replace(R.id.fragment_container, new2Fragment);//替换一个fragment
transaction.hide(newFragment);//隐藏一个fragment
transaction.remove(newFragment);//删除一个fragment
transaction.addToBackStack(null);加入BACK栈
transaction.commit();//提交事务操作

About the commit method

  • Calling the commit method does not immediately execute the change action contained in the transaction. The commit method adds the transaction to the UI thread queue of the activity
  • You can only call commit before the activity saves its state, if it is called after the state is saved, an exception will be thrown (saved state: that is, when the user leaves the activity, saveInstanceStates)

About the performance of add and replace

There are two ways to replace fragments:
1. Add in, then hide and add a new fragment. When you want to switch back to the previous fragment, hide the new fragment and show the old fragment.
2. Add it in, then replace it with a new fragment, and continue to repalce the old one when you want to cut it back

I found a blog before showing the performance ratio of these two methods:
add method
write picture description here

replace method
write picture description here

So if you want to improve performance, try to use the add method to add fragments

Encapsulates a method for adding and switching:

     /**
     * 添加/或展示一个fragment
     * @param fragment 想要添加/展示的fragment
     * @param id 占位布局的ID
     * @param tag 打一个T啊,需要用这个Tag去搜索是否存在这个fragment
     */
    private <T extends Fragment> void addNewFragment( T fragment, int id, String tag) {

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        //优先检查,fragment是否存在,避免重叠
        T tempFragment = (T)fragmentManager.findFragmentByTag(tag);

        if (tempFragment != null) {
            fragment = tempFragment;
        }

        if (fragment.isAdded()) {
            addOrShow(fragmentTransaction, fragment, id, tag);
        } else {
            if (currentFragment != null && currentFragment.isAdded()) {
                fragmentTransaction.hide(currentFragment).add(id, fragment, tag).commit();
            } else {
                fragmentTransaction.add(id, fragment, tag).commit();
            }
            currentFragment = fragment;
        }
    }

    /**
     * 添加/展示fragment方法
     * @param transaction fragment处理事务
     * @param fragment 想要添加/展示的fragment
     * @param id 占位布局的ID
     * @param tag fragment查询标识
     */
    private <T extends Fragment> void addOrShow(FragmentTransaction transaction, T fragment, int id, String tag) {
        if (currentFragment == fragment)
            return;
        if (!fragment.isAdded()) { // 如果当前fragment未被添加,则添加到Fragment管理器中
            transaction.hide(currentFragment).add(id, fragment, tag).commit();
        } else {
            transaction.hide(currentFragment).show(fragment).commit();
        }
        currentFragment.setUserVisibleHint(false);
        currentFragment = fragment;
        currentFragment.setUserVisibleHint(true);
    }

Explain here

First of all, what we pass in is that the subclass of Fragment uses a generic type (in fact, a Fragment can also be passed here, I think I seem to be superfluous)
Next, look at the process:

Created with Raphaël 2.1.2 传入参数(Fragment fragment, int id, String tag) 通过Tag查找这个fragment 存在? fragment = 查出来的 是否添加了? 添加或者展示 isAdded()? add currentFragment = fragment; 结束 show 当前fragment非空且add? 隐藏当前fragment add yes no yes no yes no yes no

In this way, no matter what fragment you replace, as long as you call this method, you will use the Add method to replace the fragment (this process is very simple to understand at a glance, if you don't understand it, it is simple and rude to paste the code directly)

Epilogue

I won't talk about the rest. So far, you can use fragments initially. As for the deeper things, I hope you will think more about programming. The water is very deep. There are always better methods, more flexible methods, and more. A business-friendly approach, so there's no end to learning !

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324895537&siteId=291194637