文章地址: http://blog.youkuaiyun.com/guolin_blog/article/details/8881711
Fragment----碎片
1. Fragment的设计哲学:
Fragment的使用就便于平板和手机软件之间相互转换:
1.Fragment通常是嵌套在Activity中使用的。
第一步:需要给Fragment创建一个与之对应的布局文件如fragment.xml,这个布局文件中的内容当然是由你自己随意写的啦!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is fragment 2"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout>
第二步:要新建一个 Fragment1 类去继承Fragment,在下面你inflate中引用了我们第一步创建的布局fragment.xml:
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
}
}
第三步:就是将这个Fragment1通过name属性添加到某个活动的布局文件中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
<fragment
android:id="@+id/fragment1"
android:name="com.example.fragmentdemo.Fragment1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
这样只要在活动中引用该布局就可以用了。是不是很简单啊。而且是在活动中直接对Fragment对应的那个布局中的控件进行实例化和操作!!!!!!就好像中间直接越过了fragment。
Fragment的一些特点:
2.Fragment可以实现在同一个Activity中嵌套多个Fragment
只要在某个活动的布局文件中多添加几个<fragment>标签就好了。
3.并且在同一个Activity中,多个Fragment彼此之间的通信是通过getActivity这个方法实现的。
例如我们在fragment2中想要获取fragment1中的id为button的按钮的实例,就可以这样写:
Button button = (Button) getActivity().findViewById(R.id.button);
这样就可以在后续的代码中对button进行各种操作:
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Button button =(Button) getActivity().findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextView textView = (TextView) getActivity().findViewById(R.id.fragment1_text);
Toast.makeText(getActivity(), textView.getText(), Toast.LENGTH_LONG).show();
}
});
}
}
还有另外一种用于Fragment与Activity之间的通信:用Bundle方法啦!
参考的地方,我懒得搬来搬去了:Fragment与Activity通信
32. MyFragment5 fragment5 = new MyFragment5();
33. Bundle bundle = new Bundle();
34. bundle.putString("name", text);// 用这个方法从Activity给Fragment发送信息,信息名称为name
35. fragment5.setArguments(bundle);// Fragment从这里向Activity接收信息
36. FragmentManager fragmentManager = getFragmentManager();// 动态创建Fragment。
37. FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
38. beginTransaction.add(R.id.layout,fragment5,"fragment5");
39. beginTransaction.commit();
40. Toast.makeText(MainActivity4.this, "向Fragment发送数据"+text, Toast.LENGTH_SHORT).show();
4.动态添加Fragment:
举例一:
这里注释一下,下面的R.id.frame是一个LinearLayout的id名称。
35. MyFragment2 fragment2 = new MyFragment2();// 实例化
36. FragmentManager fragmentManager = getFragmentManager();
37. FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
38. // 第一个参数是说你要把fragment2加载到布局ID的控件中,例子中frame在main布局文件中定义的LinearLayout。
39. // 第二个参数是说
40. beginTransaction.add(R.id.frame, fragment2);// 这里是指,把fragment2加到前面LinearLayout中。
41. beginTransaction.addToBackStack(null); // 返回键就可以返回了。
42. beginTransaction.commit();
举个二,我们现在在活动的布局文件中什么都不添加,只有一个LinearLayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
</LinearLayout>
然后在活动中修改代码:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Display display = getWindowManager().getDefaultDisplay();
if (display.getWidth() > display.getHeight()) {// 用来检测横屏还是竖屏的,随后直接进行替换。
Fragment1 fragment1 = new Fragment1();
getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit();
} else {
Fragment2 fragment2 = new Fragment2();
getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit();
}
}
}
动态加载Fragment共有四步:
1.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。
2.开启一个事务,通过调用beginTransaction方法开启。
3.向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例。
4.提交事务,调用commit方法提交。
5.Fragment的生命周期:
public class Fragment1 extends Fragment {
public static final String TAG = "Fragment1";
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(TAG, "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public ViewonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
return inflater.inflate(R.layout.fragment1, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public void onDetach(){
super.onDetach();
Log.d(TAG, "onDetach");
}
}
- onAttach方法:Fragment和Activity建立关联的时候调用。
- onCreateView方法:为Fragment加载布局时调用。
- onActivityCreated方法:当Activity中的onCreate方法执行完后调用。
- onDestroyView方法:Fragment中的布局被移除时调用。
- onDetach方法:Fragment和Activity解除关联的时候调用。
6. 下面关于郭霖博客的另一篇关于Fragment的文章,由于看的时候感觉类太多脑子不够用,所以下面自己画了一个简单的关系图以方便自己日后查看:
文章地址:http://blog.youkuaiyun.com/guolin_blog/article/details/8744943这篇博客的内容主要讲的是如何让一个活动在手机和平板之间自动做出选择来显示应有的布局页面,这样做的好处是,当需求分析变化时,我们只需要修改一次代码就可以了,便于代码的维护,下面直接上郭大侠的图:
那么下面我放一张我梳理后的结构图:
主要的代码在这里:
44. /**
45. * 当Activity创建完毕后,尝试获取一下布局文件中是否有details_layout这个元素,如果有说明当前
46. * 是双页模式,如果没有说明当前是单页模式。
47. */
48. @Override
49. public void onActivityCreated(Bundle savedInstanceState) {
50. super.onActivityCreated(savedInstanceState);
51. if (getActivity().findViewById(R.id.details_layout) != null) {
52. isTwoPane = true;
53. } else {
54. isTwoPane = false;
55. }
56. }
57.
58. /**
59. * 处理ListView的点击事件,会根据当前是否是双页模式进行判断。如果是双页模式,则会动态添加Fragment。
60. * 如果不是双页模式,则会打开新的Activity。
61. */
62. @Override
63. public void onItemClick(AdapterView<?> arg0, View view, int index, long arg3) {
64. if (isTwoPane) {
65. Fragment fragment = null;
66. if (index == 0) {
67. fragment = new SoundFragment();
68. } else if (index == 1) {
69. fragment = new DisplayFragment();
70. }
71. getFragmentManager().beginTransaction().replace(R.id.details_layout, fragment).commit();
72. } else {
73. Intent intent = null;
74. if (index == 0) {
75. intent = new Intent(getActivity(), SoundActivity.class);
76. } else if (index == 1) {
77. intent = new Intent(getActivity(), DisplayActivity.class);
78. }
79. startActivity(intent);
80. }
81. }
82.
83.}