一、理解
(1是从Android3.0开始新增的概念, 意为碎片。
(2、用来组建Activity界面的局部模块, 也可以说一个Actiivty界面可以由多个Fragment组成。
看下面的图,在手机上看新闻是,新闻列表然后点某一个,跳到新闻详情页,也就是从ActivityA跳转到ActivityB了。而平板电脑在一个页面ActivityA即显示了新闻列表也显示了新闻详情,它们在同一个页面上显示。新闻列表是FragmentA,新闻详情是FragmentB,也就是一个Activity可以同时显示多个Fragment。
(3其行为与Activity很相似, 有自己对应的View, 它有自己的生命周期,接收自己的输入事件,你可以添加或移除fragment从运行中的activity中。
(4)一个fragment必须总是嵌入在一个activity中,同时fragment的生命周期受activity的影响
(5本质上会产生一个FrameLayout,它加载的布局为其子布局/View
二、关于android-support-v4.jar
1、它是什么?
(1)google 提供的能兼容到api4(1.6)的兼容jar包.
(2)Android3.0(11)的SDK中添加了不少新的更强大的API供开发者使用
(3)v4包中包含了android3.0推出的一些新的API
2、为什么要用它?
(1)使用如果项目中直接使用了最新的API, 不能安装到低版本的手机中的
(2)而使用V4兼容包开发就可以安装到低版本(1.6)的手机
3、重要API
Fragment
ViewPager
4、注意
(1)在使用Fragment及其相关API时, 要导V4中定义的
(2)如何关联libs下jar包的源码
Jar包显示源码,在libs下创建jar包名字的properties文件
文件内容是源码路径:src=源码路径
src=D:\\adt-bundle-windows-x64\\android-sdk-windows\\extras\\android\\support\\v4\\src
三、相关API
1、Fragment
View onCreateView() 用来创建或加载一个视图,加载一个布局。
onActivityCreate()(当Activity创建好)。
getActivity()(宿主)得到Fragment所属于的那个Activity。
setArguments()设置参数, getArgument()得到参数,这两个方法用来数据传递
2、ListFragment(用来显示列表)
setListAdapter(adapter) 适配器
onListItemClick() 需要重写的方法,监听Item的点击事件
getFragmentManager()
3、FragmentActivity
(如果有用Fragment就不能再继承Activity,要继承FragmentActivity)
getSupportFragmentManager() 可以得到管理器FragmentManager
4、FragmentManager(管理器)
beginTransacation() 事务,开启事务后得到事务管理对象FragmentTransacation
5、FragmentTransacation
add(), replace(), remove()
commit()
addToBackStack()
四、在碎片中模拟返回栈
通过点击按钮添加了一个碎片之后,这时按下Back键程序就会直接退出。如果这里我们想模仿类似于返回栈的效果,按下Back键可以回到上一个碎片,该如何实现呢?
其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager. beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
五、碎片和活动之间进行通信
虽然碎片都是嵌入在活动中显示的,可是实际上它们的关系并没有那么亲密。
你可以看出,碎片和活动都是各自存在于一个独立的类当中的,它们之间并没有那么明显的方式来直接进行通信。如果想要在活动中调用碎片里的方法,或者在碎片中调用活动里的方法,应该如何实现呢?
为了方便碎片和活动之间进行通信,FragmentManager提供了一个类似于findViewById()的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:
RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);
调用FragmentManager的findFragmentById()方法,可以在活动中得到相应碎片的实例,然后就能轻松地调用碎片里的方法了。
掌握了如何在活动中调用碎片里的方法,那在碎片中又该怎样调用活动里的方法呢?其实这就更简单了,在每个碎片中都可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例,代码如下所示:
MainActivity activity = (MainActivity) getActivity();
有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要使用Context对象时,也可以使用getActivity()方法,因为获取到的活动本身就是一个Context对象了。
二、碎片(Fragment)之静态加载
一、Fragment的静态加载
1. 定义Fragment的子类, 并在onCreateView()中加载一个布局文件
2. 在布局文件中通过<fragment>指定指定自定义Fragment
3. 我们的Activity必须继承于FragmentActivity
二、实例
一个界面有两个Fragment组成
/*
* 测试使用Fragment(静态加载)
* 1. 定义Fragment的子类, 并加载一个布局文件
* 2. 在布局文件中通过<fragment>指定指定自定义Fragment
* 3. 我们的Activity必须继承于FragmentActivity
* 每个Fragment本质上都会生成一个FrameLayout, 它加载的布局为其子布局
*/
public class MainActivity extends FragmentActivity{
public MainActivity() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<!--必须要指定id,不然会报错-->
<fragment
android:id="@+id/f_main_1"
android:name="com.example.animation.MyFragment1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<!--必须要指定id,不然会报错-->
<fragment
android:id="@+id/f_main_2"
android:name="com.example.animation.MyFragment2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</LinearLayout>
public class MyFragment1 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//加载布局得到View对象并返回
//创建一个视图对象, 设置数据并返回
TextView textView = new TextView(getActivity());
textView.setText("fragment11111");
textView.setBackgroundColor(Color.RED);
return textView;
}
}
public class MyFragment2 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//加载布局得到View对象并返回
//创建一个视图对象, 设置数据并返回
TextView textView = new TextView(getActivity());
textView.setText("fragment22222");
return textView;
}
}
三、碎片(Fragment)之动态加载
一、Fragment的动态加载
1. 定义Fragment的子类, 并在onCreateView()中加载一个布局文件
2. 我们的Activity必须继承于FragmentActivity
3. 在代码中, 动态创建Fragment对象, 并添加到指定的ViewGroup中
add
replace
remove
二、实例
开始时用Fragment1显示的,点击按钮把Fragment1替换成Fragment2。
/**
* 测试使用Fragment(动态使用)
* 1.使用FragmentManager和FragmentTransaction动态使用一个Fragment
* 2. 方式:
* add(viewId, fragment): 将fragment的视图添加为指定视图的子视图(加在原有子视图的后面)
* replace(viewId, fragment): 将fragment的视图添加为指定视图的子视图(先remove原有的子视图)
* remove(fragment) : 将fragment的视图移除
*
*/
public class MainActivity extends FragmentActivity {
public MainActivity() {
Log.e("TAG", "MainActivity()..");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.e("TAG", "MainActivity onCreate()..");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建Fragment对象
MyFragment1 fragment1 = new MyFragment1();
// 得到FragmentManager
FragmentManager manager = getSupportFragmentManager();
// 得到FragmentTransacation
FragmentTransaction transaction = manager.beginTransaction();
// 添加Fragment对象并提交,fragment1添加到R.id.ll_main_container容器里
transaction.add(R.id.ll_main_container, fragment1).commit();
}
private MyFragment2 fragment2;
public void showFragment2(View v) {
// 创建Fragment对象
fragment2 = new MyFragment2();
// 得到FragmentManager
FragmentManager manager = getSupportFragmentManager();
// 得到FragmentTransacation
FragmentTransaction transaction = manager.beginTransaction();
//将当前操作添加到回退栈, 这样点击back回到上一个状态,就是说现在显示fragment2点一下back回到上一次的状态fragment1。
transaction.addToBackStack(null);
// 替换Fragment对象并提交
transaction.replace(R.id.ll_main_container, fragment2).commit();
}
public void deleteFragment2(View v) {
// 得到FragmentManager
FragmentManager manager = getSupportFragmentManager();
// 得到FragmentTransacation
FragmentTransaction transaction = manager.beginTransaction();
// 移除Fragment对象并提交
transaction.remove(fragment2).commit();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="显示fragment2"
android:onClick="showFragment2"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="移除fragment2"
android:onClick="deleteFragment2"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_main_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
/*
添加Fragment对象显示
onAttach()-->onCreate()-->onCreateView()-->onActivityCreated()-->onstart()-->onResume()
home到桌面
onPause()-->onStop()
回到应用
onStart()-->onResume()
replace为其它Fragment
onPause()-->onStop()-->onDestroyView()
返回到本身的Fragment
onCreateView()-->onActivityCreated()-->onstart()-->onResume()
退出应用
onPause()-->onstop()-->onDestroyView()-->onDestroy()-->onDetach()
*/
public class MyFragment1 extends Fragment {
@Override
public void onAttach(Activity activity) {
Log.e("TAG", "onAttach()");
super.onAttach(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.e("TAG", "onCreate()");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("TAG", "onCreateView()");
//加载布局得到View对象并返回
//创建一个视图对象, 设置数据并返回
TextView textView = new TextView(getActivity());
textView.setText("fragment11111");
textView.setBackgroundColor(Color.RED);
return textView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.e("TAG", "onActivityCreated()");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.e("TAG", "onStart()");
super.onStart();
}
@Override
public void onResume() {
Log.e("TAG", "onResume()");
super.onResume();
}
@Override
public void onPause() {
Log.e("TAG", "onPause()");
super.onPause();
}
@Override
public void onStop() {
Log.e("TAG", "onStop()");
super.onStop();
}
@Override
public void onDestroyView() {
Log.e("TAG", "onDestroyView()");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.e("TAG", "onDestroy()");
super.onDestroy();
}
@Override
public void onDetach() {
Log.e("TAG", "onDetach()");
super.onDetach();
}
}
public class MyFragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//加载布局得到View对象并返回
//创建一个视图对象, 设置数据并返回
TextView textView = new TextView(getActivity());
textView.setText("fragment22222");
return textView;
}
}
四、碎片(Fragment)之Fragment的生命周期
一、Fragment的生命周期
生命周期方法
onAttach() 关联,Fragment关联到Activity上
onCreate()
onCreateView()返回一个显示的View (重要)
onActivityCreated()创建好(重要)
onStart()
onResume()
onPause()
onStop()
onDestroyView() 销毁视图
onDestroy()销毁自己
onDetach()Fragment与Activity断开关联
测试用例:
添加Fragment对象显示
home到桌面
回到应用
replace为其它Fragment
返回到本身的Fragment
退出应用
添加Fragment对象显示
onAttach()-->onCreate()-->onCreateView()-->onActivityCreated()-->onstart()-->onResume()
home到桌面
onPause()-->onStop()
回到应用
onStart()-->onResume()
replace为其它Fragment
onPause()-->onStop()-->onDestroyView()
返回到本身的Fragment
onCreateView()-->onActivityCreated()-->onstart()-->onResume()
退出应用
onPause()-->onstop()-->onDestroyView()-->onDestroy()-->onDetach()
二、 生命周期分析
1. 当一个fragment被创建的时候,它会经历以下状态.
- onAttach()
- onCreate()
- onCreateView()
- onActivityCreated()
2. 当这个fragment对用户可见的时候,它会经历以下状态。
- onStart()
- onResume()
3. 当这个fragment进入“后台模式”的时候,它会经历以下状态。
- onPause()
- onStop()
4. 当这个fragment被销毁了(或者持有它的activity被销毁了),它会经历以下状态。
- onPause()
- onStop()
- onDestroyView()
- onDestroy() // 本来漏掉类这个回调,感谢xiangxue336提出。
- onDetach()
5. 就像activitie一样,在以下的状态中,可以使用Bundle对象保存一个fragment的对象。
- onCreate()
- onCreateView()
- onActivityCreated()
6. fragments的大部分状态都和activitie很相似,但fragment有一些新的状态。
- onAttached() —— 当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。
- onCreateView() —— 当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。
- onActivityCreated() —— 当activity的onCreated()方法返回后调用此方法
- onDestroyView() —— 当fragment中的视图被移除的时候,调用这个方法。
- onDetach() —— 当fragment和activity分离的时候,调用这个方法。
一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。