IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android之Fragment -> 正文阅读

[移动开发]android之Fragment

? 目录

一Fragment的简介和生命周期:

? ? ? ? ? ? ???<1> Fragment的简介

? ? ??? ??? ??<2> Fragment的生命周期

二将Fragment添加到Activty中使用

? ? ? ? ? ? ? <1>概述

? ? ? ? ? ? ? <2>使用不兼容方法将Fragemnt添加到Activity中使用

? ? ? ? ? ? ? ? ? ? ? ? ? ? <2.1>不兼容方法的大概步骤:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<2.2>不兼容方法的实际代码展示

? ? ? ? ? ? ? <3>使用兼容方法将Fragment添加到Activity中使用

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<3.1>不兼容方法的大概步骤:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<3.2>不兼容方法的实际代码展示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<3.3>不兼容方法的一个实际例子:

三Fragment和Fragment之间的通信

? ? ? ? ? ? <1>在fragment中如何修改activity界面中的相关内容:

? ? ? ? ? ? <2>在activity中如何修改Fragment界面中的相关内容:

? ? ? ? ? ? <3>在activity中如何给Fragment传递信息

四.Fragment使用中的重要方法的讲解

五Fragment的压栈出栈

? ? ? ? ? ? ? ? ?<1>.第一种方式:使用add()+addToBackStack()

? ? ? ? ? ? ? ? ?<2>.第二种方式:使用add()+addToBackStack()+直接重写onBackPressed()

? ? ? ? ? ? ? ? ?<3>第三种方式:使用add()+ArrayList+重写onbackProcess()方法

六Fragment的hide()和show()方法的使用

? ? ? ? ? ? ? ? ? ??? <6.1>.两个方法如何使用:

? ? ? ? ? ? ? ? ? ? ?<6.2>两个方法的使用场景

? ? ? ? ? ? ? ? ? ? ? <6.3>.模拟微信首页的形式

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <1> 微信首页大致原理讲解?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <2>微信首页具体的代码

? ? ? ? ? ? ? ? ? ? ?<6.4>正常的使用(将所有的fragment添加到了回退栈中,这种场景我暂时没有见过****不太重要,有时间了再看吧):

? ? ? ? ? ? ? ? ? ? ?<6.5>在项目4中出现了一个问题,解决方法如下(这个也不太重要,当有充足时间的时候,再看这个):


一Fragment的简介和生命周期:

? ??? ???<1> Fragment的简介

? ??? ??? ??? ??? ?Fragment就是activity界面的一部分,简称碎片,在一个app中如果只是要求一个页面的部分不断的变化,这个不断变化的部分就可用用fragment来替代,该类是android 3.0新出来的(api是11)。

? ??? ???<2>?Fragment的生命周期

? ??? ??? ??? ??? ??? ??Fragment有11个生命周期方法,每个方法调用的时机和activity和生命周期调用方法的时机的关系,如图所示

       --onAttach()    当fragment和它的activity第一次关联的时候调用
       --onCreate()    调用这个方法去初始化fragment的创建
       --onCreateView()  调用这个方法去实例化Fragment的用户界面(这个方法的返回值是View)
       --onActivityCreated()   当fragment绑定的activity已经创建了,fragment已经被实例化了的时候,这个方法会被调用;
       --onStart()  当fragment可见但是没有焦点的时候调用,绑定Activity的onStart()方法(在activity的onstart()方法之后调用)
       --onResume() 当fragment可见且获取焦点的时候调用,绑定Activity的onResume()方法(在activity的onresume()方法之后调用)
       --onPause() 当Fragment可见但是失去焦点的时候调用,绑定Activity的onPause()方法(在activity的onPause()方法之后调用)
       --onStop() 当Fragment不可见的时候调用,绑定Activity的onStop()方法(在activity的onstop()方法之后调用)
       --onDestroyView() 当Fragement的用户界面和Fragment解除关联的时候调用
       --onDestroy()  当Fragment不再有用的时候()调用
       --onDetach()  当Fragment和activity解除关联的时候调用。

二将Fragment添加到Activty中使用

? ? ? ? ? ? ? ? <1>概述

<1>Fragemnt出现的api是11,也就是android3.0出现的, 当我们的app是兼容Android 3.0之下的版本的时候,此时我们在activity中添加Fragment就必须要使用兼容版的方式进行添加了;但是如果我们
    		的app不需要兼容到android 3.0之下的话,此时就可以直接使用不兼容版本的方式在activty中添加Fragment。
    <2>将Fragment添加到Activity中的兼容版本的本质是:    
            	每个android系统都有v4包或者v7包(v7包中包含大部分v4东西),所以说直接使用v4包中的类,不管什么版本的android版本都可以运行,因为都可以找到这个类。所以该种方式使用的Fragemnt的就是		V4包中的,FragmentManager也是V4包中的,这样不管在任何的android中版本中,都可以找到这个类了,那么Fragment在任何版本中也都可以展示了。
	<3>现况是:   
               google现在除了Androidx替代了v4,v7等扩展包了,所以现在使用的Fragment以及相关的FragmentActivity都是androidx包中的东西。其他不变。             

? ? ? ? ? ? ? ? <2>使用不兼容方法将Fragemnt添加到Activity中使用

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <2.1>不兼容方法的大概步骤:

				<1>创建一个类继承Fragment(该Fragment为android.jar包中的类),复写其中的onCreateView()方法
                <2>创建一个类继承Activity(该Activity是android.jar包中的类,这个不受限制)
                <3>在Activity中开始添加Fragment:
                		<3.1>创建Fragment子类对象
                        <3.2>获取到FragmentManager对象(该Fragment是android.jar包中的类)
                        <3.3>通过FragmentManager对象获取到FragmentTransaction对象(FragmentTransaction是android.jar包中的类)
                        <3.4>调用FragmentTransaction对象的相关方法添加Fragmen到activity中。
                        			具体的方法:add(),replace(),hide(),show(),commit()等方法。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <2.2>不兼容方法的实际代码展示

<1>创建一个类继承Fragment
import android.app.Fragment;//是android.jar中的Fragment,不是v4包中的

public class MySelftFragment extends Fragment {

    private TextView tv_two;
    private Button bt_callback;

    @Nullable
    @Override  
    //这个方法必须要重写,作用:实例化fragnment的用户界面。
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.fragment_myself, null);
        return inflate;

    }
}

<2>创建一个普通的Activity
<3>添加Fragment到Activiyt中

        //1。创建Fragment的对象。
         MySelftFragment fragment=new MySelftFragment();
        //2.获取FragmentManager对象
        FragmentManager fragmentManager = getFragmentManager();
        //3.开启事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //4.调用添加方法,(使用穿进去的Fragment对象的xml文件替换R.id.ll_content的控件)
        fragmentTransaction.add(R.id.ll_content,fragment,"mySelftFragment").addToBackStack("qindong");
        //5.提交事务,mySelftFragmentId就是这个特定的fragment的id值了,在activity中可以通过findFragmentById(id)来获取到相应的fragment对象。
        mySelftFragmentId = fragmentTransaction.commit();

? ? ? ? ? ? ? ? <3>使用兼容方法将Fragment添加到Activity中使用

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <3.1>兼容方法的大概步骤:

<1>创建一个类继承Fragment,这个Fragment是v4包中的Fragment,不是android.jar中的Fragment
                       <2>创建一个类继承FragmentActivity,该FragmentActivity是V4包中的类,该类也是继承与activity的。
                       <3>在FragmentActivity中,将fragment添加到actiivty中:
                       			<1>创建Frgment对象
                                <2>获取到FragmentManager对象(该FragmentManager是v4包下的类)
                                <3>通过FragmentManager对象,获取到FragmentTransaction(该FragmentTransaction是v4包下的类)
                                <4>调用FragmentTransaction的相关方法将Fragment对象添加到Activity中。
                                		具体方法:add(),replace(),hide(),show(),commit()等方法
                                        
                                        
                                        
                  跟新:
                  		但是现在androidx已经替换了v4,v7等扩展包,所以第一步中继承的Fragment,现在已经变成了Androidx中的Fragmnet,如:androidx.fragment.app.Fragment;
                        		第二步中继承的FragmentActivity,也变成了androidx包中的了,如:import androidx.fragment.app.FragmentActivity;
                    	而其他的步骤则保持不变。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <3.2>兼容方法的实际代码展示:

        /**
         * 注意:一下的Fragment,FragmentManager,FragmentTransaction都是v4包中的类。
         * */
        //0.创建相应的Fragment对象
        RedFragment redFragment = new RedFragment();
        //1.获取到相应的fagnmentManager对象,注意此时使用的getSupportFragmentManager()方法
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        //2.开启FragmentManager对象的事务管理器
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
        //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
        fragmentTransaction.replace(R.id.fl_frameLayout_content, redFragment, "redFragment");
        //4.向fragment事务管理器提交,创建fragment
        fragmentTransaction.commit();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <3.3>不兼容方法的一个实际例子:

<1>创建三个类均继承Fragment(V4包中的fragment)
//这是第一个Fragment的子类
public class RedFragment extends Fragment {

    @Nullable
    @Override
    //该方法用于实例化fragment的用户界面(该方法返回一个view)
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, null);
        return view;
    }
}

//这是第二个Fragment子类
public class GreenFragment extends BaseFragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_green,null);
        return view;
    }
}


//这是第三个Fragment的子类
public class BlueFragment extends BaseFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_blue,null);
        return view;
    }
}


<2>创建一个类FragmentOneActivity继承FragmentActivitry(V4包中的类)

public class FragmentOneActivity extends FragmentActivity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private ArrayList<BaseFragment> arrayList=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("qindong", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        ShowRedFragment();
    }

    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        /**
         * 注意:一下的Fragment,FragmentManager,FragmentTransaction都是v4包中的类。
         * */
        //0.创建相应的Fragment对象
        RedFragment redFragment = new RedFragment();
        redFragment.setLogName("RedFragment:");
        //1.获取到相应的fagnmentManager对象,注意此时使用的getSupportFragmentManager()方法
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        //2.开启FragmentManager对象的事务管理器
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
        //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
        fragmentTransaction.replace(R.id.fl_frameLayout_content, redFragment, "redFragment");
        //4.向fragment事务管理器提交,创建fragment
        fragmentTransaction.commit();
    }

    private void ShowGreenFragment() {
        GreenFragment greenFragment = new GreenFragment();
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fl_frameLayout_content, greenFragment, null);
        fragmentTransaction.commit();
        arrayList.add(greenFragment);

    }

    private void ShowBlueFragment() {
        BlueFragment blueFragment = new BlueFragment();
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fl_frameLayout_content, blueFragment, null);
        fragmentTransaction.commit();
        arrayList.add(blueFragment);
    }
}

<3>这是activity对应的xml布局文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/fl_frameLayout_content"
        android:layout_width="match_parent"
        android:layout_height="400dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="这是默认显示的内容" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_red"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="红色" />

        <Button
            android:id="@+id/bt_green"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="绿色" />

        <Button
            android:id="@+id/bt_blue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="蓝色" />
    </LinearLayout>

</LinearLayout>

三Fragment和Activity之间的通信? ?

? ??? ??? ? <1>在fragment中如何修改activity界面中的相关内容:

? ??? ??? ??? ??? ??? ? 思路:通过方法getActivity())得到frgment所绑定的那个activity对象,然后调用该activity类中的方法,就可以达到目的了

//这是在fragment中的方法,setInfo(String s)是其绑定的activity中的方法
        String s = tv_two.getText().toString();
        ((FragmentActivity) getActivity()).setInfo(s);

?

? ??? ??? ? <2>在activity中如何修改Fragment界面中的相关内容:

? ??? ??? ??? ??? ? ? ?思路:在actiivty中获取到特定的Fragment的对象,然后通过对象调用Fragment中的方法即可。而在activity中获取到特定的Fragment对象,有两种方式,分别是通过target和ID,如下:

//1.第一种方式:在actiivty中,通过target值来获取到特定的Fragment对象
HomeFragment homeFragment = (HomeFragment) getFragmentManager().findFragmentByTag("homeFragment");


//2.第二种方式:在actiivty中,通过id值来获取到特定的Fragment对象
       MySelftFragment mySelfFragment = (MySelftFragment) getFragmentManager().findFragmentById(mySelftFragmentId);//通过id来获取特定的对象




//3如何给特定的Fragment设置tag和id,则是如下:
        //MySelftFragment是自定义的一个类,继承Fragment。-----这些方法是不考虑兼容的版本。
        MySelftFragment fragment=new MySelftFragment();
        //1.获取FragmentManager对象
        FragmentManager fragmentManager = getFragmentManager();
        //2.开启事务
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //3.调用添加方法replace()或者add()方法,其中第三个参数就是为本Fragment设置的tag
        fragmentTransaction.replace(R.id.ll_content,fragment,"mySelftFragment");
//        fragmentTransaction.add(R.id.ll_content,fragment,"mySelftFragment");
        //提交事务 ,此时返回的int型值就是本Fragment的id值。
        int  mySelftFragmentId = fragmentTransaction.commit();

?

? ? ? ? ? ? ? <3>在activity中如何给Fragment传递信息

? ? ? ? ? ? ? ? ? ? ? ? 思路:在Fragment中有一个方法,即setArguments(Bundle bundle),我们可以将要传递的数据封装在bundle中;然后当我们在Fragmnet中获取该bundle对象,进而提取到我们的数据即可。

	1>在activity中创建一个Fragment对象,然后将数据封装在Bundle中。
    
    			Fragment fragment=new GoodsFragment();
                Bundle bundle=new Bundle();
                bundle.putString("seller_id",seller_id);
                fragment.setArguments(bundle);
		...(正常的将Fragment添加到Activity中的代码,此处省略)
    
    2>在对应的Fragment中,获取到该Bundle对象,然后获取到该数据。
    
    	public class GoodsFragment extends BaseFragment {

    @Override
    public View onCreateView( LayoutInflater inflater,  ViewGroup container,  Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.fragment_goods, null);
        Bundle bundle=getArguments();
        String seller_id=bundle.getString("seller_id");
        return inflate;
    }
}

四Fragment使用中的重要方法的讲解:

       < 1>.replace(int id,Fragment fragment,String tag)----会直接将之前的所有的Fragment直接销毁(直接调用之前所有的Fragment的onpause()--onstop()----ondestroyView()----ondestroy()---onedetach()),然后在创建本Fragment(onAttach()---onCreate()----onCreateView()---onActivityCreate()--onStart()---onResume());
                        当在调用replace()方法的同时调用了addToBackStack(),那么此时之前所有的的fragment执行的就是(onpause()--onstop()----ondestroyView()),然后在回退到他们的fragment页面的时候,其会执行(oncreateView()----onActivityCreated()--onstart()--onresume());
                        
                        
       <2>.add(int id ,Fragment fragment,String tag)-------当调用这个方法的时候,此时对于上一个Fragmnet(是其本身或者是另一个Fragment),系统什么都不会做,其还是处于onResume()执行完的状态,也就是说其Fragment对象不会销毁;对于本Fragment,会执行以下方法(onAttach()--oncreate()---oncreateView()---onActivityCreated()--onstart()---onResume());
                    使用add()方法添加同一Fragmnet的同一个对象,不能添加多次,否则应用会崩掉(测试过,同一对象也就是要说这个Fragment应该是一个全局变量或者静态全局变量)
                    
                    
                    
         3.当我们使用FragmentTransaction对象的add()方法添加Fragment的时候,此时系统是以栈的形式来进行管理的,即先进后出。例子:一下三个Fragment对应的都是activity中同一个FrameLayout的时候,前两个是通过add()方法添加的,此时管理fragment的结构数据(即栈)中有两个fragment对象,当第三个使用replace方法添加fragment的时候,此时调用fragment的生命周期方法()来销毁栈中的所有的fragment对象,顺序为倒叙(即先销毁第二个fragment对象,然后在销毁第一个fragment对象)
                    使用replace()方法添加同一个Fragmnet的同一个对象,添加多少次都没有关系,应用都不会崩掉(),因为此时这个Fragment对象不会走任何生命周期方法。
                    
                    
                    
        4.回退键即onBackProcess()中默认就是调用当前activity的finish()方法,销毁当前activity。
        
        
        5.addToBackStack(String name)------------注意:   将三个fragmnet添加到回退栈中,调用该方法,传入的name值可以不同,这里基本没有意义,可以直接传入null。
                当前边的都是通过replace().addToBackStack(String stackName)--的时候添加的时候,此时,第二个fragment被添加的时候,第一个Fragment执行的onpause()--onstop--ondestroyView(),然后第一个fragment就处于这个状态了,之后的就以此类推;当开始回退的时候,从第四个fragment开始回退到第三个fragment的时候,此时第四个frament执行的方法是(onpause(0--onstop()---ondestroyView()---ondestroy()--ondetach()),第三个fragment执行的方法是(oncreateView()---onactivityCreated()----onstart()---onresume()),之后的就以此类推。
                当Fragment都是通过add().addToBackStack(String stackName)的时候添加的时候,此时,第二个fragment被添加的时候,第一个Fragmnet什么都不执行,而是一直处于onresume()状态,而第二个fragment执行的方法是onAttach()--onCreate()---onCreateView()---onActivityCreated()--onstart()---onResume().;当开始回退的时候,从第四个Fragment回退到第三个Fragment的时候,此时第四个Fragment执行的方法是onpause()-----onstop----ondestoryView()---ondestroy()----onDetach(),第三个fragment还是什么方法都不执行。
                当fragment前两个是通过add().addToBackStack(String stackName)添加,第三个是通过replace().addToBackStack(String stackName)--的时候添加,当添加第三个fragment的时候,此时第一个和第二个都会执行其本身fragmen相应的方法(onpause()--onstop---ondestroyView())方法,而第三个Fragment执行的则是(onAttach(0--onCreate()---onCreateView()---onActivityCreated()--onstart()---onResume());当从第三个回退到第二个的时候,此时第三个fragment执行的方法是(onpause()-----onstop----ondestoryView()---ondestroy()----onDetach()),然后执行的第一个和第二个Fragment相应的方法(onCreaeView()--onactivityCreated()---onstart()--onResume());从第二个Fragment回退到第一个Fragment的时候,此时第二个Fragment执行的(onpause()-----onstop----ondestoryView()---ondestroy()----onDetach()),第一个Fragemnt则是什么都不执行。
                重点:当使用该方法addToBackStack(String name)往activity中添加了一个fragment,此时在在内存就存在一个回退栈了,当我们点击回退键的时候,系统首先销毁回退栈中的那个Fragment,当回退栈中的fragment已经没有的时候,此时点击返回键就会直接销毁activity和不在回退栈中的所有的Fragment。
                          例子:当第一个,第二个,第三个fragment都是通过add()方法添加到activity的且没有使用addToBackStack()方法,此时第四个fragment是通过replace()添加的,                                            而且调用了addToBackStack()方法,此时第一次点击回退键,就会销毁第四个fragment,返回到第三个fragment;然后在点击返回键,就直接销毁这个actiivty                                            和所有的fragment了

               注意:当replace方法同时调用过了addToBackStack()方法的时候,此时这个replace对前面的fragment,不管是使用add还是repalce添加的,不管是不是调用的addbacktostack方法,前面的fragmnet执行的生命周期方法都是(onpause-----onstop------ondestroyView()),区别在于如果是通过add添加fragment,replace+addbacktostack的fragment在回退的时候,add所有的fragment都会执行(oncreateView---onactivityCreate---onstart---onresume),而replac方法添加的fragtment则是推到那个fragment,执行那个frament的(oncreateview---onactivitycreate---onstart----onresume).;在回退的时候,主要是判断回退栈中是否还有fragment对象,如果有,则返回上一个fragment,如果没有则直接执行activity的finish()方法。



          6.什么时候用add()方法,什么时候用replace()方法?
                    初步判断,当用户点击返回键,想要显示之前得页面(用户在该页面上做了一些操作)      ,此时就用add()方法;否则就是replace()方法。
                    
                    
         7.乡下兼容版本的fragment和不向下兼容的Fragment的FragmentTransction的commit()只能调用一次,当第二次或者多次调用的时候,此时就会应用就会崩掉。

五Fragment的压栈出栈

? ? ? ? ? ?<1`>.第一种方式:使用add()+addToBackStack()

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <1.1>注意点

			<1> 为了保证activity在最后一个回退的时候,当前的activity的xml中FrameLayout位置有一个fragment,所以第一个添加到activity中的fragment就不能使用addToBackStack()方法
           	<2>如果想要点击回退键在回退fragment的时候,保证之前的fragment页面的内容(有用户输入的信息),就要使用add()方法;如果想要在点击回退键回退fragment的时候,让之前的fragment在重新走一次oncreateView()---onActivityCreated()--onstart()--onresume()方法,此时就要使用replace()方法。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1.2>代码实例

public class FragmentOneActivity extends Activity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private ArrayList<BaseFragment> arrayList = new ArrayList<>();
    private FragmentManager fragmentManager;
    BlueFragment blueFragment = new BlueFragment();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("qindong", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        getFragmentTransition();
        //第一次添加的fragment没有使用addToBackStack()方法
        ShowBlueFragmentOne();
    }
    
    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        //0.创建相应的Fragment对象(这个类的内容无关紧要)
        RedFragment redFragment = new RedFragment();
        redFragment.setLogName("RedFragment:");
        //1.获取到相应的fagnmentManager对象,注意此时使用的getSupportFragmentManager()方法
//        FragmentManager supportFragmentManager = getSupportFragmentManager();
        //2.开启FragmentManager对象的事务管理器
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
        //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
        fragmentTransaction.add(R.id.fl_frameLayout_content, redFragment, "redFragment").addToBackStack(null);
        //4.向fragment事务管理器提交,创建fragment
        fragmentTransaction.commit();
    }

    private void ShowGreenFragment() {
        GreenFragment greenFragment = new GreenFragment();
        greenFragment.setLogName("greenFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, greenFragment, "GreenFragment").addToBackStack(null);
        fragmentTransaction.commit();

    }

    private void ShowBlueFragment() {
        BlueFragment blueFragment = new BlueFragment();
        blueFragment.setLogName("blueFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, "BlueFragment").addToBackStack(null);
        fragmentTransaction.commit();
    }

    private void ShowBlueFragmentOne() {
        BlueFragment blueFragment = new BlueFragment();
        blueFragment.setLogName("blueFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, "blueFragment");
        fragmentTransaction.commit();
    }
}

? ? ? ? ? ? <2>.第二种方式:使用add()+addToBackStack()+直接重写onBackPressed()

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <1>第二种方法和第一种方法的区别:

<1>不用设置第一个添加到activity的fragment对象不能使用addToBackStack()方法.
                <2>直接重写onBackProgress()方法,判断当前回退栈中Fragment的数目,如果该数目>1 ,那就让回退栈继续弹栈;如果该数目<=1 ,此时直接调用该activity的finish()方法。                                                		

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <2>第二种方法之重写onBackPressed()

    @Override
    public void onBackPressed() {
        //获取当前回退栈中的fragment数目,如果为1,直接finish;如果>1,则调用方式进行弹栈
            if(getFragmentManager().getBackStackEntryCount()>1){
                getFragmentManager().popBackStack();
            }else {
                finish();
            }
    }

? ? ? ? ?<3>第三种方式:使用add()+ArrayList+重写onbackProcess()方法

? ? ? ? ? ? ? ? ? ? ? ? ? ? <3.1>注意点

  					这种方式只能保证在点击回退键回退的时候,显示的之前的fragment是用于离开时候的样子。

? ? ? ? ? ? ? ? ? ? ? ? ? ?<3.2>代码:? ?

public class FragmentOneActivity extends Activity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private ArrayList<Fragment> arrayList = new ArrayList<>();
    private FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("qindong", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        getFragmentTransition();
        ShowBlueFragmentOne();
    }

    private void getFragmentTransition() {
        fragmentManager = getFragmentManager();
    }

    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        //0.创建相应的Fragment对象
        RedFragment redFragment = new RedFragment();
        arrayList.add(redFragment);
        redFragment.setLogName("RedFragment:");
        //1.获取到相应的fagnmentManager对象,注意此时使用的getSupportFragmentManager()方法
//        FragmentManager supportFragmentManager = getSupportFragmentManager();
        //2.开启FragmentManager对象的事务管理器
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
        //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
        fragmentTransaction.add(R.id.fl_frameLayout_content, redFragment, "redFragment");
        //4.向fragment事务管理器提交,创建fragment
        fragmentTransaction.commit();

    }

    private void ShowGreenFragment() {
        GreenFragment greenFragment = new GreenFragment();
        arrayList.add(greenFragment);
        greenFragment.setLogName("greenFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, greenFragment, "GreenFragment");
        fragmentTransaction.commit();

    }

    private void ShowBlueFragment() {
        BlueFragment blueFragment = new BlueFragment();
        arrayList.add(blueFragment);
        blueFragment.setLogName("blueFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, "BlueFragment");
        fragmentTransaction.commit();

    }

    private void ShowBlueFragmentOne() {
        BlueFragment blueFragment = new BlueFragment();
        arrayList.add(blueFragment);
        blueFragment.setLogName("blueFragment:");
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, "blueFragment");
        fragmentTransaction.commit();
    }

    @Override
    public void onBackPressed() {
        
            if (arrayList.size() > 1) {
            //注意此处的getFragmentManager().beginTransaction()动态获取到transaction对象,如果是使用的是同一个Transaction对象,不能达到效果。
                //从transaction对象中移除最后一个fragment
            getFragmentManager().beginTransaction().remove(arrayList.get(arrayList.size() - 1)).commit();
                //从ArrayList集合中删除最后一个元素
            arrayList.remove(arrayList.size() - 1);
        } else {
            finish();
        }
    }
}

六Fragment的hide()和show()方法的使用? ??

? ? ? ? ? ? <6.1>.两个方法如何使用:

       //1.首先获取到FragmentManager对象
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        //2.获取到FragmentTransaction对象
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        //3.先调用hide(Fragment fragmnet)方法,隐藏当前显示的Fragment,然后调用show(Fragment frgment),显示想要显示的Fragment
        fragmentTransaction.hide(Fragment fragment).show(Fragment fragment);
        //4.提交失误
        fragmentTransaction.commit();

? ? ? ? ? ? <6.2>两个方法的使用场景

<1>之所以使用hide()和show()方法就是为了复用之前已经创建过的fragmnet对象,不再重新进行添加了,这就是目的。
        <2>hide()和show()方法的使用:
               比如说app的首页,底部有四个按钮,上边就是一个FrameLayout,点击底部的四个按钮,分别显示不同的framgnet。当我们第一次点击底部的某一个按钮的时候,
               此时肯定是调用add()或者replace()方法,将创建好的fragment对象添加到对象的FrameLayout中去;但是当用户又重新点击底部按钮的时候,此时如果使用add()
               或者replace()方法就不行了,因为这是重新创建一个新的Fragment对象添加到当前的FrameLayout中,不符合需求,需求应该是显示之前之前的Fragment,
               此时我们就需要使用hide()和show()方法了。
               hide(Fragment fragment)-------此时传入的fragmnt对象就是当前显示的Fragment的对象。
               show(Fragment fragment)------此时传入的fragment对象就是我们想要显示的再内存中已经存在的fragment对象。
               因为底部有四个按钮,分别对应着四个不同的Fragment对象,我们需要处理的只是当前显示的Fragment对象和想要显示的Fragment对象,对于其他的Fragment对象,
               我们可以不做处理的。

? ? ? ? ? ?<6.3>.模拟微信首页的形式

? ? ? ? ? ? ? ? ? ? ? ? ? ? <1> 微信首页大致原理讲解

原理:在一个页面上,页面底部有四个按钮,上边是一个FrameLayout,当我们第一次点击底部按钮的时候,创建一个Fragment并显示在Fragment上;当Fragment对象已经创建好了,此时点击底部按钮,隐藏当前的fragment,显示我们点击的按钮所对应的fangment,使用的是hide()和show()的方法。

? ? ? ? ? ? ? ? ? ? <2>微信首页具体的代码

<1>这是Activity中的代码

            public class FragmentOneActivity extends FragmentActivity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private FragmentManager fragmentManager;
    private String RedFragmentTag = "RedFragment";
    private String BlueFragmentTag = "BlueFragment";
    private String GreenFragmentTag = "GreenFragment";
    private String CurrentFragmentTag = "";
    private RedFragment redFragment;
    private GreenFragment greenFragment;
    private BlueFragment blueFragment;

    private HashMap<Integer, String> hashMap = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        getFragmentTransition();
        ShowBlueFragment();
    }

    private void getFragmentTransition() {
        fragmentManager = getSupportFragmentManager();
    }

    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
               //redFragment!=null判断是不是第一次显示该Fragment,如果是第一次的话,底下的代码就不用显示了。
            if (frament != null && redFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (redFragment == null ) {
            //0.创建相应的Fragment对象
            redFragment = new RedFragment();
            //2.开启FragmentManager对象的事务管理器
            //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
            //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
            fragmentTransaction.add(R.id.fl_frameLayout_content, redFragment, RedFragmentTag);   
        } else {
                  fragmentTransaction.show(redFragment).
        }
        
        CurrentFragmentTag = RedFragmentTag;
        fragmentTransaction.commit();
    }


    private void ShowGreenFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            //greenFragment!=null判断是不是第一次显示该Fragment,如果是第一次的话,底下的代码就不用显示了。
            if (frament != null && greenFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }

        if (greenFragment == null || greenFragment.isMyDetach() ) {
            greenFragment = new GreenFragment();
            fragmentTransaction.add(R.id.fl_frameLayout_content, greenFragment, GreenFragmentTag);
        } else {
            fragmentTransaction.show(greenFragment);
        }
        
       CurrentFragmentTag = GreenFragmentTag;
        fragmentTransaction.commit();
    }

    private void ShowBlueFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();


        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            if (frament != null&& blueFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (blueFragment == null ) {
            blueFragment = new BlueFragment();
            fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, BlueFragmentTag);
        } else {
            fragmentTransaction.show(blueFragment);
        }
        
        CurrentFragmentTag = BlueFragmentTag;
        fragmentTransaction.commit();
    }
    
}

<2>这是Activity对应的xml布局文件:

相应的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/fl_frameLayout_content"
        android:layout_width="match_parent"
        android:layout_height="400dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="这是默认显示的内容" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_red"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="红色" />

        <Button
            android:id="@+id/bt_green"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="绿色" />

        <Button
            android:id="@+id/bt_blue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="蓝色" />
    </LinearLayout>

</LinearLayout>


<3>这是三个Fragment的代码:


public class RedFragment extends Fragment {

    @Nullable
    @Override
    //该方法用于实例化fragment的用户界面(该方法返回一个view)
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","RedFragment:"+"onCreateView");
        View view = inflater.inflate(R.layout.fragment_home, null);
        return view;
    }
}

public class GreenFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","GreenFragment:"+"onCreateView");
        View view=inflater.inflate(R.layout.fragment_green,null);
        return view;
    }
}

public class BlueFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","BlueFragment:"+"onCreateView");
        View view=inflater.inflate(R.layout.fragment_blue,null);
        return view;
    }
}

? ? ? ? ? ? ? ? ? ? ? ? ? ? <6.4>正常的使用(将所有的fragment添加到了回退栈中,这种场景我暂时没有见过****不太重要,有时间了再看吧):

  主要思想:使用CurrentFragmentTag变量记录当前显示的Fragment对应的tag,然后通过findViewByTag()来获取Fragment
                    
            
            
            public class FragmentOneActivity extends FragmentActivity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private FragmentManager fragmentManager;
    private String RedFragmentTag = "RedFragment";
    private String BlueFragmentTag = "BlueFragment";
    private String GreenFragmentTag = "GreenFragment";
    private String CurrentFragmentTag = "";
    private RedFragment redFragment;
    private GreenFragment greenFragment;
    private BlueFragment blueFragment;

    private HashMap<Integer, String> hashMap = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("qindong", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        getFragmentTransition();
        ShowBlueFragment();
    }

    private void getFragmentTransition() {
        fragmentManager = getSupportFragmentManager();
    }

    @Override
    protected void onStart() {
        Log.d("qindong", "onStart");
        super.onStart();
    }

    @Override
    protected void onResume() {
        Log.d("qindong", "onResume");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d("qindong", "onPause");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d("qindong", "onStop");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d("qindong", "onDestroy");
        super.onDestroy();
    }


    @Override
    protected void onRestart() {
        Log.d("qindong", "onRestart");
        super.onRestart();
    }

    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
               //redFragment!=null判断是不是第一次显示该Fragment,如果是第一次的话,底下的代码就不用显示了。
            if (frament != null && redFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (redFragment == null || redFragment.isMyDetach() ) {
            //0.创建相应的Fragment对象
            redFragment = new RedFragment();
            redFragment.setLogName("RedFragment:");
            //2.开启FragmentManager对象的事务管理器
            //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
            //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
            fragmentTransaction.add(R.id.fl_frameLayout_content, redFragment, RedFragmentTag).addToBackStack("");   
        } else {
                  fragmentTransaction.show(redFragment).
        }
        
        CurrentFragmentTag = RedFragmentTag;
        fragmentTransaction.commit();
    }


    private void ShowGreenFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            //greenFragment!=null判断是不是第一次显示该Fragment,如果是第一次的话,底下的代码就不用显示了。
            if (frament != null && greenFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }

        if (greenFragment == null || greenFragment.isMyDetach() ) {
            greenFragment = new GreenFragment();
            //这一句无关紧要,是自己写的,有关打印log的东西。
            greenFragment.setLogName("greenFragment:");
            fragmentTransaction.add(R.id.fl_frameLayout_content, greenFragment, GreenFragmentTag).addToBackStack("");
        } else {
            fragmentTransaction.show(greenFragment);
        }
        
       CurrentFragmentTag = GreenFragmentTag;
        fragmentTransaction.commit();
    }

    private void ShowBlueFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();


        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            if (frament != null&& blueFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (blueFragment == null || blueFragment.isMyDetach()) {
            blueFragment = new BlueFragment();
            blueFragment.setLogName("blueFragment:");
            fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, BlueFragmentTag).addToBackStack("");
        } else {
            fragmentTransaction.show(blueFragment);
        }
        
        CurrentFragmentTag = BlueFragmentTag;
        fragmentTransaction.commit();
    }

    @Override
    public void onBackPressed() {
        if (fragmentManager.getBackStackEntryCount() > 1) {
            fragmentManager.popBackStack();
        } else {
            finish();
        }
    }
}


相应的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/fl_frameLayout_content"
        android:layout_width="match_parent"
        android:layout_height="400dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="这是默认显示的内容" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_red"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="红色" />

        <Button
            android:id="@+id/bt_green"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="绿色" />

        <Button
            android:id="@+id/bt_blue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="蓝色" />
    </LinearLayout>

</LinearLayout>


相应的Frgment:
public class RedFragment extends BaseFragment {

    @Nullable
    @Override
    //该方法用于实例化fragment的用户界面(该方法返回一个view)
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","RedFragment:"+"onCreateView");
        View view = inflater.inflate(R.layout.fragment_home, null);
        return view;
    }
}

public class GreenFragment extends BaseFragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","GreenFragment:"+"onCreateView");
        View view=inflater.inflate(R.layout.fragment_green,null);
        return view;
    }
}

public class BlueFragment extends BaseFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("qindong","BlueFragment:"+"onCreateView");
        View view=inflater.inflate(R.layout.fragment_blue,null);
        return view;
    }
}


这是BaseFragment:

public class BaseFragment extends Fragment {

    public String mFragmentName;
    public void setLogName(String fragmentName){
        mFragmentName=fragmentName;
    }
    public ArrayList<BaseFragment> arrayList=new ArrayList<>();
    @Override
    public void onAttach(Context context) {
        Log.d("qindong",mFragmentName+"onAttach");
        arrayList.add(this);
        super.onAttach(context);

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        Log.d("qindong",mFragmentName+"onCreate");
        super.onCreate(savedInstanceState);
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        Log.d("qindong",mFragmentName+"onActivityCreated");
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        Log.d("qindong",mFragmentName+"onStart");
        super.onStart();
    }

    @Override
    public void onResume() {
        Log.d("qindong",mFragmentName+"onResume");
        super.onResume();
    }

    @Override
    public void onPause() {
        Log.d("qindong",mFragmentName+"onPause");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.d("qindong",mFragmentName+"onStop");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        Log.d("qindong",mFragmentName+"onDestroyView");
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        Log.d("qindong",mFragmentName+"onDestroy");
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        Log.d("qindong",mFragmentName+"onDetach");
        arrayList.remove(this);
        super.onDetach();
    }
}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <6.5>在项目4中出现了一个问题,解决方法如下(这个也不太重要,当有充足时间的时候,再看这个):

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <1>出现的问题和解决的方法:

            /**
             * 此时会出现一个问题,那就是用户点击了返回键进行回退的时候,然后又重新点击一个按钮,去显示一个Fragment,那么此时出现一个问题:
             *          按钮对应的方法中想要显示的Fragment对象,并没有显示出来,界面依旧是我们原来的Fragment
             *
             *    原因分析: 当用户点击回退的时候,当前显示的Fragment对应的CurrentFragmentTag应该发生变化,但是由于我们再回退的时候,没有对
             *                      CurrentFragmentTag作处理,所以此时的CurrentFragmentTag是用户点击返回键已经销毁或者准备销毁(当时已经执行了onDetch()方法)的那个fragment对象的tag,
             *              而此时通过CurrentFragmentTag找到的Fragment对象就已经是错的的,因为当执行了onDatch()方法之后,这个fragment对象不一定就马上销毁,所以这里有两种情况:
             					<1>这个fragment没有马上销毁,此时我们找到了这个fragment对象,并执行了hide()方法,由于当前显示的fragment并不是我们找到的这个fragment,所以hide不会起作用,后边的show也就无法起作用了。
                                <2>这个fragment马上销毁了,此时我们没有找到这个fragment对象,那么此时压根就不会执行hide()方法,那么当前显示的fragment也是不会隐藏。
                            所以这里的方法如下:
                            		<1>纠正CurrentFragmentTag的值,这个动作在onBackPressed()方法中做,当用户点击返回键的时候,直接获取到回退栈中的倒数第二个fragment的tag值,然后赋值给CurrentFragmentTag即可。
                                    <2>解决一种情况,当用户点击返回键,从当前的fragmentA退回到上一个fragmnetB中,但是又点击导航按钮要显示FragmentA,此时由于FragmentA对象不知道存在不存在(因为Fragment并不一定在执行了onDeatch()方法之后立即被垃圾回收器回收),当这个FragmentA的对象不存在的时候,此时原来的代码就可以正常运行;但是当这个FragmentA的对象存在的时候,此时这个原来的代码就不能正常运行了,因为执行了onDeatch()方法的Fragment对象是不会执行show()方法,所以这里需要在重新创建一个FragmentA的对象,面对这种情况的解决方案:在每一个底部导航按钮的点击事件中,增加一个判断,即将执行了onDeatch方法的Fragment对象视同已经被销毁的Fragment对象。
        if (redFragment == null || redFragment.isMyDetach() ) {
      				...
        } else {
      			    ...
        }
                                
                                
                                
             *
             *    解决方法:  1.redFragment.isMyDetach()是自己写的方法,当Fragment执行了onDetach()方法后,该方法返回是true,其他时间返回false。
             *                      因为当Fragment对象执行了onDetach()方法之后,该Fragment对象并不是立即为null的。
             *               2.首先在每一次使用add方法进行添加Fragment对象的时候,将对应的id为key,将tag作为value,存入到hashMap中。
             *                  在onBackProcess()方法中,获取到当前显示的Fragment对应的id值,然后从hashMap根据id值,取出相应的tag值   
             *               3.使用redFragment.isMyDetach()方法判断该Fragment对象是否经过了onDetach()方法,如果调用了这个方法,那么此时就去重新为
             *                      Fragment创建对象。
             *             
             *                      
             * */ 

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<2>全部的代码:

发生改变的东西:就是acivity和baseFragment

这是activity:

public class FragmentOneActivity extends FragmentActivity {

    private Button bt_red;
    private Button bt_green;
    private Button bt_blue;
    private FrameLayout fl_content;
    private FragmentManager fragmentManager;
    private String RedFragmentTag = "RedFragment";
    private String BlueFragmentTag = "BlueFragment";
    private String GreenFragmentTag = "GreenFragment";
    private String CurrentFragmentTag = "";
    private RedFragment redFragment;
    private GreenFragment greenFragment;
    private BlueFragment blueFragment;

    private HashMap<Integer, String> hashMap = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("qindong", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_one);
        initView();
        initEvent();
        getFragmentTransition();
        ShowBlueFragment();
    }

    private void getFragmentTransition() {
        fragmentManager = getSupportFragmentManager();
    }

    @Override
    protected void onStart() {
        Log.d("qindong", "onStart");
        super.onStart();
    }

    @Override
    protected void onResume() {
        Log.d("qindong", "onResume");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d("qindong", "onPause");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d("qindong", "onStop");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d("qindong", "onDestroy");
        super.onDestroy();
    }


    @Override
    protected void onRestart() {
        Log.d("qindong", "onRestart");
        super.onRestart();
    }

    private void initView() {
        bt_red = (Button) findViewById(R.id.bt_red);
        bt_green = (Button) findViewById(R.id.bt_green);
        bt_blue = (Button) findViewById(R.id.bt_blue);
        fl_content = (FrameLayout) findViewById(R.id.fl_frameLayout_content);
    }

    private void initEvent() {
        bt_red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowRedFragment();
            }
        });
        bt_green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowGreenFragment();
            }
        });
        bt_blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ShowBlueFragment();
            }
        });
    }


    private void ShowRedFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            /**
             * 此时会出现一个问题,那就是用户点击了返回键进行回退的时候,然后又重新点击一个按钮,去显示一个Fragment,那么此时出现一个问题:
             *          按钮对应的方法中想要显示的Fragment对象,并没有显示出来,界面依旧是我们原来的Fragment
             *
             *    原因分析: 当用户点击回退的时候,当前显示的Fragment对应的CurrentFragmentTag应该发生变化,但是由于我们再回退的时候,没有对
             *                      CurrentFragmentTag作处理,所以此时的CurrentFragmentTag是已经点击返回键已经销毁的那个fragment对象的tag,
             *              而此时我们通过findFragmentByTag找到的Fragment对象为null,是进入不到方法中,进行hide()方法的调用的。
             *
             *    解决方法:  1.redFragment.isMyDetach()是自己写的方法,当Fragment执行了onDetach()方法后,该方法返回是true,其他时间返回false。
             *                      因为当Fragment对象执行了onDetach()方法之后,该Fragment对象并不是立即为null的。
             *               2.首先在每一次使用add方法进行添加Fragment对象的时候,将对应的id为key,将tag作为value,存入到hashMap中。
             *                  在onBackProcess()方法中,获取到当前显示的Fragment对应的id值,然后从hashMap根据id值,取出相应的tag值   
             *               3.使用redFragment.isMyDetach()方法判断该Fragment对象是否经过了onDetach()方法,如果调用了这个方法,那么此时就去重新为
             *                      Fragment创建对象。
             *               4.       
             *                      
             * */           
            if (frament != null && redFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (redFragment == null || redFragment.isMyDetach() ) {
            //0.创建相应的Fragment对象
            redFragment = new RedFragment();
            redFragment.setLogName("RedFragment:");
            //2.开启FragmentManager对象的事务管理器
            //3.调用事物管理器中的方法replace()或者add(),将fragment对象添加到当前的activity中,并指定其要替换的xml中的控件的id
            //该方法的第三个参数为这个Fragment的tag,可以根据findFragmentByTag(String tag);来获取相应的Fragment对象。
            fragmentTransaction.add(R.id.fl_frameLayout_content, redFragment, RedFragmentTag).addToBackStack("");
            CurrentFragmentTag = RedFragmentTag;
            //4.向fragment事务管理器提交,创建fragment
            int id = fragmentTransaction.commit();
            hashMap.put(id, RedFragmentTag);
        } else {
            CurrentFragmentTag = RedFragmentTag;
            fragmentTransaction.show(redFragment).commit();
        }
    }


    private void ShowGreenFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            if (frament != null && greenFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }

        if (greenFragment == null || greenFragment.isMyDetach() ) {
            greenFragment = new GreenFragment();
            greenFragment.setLogName("greenFragment:");
            fragmentTransaction.add(R.id.fl_frameLayout_content, greenFragment, GreenFragmentTag).addToBackStack("");

            CurrentFragmentTag = GreenFragmentTag;
            //4.向fragment事务管理器提交,创建fragment
            int id = fragmentTransaction.commit();
            hashMap.put(id, GreenFragmentTag);
        } else {
            CurrentFragmentTag = GreenFragmentTag;
            fragmentTransaction.show(greenFragment).commit();
        }
    }

    private void ShowBlueFragment() {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();


        if (!CurrentFragmentTag.isEmpty()) {
            Fragment frament = fragmentManager.findFragmentByTag(CurrentFragmentTag);
            if (frament != null&& blueFragment!=null) {
                fragmentTransaction.hide(frament);
            }
        }
        if (blueFragment == null || blueFragment.isMyDetach()) {
            blueFragment = new BlueFragment();
            blueFragment.setLogName("blueFragment:");
            fragmentTransaction.add(R.id.fl_frameLayout_content, blueFragment, BlueFragmentTag).addToBackStack("");
            CurrentFragmentTag = BlueFragmentTag;
            //4.向fragment事务管理器提交,创建fragment
            int id = fragmentTransaction.commit();
            hashMap.put(id, BlueFragmentTag);
        } else {
            CurrentFragmentTag = BlueFragmentTag;
            fragmentTransaction.show(blueFragment).commit();
        }
    }

    @Override
    public void onBackPressed() {
        if (fragmentManager.getBackStackEntryCount() > 1) {
            //获取到当前显示的fragmnt对应的entity,注意索引为fragmentManager.getBackStackEntryCount() - 2
            FragmentManager.BackStackEntry backStackEntryAt = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 2);
            //获取到当前显示的fragment对应的id值
            int id = backStackEntryAt.getId();
            CurrentFragmentTag=hashMap.get(id);
            fragmentManager.popBackStack();
        } else {
            finish();
        }
    }
}


这是BaseFragment:
    
public class BaseFragment extends Fragment {

    public String mFragmentName;
    //添加了一个标签,用于判断该Fragment是否调用了onDetach()方法。
    public boolean isMyDetach;
    public void setLogName(String fragmentName){
        mFragmentName=fragmentName;
        mFragmentName=fragmentName;
    }
    public ArrayList<BaseFragment> arrayList=new ArrayList<>();
    @Override
    public void onAttach(Context context) {
        Log.d("qindong",mFragmentName+"onAttach");
        arrayList.add(this);
        isMyDetach=false;
        super.onAttach(context);

    }

    public boolean isMyDetach(){
        return isMyDetach;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        Log.d("qindong",mFragmentName+"onCreate");
        super.onCreate(savedInstanceState);
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        Log.d("qindong",mFragmentName+"onActivityCreated");
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        Log.d("qindong",mFragmentName+"onStart");
        super.onStart();
    }

    @Override
    public void onResume() {
        Log.d("qindong",mFragmentName+"onResume");
        super.onResume();
    }

    @Override
    public void onPause() {
        Log.d("qindong",mFragmentName+"onPause");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.d("qindong",mFragmentName+"onStop");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        Log.d("qindong",mFragmentName+"onDestroyView");
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        Log.d("qindong",mFragmentName+"onDestroy");
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        Log.d("qindong",mFragmentName+"onDetach");
        arrayList.remove(this);
        isMyDetach=true;
        super.onDetach();
    }
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-25 08:13:48  更:2021-11-25 08:15:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:32:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码