Bootstrap

Activity中使用Fragment

本讲内容:Fragment的使用

Fragment是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。


一、创建一个Fragment

继承Fragment类,重写生命周期方法,需要重写一个onCreateView()方法来返回这个Fragment的布局。


示例一:在一个活动当中添加两个碎片,并让这两个碎片平分活动空间(静态加载)


下面是res/layout/left_fragment.xml 布局文件:

[java]   view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <Button  
  8.         android:id="@+id/button"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center_horizontal"  
  12.         android:text="Button" />  
  13.   
  14. </LinearLayout>  

下面是res/layout/right_fragment.xml 布局文件:

[java]   view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#0f0"  
  6.     android:orientation="vertical" >  
  7.   
  8.      <TextView  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center_horizontal"  
  12.         android:text="This is right fragment"  
  13.         android:textSize="20sp" />  
  14.   
  15. </LinearLayout>  


下面是LeftFragment.java文件:

[java]   view plain  copy
  1. public class LeftFragment extends Fragment {  
  2.   
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  4.         // 通过LayoutInflater的inflate()方法将定义的布局动态加载进来并转换成View对象  
  5.         /** 
  6.          * resource:Fragment需要加载的布局文件 
  7.          * root:加载布局文件的父ViewGroup 
  8.          * attactToRoot:false为不返回父ViewGroup 
  9.          */  
  10.         View view = inflater.inflate(R.layout.left_fragment, container, false);  
  11.         return view;  
  12.     }  
  13. }  

下面是Right Fragment .java文件:

[java]   view plain  copy
  1. public class RightFragment extends Fragment{  
  2.       
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  4.         View view=inflater.inflate(R.layout.right_fragment, container, false);  
  5.         return view;  
  6.     }  
  7. }  

下面是res/layout/activity_main.xml 布局文件:

[java]   view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <fragment  
  7.         android:id="@+id/left_fragment"  
  8.         android:name="com.example.fragmenttest.LeftFragment"  
  9.         android:layout_width="0dp"  
  10.         android:layout_height="match_parent"  
  11.         android:layout_weight="1" />  
  12.   
  13.     <fragment  
  14.         android:id="@+id/right_fragment"  
  15.         android:name="com.example.fragmenttest.RightFragment"  
  16.         android:layout_width="0dp"  
  17.         android:layout_height="match_parent"  
  18.         android:layout_weight="1" />  
  19.   
  20. </LinearLayout>  

下面是MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends Activity {  
  2.     protected void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         setContentView(R.layout.activity_main);  
  5.     }  
  6. }  


注意:如果Fragment引用的包是:import android.support.v4.app.Fragment;  Activity必须是继承FragmentActivity



示例二:动态添加碎片(在示例一基础上修改)

动态添加碎片步骤:(对Fragment进行添加add()、移除remove()、替换replace()。)

1、创建待添加的碎片实例。

2、获取FragmentManager,调用getFragmentManager()方法得到。

3、开启一个事务,通过调用beginTransaction()方法开启。

4、向容器加入碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。

5、提交事务,调用commit()方法来完成。


点击按钮


下面是res/layout/another_right_fragment.xml 布局文件:

[java]   view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#ff0"  
  6.     android:orientation="vertical" >  
  7.   
  8.      <TextView  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center_horizontal"  
  12.         android:text="This is another right fragment"  
  13.         android:textSize="20sp" />  
  14.   
  15. </LinearLayout>  

下面是 AnotherRightFragment .java文件:

[java]   view plain  copy
  1. public class AnotherRightFragment extends Fragment{  
  2.       
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  4.         //通过LayoutInflater的inflate()方法将定义的布局动态加载进来  
  5.         View view=inflater.inflate(R.layout.another_right_fragment, container, false);  
  6.         return view;  
  7.     }  
  8. }  

下面是res/layout/activity_main.xml 布局文件:

[java]   view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <fragment  
  7.         android:id="@+id/left_fragment"  
  8.         android:name="com.example.fragmenttest.LeftFragment"  
  9.         android:layout_width="0dp"  
  10.         android:layout_height="match_parent"  
  11.         android:layout_weight="1" />  
  12.   
  13.     <FrameLayout  
  14.         android:id="@+id/right_layout"  
  15.         android:layout_width="0dp"  
  16.         android:layout_height="match_parent"  
  17.         android:layout_weight="1" >  
  18.   
  19.         <fragment  
  20.             android:id="@+id/right_fragment"  
  21.             android:name="com.example.fragmenttest.RightFragment"  
  22.             android:layout_width="match_parent"  
  23.             android:layout_height="match_parent" />  
  24.     </FrameLayout>  
  25.   
  26. </LinearLayout>  

下面是MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends Activity implements OnClickListener{  
  2.     private Button button;  
  3.       
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         button=(Button) findViewById(R.id.button);  
  8.         button.setOnClickListener(this);  
  9.     }  
  10.   
  11.     public void onClick(View v) {  
  12.         switch (v.getId()) {  
  13.         case R.id.button:  
  14.             AnotherRightFragment fragment=new AnotherRightFragment();//创建待添加碎片  
  15.             FragmentManager manager=getFragmentManager();//获取FragmentManager  
  16.             FragmentTransaction transaction=manager.beginTransaction();//开启一个事务  
  17.             transaction.replace(R.id.right_layout, fragment);//向容器加入碎片  
  18.             transaction.commit();//提交事务  
  19.             break;  
  20.         default:  
  21.             break;  
  22.         }  
  23.     }  
  24. }  

示例三:在碎片中模拟返回栈

在示例二,我们通过点击按钮添加一个碎片后,这时按下Back键程序就会直接退出。如果我们想模仿类似于返回栈的效果,按下Back键可以返回到上一个碎片,这时就要用到FragmentTransaction中提供一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,它可以接收一个名字用于描述返回栈的状态,一般传入null即可。

修改下MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends Activity implements OnClickListener{  
  2.     private Button button;  
  3.       
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         button=(Button) findViewById(R.id.button);  
  8.         button.setOnClickListener(this);  
  9.     }  
  10.   
  11.     public void onClick(View v) {  
  12.         switch (v.getId()) {  
  13.         case R.id.button:  
  14.             AnotherRightFragment fragment=new AnotherRightFragment();//创建待添加碎片  
  15.             FragmentManager manager=getFragmentManager();//获取FragmentManager  
  16.             FragmentTransaction transaction=manager.beginTransaction();//开启一个事务  
  17.             transaction.replace(R.id.right_layout, fragment);//向容器加入碎片  
  18.             transaction.addToBackStack(null);  
  19.             transaction.commit();//提交事务  
  20.             break;  
  21.         }  
  22.     }  
  23. }  


二、碎片和活动之间进行通信

1、在活动中调用碎片里的方法

FragmentManager提供了一个findFragmentById()或findFragmentByTag()方法,可以在活动中得到相应碎片的实例,然后就能调用该碎片里的方法了。

[java]   view plain  copy
  1. RightFragment rightFragment=(RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);  
2、在碎片里调用活动中的方法

在每个碎片中都可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例,如下

[java]   view plain  copy
  1. MainActivity activity=(MainActivity) getActivity()  
有了活动实例之后,就可以在碎片里调用活动里的方法了。


示例四:Activity向Fragment(动态加载)传递数据

在Activity中创建Bundle数据包,并调用Fragment的setArguments()方法

 

下面是res/layout/first_fragment.xml 布局文件:

[java]   view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/id_text"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:textSize="25sp" />  
  12.   
  13. </LinearLayout>  

下面是FirstFragment.java文件:

[java]   view plain  copy
  1. public class FirstFragment extends Fragment {  
  2.     private TextView tv;  
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  4.         View view=inflater.inflate(R.layout.first_fragment, container,false);  
  5.         //注意通过view.findv,否则报错  
  6.         tv=(TextView) view.findViewById(R.id.id_text);  
  7.         String text=getArguments().get("name")+"";  
  8.         tv.setText(text);  
  9.         Toast.makeText(getActivity(), "Fragment接收到"+text, Toast.LENGTH_LONG).show();  
  10.         return view;  
  11.     }  
  12. }  


下面是res/layout/activity_main.xml 布局文件:

[java]   view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:id="@+id/layout"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <EditText  
  9.         android:id="@+id/id_edit"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:hint="输入数据" />  
  13.   
  14.     <Button  
  15.         android:id="@+id/id_send"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="发送" />  
  19.   
  20. </LinearLayout>  

下面是MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends FragmentActivity {  
  2.     private EditText edit;  
  3.     private Button send;  
  4.       
  5.     protected void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.activity_main);  
  8.         initViews();  
  9.     }  
  10.   
  11.     private void initViews() {  
  12.         edit=(EditText) findViewById(R.id.id_edit);  
  13.         send=(Button) findViewById(R.id.id_send);  
  14.         send.setOnClickListener(new OnClickListener() {  
  15.             public void onClick(View v) {  
  16.                 String text=edit.getText().toString();  
  17.                 FirstFragment fragment=new FirstFragment();  
  18.                 Bundle bundle=new Bundle();  
  19.                 bundle.putString("name", text);  
  20.                 fragment.setArguments(bundle);  
  21.                   
  22.                 //向activity_main布局文件中动态加载Fragment  
  23.                 FragmentManager manager=getFragmentManager();  
  24.                 FragmentTransaction transaction=manager.beginTransaction();  
  25.                 transaction.add(R.id.layout, fragment);  
  26.                 transaction.commit();  
  27.                   
  28.                 Toast.makeText(MainActivity.this"Activity-->Fragment发送数据", Toast.LENGTH_LONG).show();  
  29.             }  
  30.         });  
  31.     }  
  32. }  


示例五:Activity向Fragment(静态加载)传递数据

 

下面是res/layout/first_fragment.xml 布局文件:

[java]   view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/id_text"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:textSize="25sp"  
  12.         android:text="静态加载fragment:" />  
  13.       
  14.     <Button   
  15.         android:id="@+id/button"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="获取"/>  
  19.   
  20. </LinearLayout>  


下面是FirstFragment.java文件:

[java]   view plain  copy
  1. public class FirstFragment extends Fragment {  
  2.     private Button b;  
  3.     private String data;  
  4.       
  5.       
  6.     public String getData() {  
  7.         return data;  
  8.     }  
  9.   
  10.   
  11.     public void setData(String data) {  
  12.         this.data = data;  
  13.     }  
  14.   
  15.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  16.         View view=inflater.inflate(R.layout.first_fragment, container,false);  
  17.         b=(Button) view.findViewById(R.id.button);  
  18.         b.setOnClickListener(new OnClickListener() {  
  19.             public void onClick(View v) {  
  20.                 data=getData();  
  21.                 Toast.makeText(getActivity(), "data="+data, Toast.LENGTH_SHORT).show();  
  22.             }  
  23.         });  
  24.           
  25.         return view;  
  26.     }  
  27. }  

下面是res/layout/activity_main.xml 布局文件:

[java]   view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:id="@+id/layout"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <EditText  
  9.         android:id="@+id/id_edit"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:hint="输入数据" />  
  13.   
  14.     <Button  
  15.         android:id="@+id/id_send"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="发送" />  
  19.       
  20.     <fragment   
  21.         android:id="@+id/first_fragment"  
  22.         android:name="com.example.fragmentdemo.FirstFragment"  
  23.         android:layout_width="wrap_content"  
  24.         android:layout_height="wrap_content"/>  
  25.   
  26. </LinearLayout>  

下面是MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends FragmentActivity {  
  2.     protected void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         setContentView(R.layout.activity_main);  
  5.         initViews();  
  6.     }  
  7.   
  8.     private void initViews() {  
  9.         FragmentManager manager=getFragmentManager();  
  10.         Fragment fragment = manager.findFragmentById(R.id.first_fragment);  
  11.         FirstFragment firstFragment=(FirstFragment) fragment;  
  12.         firstFragment.setData("Activity向Fragment发送数据");  
  13.     }  
  14. }  

示例六:Fragment向Activity传递数据

Fragment-->Activity:需要在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现回调接口。这样Fragment可调用该回调方法将数据传递给Activity

 

下面是FirstFragment.java文件:

[java]   view plain  copy
  1. public class FirstFragment extends Fragment {  
  2.     private Button b;  
  3.       
  4.     private String data="Thank you,Activity!";  
  5.     private ISendData sendData;  
  6.       
  7.     interface ISendData{  
  8.         void send(String data);  
  9.     }  
  10.       
  11.     /** 
  12.      * 当Fragment被添加到Activity时候会回调这个方法,并且只调用一次  
  13.      */  
  14.     public void onAttach(Activity activity) {  
  15.         sendData=(ISendData) activity;  
  16.         super.onAttach(activity);  
  17.     }  
  18.       
  19.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
  20.         View view=inflater.inflate(R.layout.first_fragment, container,false);  
  21.         b=(Button) view.findViewById(R.id.button);  
  22.         b.setOnClickListener(new OnClickListener() {  
  23.             public void onClick(View v) {  
  24.                 Toast.makeText(getActivity(), "Fragment向Activity发送"+data, Toast.LENGTH_SHORT).show();  
  25.                 sendData.send(data);                  
  26.             }  
  27.         });  
  28.         return view;  
  29.     }  
  30. }  

下面是MainActivity.java主界面文件:

[java]   view plain  copy
  1. public class MainActivity extends FragmentActivity implements ISendData{  
  2.       
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_main);  
  6.     }  
  7.   
  8.     public void send(String data) {  
  9.         Toast.makeText(MainActivity.this"已成功接收到" + data + ",客气了!",Toast.LENGTH_SHORT).show();  
  10.     }  
  11. }  
;