Android’s learning and use of Fragments and problem solving

 

Fragment switching method one

public class MainActivity extends AppCompatActivity {
    Fragment_one one=new Fragment_one();
    Fragment_two two=new Fragment_two();
    FragmentManager manager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        manager=getSupportFragmentManager();//获得Frgment的管理类
    }
    public void one(View view) {
        Toast.makeText(this, "点击了1"+one.isHidden(), Toast.LENGTH_SHORT).show();
        //显示指定的Fragment
        showNewFragment(R.id.mfragment,one);
    }
    public void two(View view) {
        Toast.makeText(this, "点击了2"+two.isHidden(), Toast.LENGTH_SHORT).show();
        //显示制定的Fragment
        showNewFragment(R.id.mfragment,two);
    }

    //这里one.isHidden()和two.isHidden()打印的都为true
    /**
     *
     * @param layoutId 制定的占位视图ID
     * @param fragment 替换的Fragment
     *                 1. !fragment.isAdded() 这里是判断如果我们添加了 之后就不会再添加
     *                 否则会出现异常:Fragment already added 
     *                 2.每次事务只能提交一次
     *                 否则也会出现异常:Fragment already commit
     *
     */
    public void showNewFragment(int layoutId,Fragment fragment){
        FragmentTransaction t1= manager.beginTransaction();
        if(fragment!=null&& !fragment.isAdded()){
            t1.add(layoutId,fragment);
        }
        hideAllFragment();
        t1.show(fragment);
        t1.commit();
    }
    /**
     * 隐藏所以Fragment
     */
    public void hideAllFragment(){
        FragmentTransaction t2= manager.beginTransaction();
            if(one != null){
                t2.hide(one);
            }
            if(two != null){
                t2.hide(two);
            }
            t2.commit();
    }
}

Fragment switching method two

public class MainActivity extends AppCompatActivity {
    Fragment_one one=new Fragment_one();
    Fragment_two two=new Fragment_two();
    FragmentManager manager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        manager=getSupportFragmentManager();//获得Frgment的管理类
        manager.beginTransaction()//添加需要的Fragment,显示默认显示的Fragment
                .add(R.id.mfragment,one)
                .add(R.id.mfragment,two)
                .show(one)
                .commit();
    }
    //这里one.isHidden()和two.isHidden()打印的都为true
    public void one(View view) {
        Toast.makeText(this, "点击了1"+one.isHidden(), Toast.LENGTH_SHORT).show();
        //替换指定的Fragment
        showNewFragment(R.id.mfragment,one);
        manager.beginTransaction()
                .replace(R.id.mfragment,one)
                .commit();
    }
    public void two(View view) {
        Toast.makeText(this, "点击了2"+two.isHidden(), Toast.LENGTH_SHORT).show();
        //替换制定的Fragment
        manager.beginTransaction()
                .replace(R.id.mfragment,two)
                .commit();
    }

The third way to switch Fragment is to combine it with ViewPager

The main thing is to write a ViewPager adapter ( FragmentPagerAdapter) , and put the instantiated Fragment into the adapter, so that you can slide it left and right, and you can also monitor the subscript to control it. The navigation bar displays which page, so I am too lazy to write the code. Yes,

The impact of ViewPager on Fragment life cycle

ViewPager+Fragment is already a relatively common combination, generally used with ViewPager's FragmentPagerAdapter or FragmentStatePagerAdapter. However, in order to prevent glitches from sliding, ViewPager has a caching mechanism. By default, ViewPager will create and cache pages (such as Fragments) on the left and right sides of the current page. At this time, both left and right Fragments will execute the life cycle from onAttach->….->onResume. Obviously the Fragment is not displayed but has already reached onResume. In some cases, problems will occur. For example, the timing of loading data, determining whether the Fragment is visible, etc.

Lazy loading

If the data loading timing is not processed, using ViewPager will also load the data of the left and right Fragments by default. When data loading consumes resources, it will affect performance. We can adjust the loading timing and use lazy loading, specifically loading data when the Fragment is actually visible.

setUserVisibleHint(boolean isVisibleToUser) will be called when Fragment is switched. isVisibleToUser indicates whether it is visible to the user. setUserVisibleHint is not only called when the Fragment is switched, it is called once before onAttach, when isVisibleToUser is false, and once before onCreateView. The value of isVisibleToUser is whether the current Fragment is visible, and then it is called when the Fragment is switched.

Because setUserVisibleHint will be called before onCreateView, if data loading involves view-related operations, don’t forget to set a variable to determine whether the view has been created.

--------------------------------------------------------------------------------------------------------

Let’s analyze the difference between replace and Hide Show .

The difference between Fragment, replace and Hide Show .

1. Replace, add a rollback stack, the Fragment is not destroyed, but it switches back to the destroyed view and re-created view.

2. Replace, without adding a back stack, and the Fragment is destroyed.

3. Hide, show, and Fragment are not destroyed, nor are the views destroyed. Hiding and showing do not follow the life cycle.

This is the life cycle that jumps from view one to view two using replace.

This is the method lifecycle using Hide Show

It can be seen that our view is not destroyed. We jump from the creation of view one to view two and do not execute any life cycle when returning to view one.

Summarize the impact of each method on the life cycle of Fragment .

add:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume

remove:onPause->onStop->onDestroyView->onDestroy->onDetach

show:onHiddenChanged(boolean hidden) hidden为false

hide:onHiddenChanged(boolean hidden) hidden为true

replace: The remove life cycle of the old Fragment -> the add life cycle of the new Fragment

replace+addToBackStack: onPause->onStop->onDestroyView->new Fragment's add life cycle
and then click back: new Fragment's remove->onCreateView->onViewCreated->onActivityCreated->onStart->onResume is the line in the first picture

detach: onPause->onStop->onDestroyView You can see that only the view is removed, the Fragment association status remains unchanged, and it is still under the management of FragmentManger

FragmentTransaction.attach(Fragment var1):onStart->onResume->onCreateView

 

Normal Fragment life cycle

 

 

onAttach(Context context) : Called when Fragment is associated with Activity, and only called once. In this callback, we can convert the context into Activity and save it, thereby avoiding the situation of frequently calling getAtivity() to obtain Activity in the later period, and avoiding the exception that getAtivity() is empty in some cases (when Activity and Fragment are separated) . At the same time, the incoming Arguments can also be extracted and parsed in this callback. It is strongly recommended to pass parameters to Fragment through setArguments, because Fragment will not save relevant attributes when the application is recycled by the system.

onCreate() : Called when the Fragment is initially created, similar to Activity's onCreate. View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState): Called when preparing to draw the Fragment interface. The return value is the root view of the Fragment to draw the layout. Of course, it can also return null. Note that when using inflater to build a View, be sure to specify false for attachToRoot, because Fragment will automatically add the view to the container, and attachToRoot if true will repeatedly add errors. onCreateView will not necessarily be called. When adding a Fragment without an interface, it will not be called, such as calling the add(Fragment fragment, String tag) method of FragmentTransaction.

onCreateView() : Load the Fragment layout and bind the layout file
onActivityCreated() : The Activity whose table name is bound to the Fragment has completed onCreate and can interact with the Activity.
onStart() : Fragment becomes visible state
onResume() : Fragment becomes interactive state
onPause() : Fragment becomes non-interactive state (does not mean invisible)
onSaveInstanceState() : Saves the state of the current Fragment. Record some data, such as the text typed in EditText. Even if the Fragment is recycled and re-created, the text typed in EditText can still be restored.
onStop() : Fragment becomes invisible
onDestroyView() : Destroys the relevant view of Fragment, but does not unbind it from Activity. You can re-create the view through onCreateView().
onDestroy() will be called when the Fragment is destroyed or in the case of ViewPager+Fragment : called when the Fragment is destroyed.
onDetach() : Unbind from Activity. Fragmen destroy the last step

The impact on the life cycle of applications being recycled by the system

In order to prevent errors when the system recycles the application, it is strongly recommended that you
1. Use the setArguments (Bundle bundle) method to pass parameters. Everyone must be very familiar with conventional variables, so I won’t go into details. The main emphasis here is on View variables and interface variables. View variables can be implemented by passing in the ID of the View and then obtaining the view through the ID. The interface can be implemented through Activity, and Fragment is forced to be implemented by Activity.
2. Before addingFragment, first use findFragmentById to determine whether it has been added to avoid repeated additions. If you use FragmentAdapter, you can store the corresponding Fragment.getTag in onSaveInstanceState.

Recommended framework fragmentation

Let’s take a look at YoKey’s explanation of Fragmentation .

https://www.jianshu.com/p/d9143a92ad94

 

 

Guess you like

Origin blog.csdn.net/yuhui77268769/article/details/103200840