? 目录
一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();
}
}
|