本文围绕以下三个部分展开:
一、Fragment 碎片 / 帧 / 片段
二、两个案例
(一)、静态 Fragment
附 代码补充
(二)、动态 Fragment
附 代码补充
一、Fragment 碎片 / 帧 / 片段
1.Fragment 碎片 / 帧 / 片段
从 android 3.0 进入 Fragment 的概念,目的是在不同类型屏幕下实现 UI 的动态和灵活设计。
由于 Fragment 有独立的生命周期及可用复用,所以在设计复杂 UI 时(Tab 导航、 ViewPager 及 抽屉导航)应用极为广泛。
创建 Activity 的时候,需要完成三步:1.XxxActivity ; 2. activity_Xxx.xml ; 3.在功能清单中注册。最后,在 Activity 之间还要实现跳转。
Fragment 是轻量级的 Activity ,不需要在功能清单中注册。
2.Fragment 生命周期
3.Fragment 相关类
(1)android.app.Fragment
(2)android.app.FragmentManager
Fragment 管理器,用于管理与当前活动关联的 Fragment .
(3)android.app.FragmentTransaction
Fragment 事务,开始一系列的 Fragment 操作。
二、两个案例
案例(一)、静态 Fragment
打开App后,默认主界面如下:
当左边点击“Android”的时候,右边碎片正中间出现“Android”:
同样,当点击其他项的时候,右边碎片正中间出现对应的内容:
(1)创建 碎片 : LeftFragment & fragment_left.xml , RightFragment & fragment_right.xml 。
(2)写两个碎片的内容。
fragment_left.xml:一个ListView。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xiangdong.staticfragment.LeftFragment">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
fragment_right.xml:一个TextView。默认界面是在正中间显示本app的名字:“StaticFragment”。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light"
tools:context="com.xiangdong.staticfragment.RightFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/app_name"
android:textColor="@android:color/white"/>
</RelativeLayout>
<!--
代码说明:
(1)因为这两个碎片都会被调用,因此都要写 id。
(2)android:background="@android:color/holo_blue_light"
设置背景色为:浅蓝色。
(3)android:textAppearance="?android:attr/textAppearanceLarge"
一种大字体的格式。
-->
(3)写主布局文件:activity_main.xml。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<!--
主界面上,显示两个 碎片(帧/片段) 界面
-->
<fragment
android:id="@+id/leftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.xiangdong.staticfragment.LeftFragment"
tools:layout="@layout/fragment_left"/>
<fragment
android:id="@+id/rightFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.xiangdong.staticfragment.RightFragment"
tools:layout="@layout/fragment_right"/>
</LinearLayout>
<!--
代码说明:
(1)主布局文件上,左右各放一个碎片,因此用 LinearLayout,方向需设为 水平。
android:orientation="horizontal"
(2)android:name="com.xiangdong.staticfragment.LeftFragment"
主布局文件 与 LeftFragment 关联。
tools:layout="@layout/fragment_left"
主布局文件 与 fragment_left 关联。
-->
(4)主活动:MainActivity 。创建的时候,就会有以下代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载主布局文件,就会加载两个碎片界面。(在配置文件中,布局文件与Activity关联了)
setContentView(R.layout.activity_main);
}
(5)LeftFragment。调用 onAttach() 方法:在 Fragment 与 Activity 关联时。
/**
* Fragment 与 Activity 关联时调用
* @param activity
*/
@Override
public void onAttach(Activity activity) {
// 2. 关联时,会调用这个方法
super.onAttach(activity);
// 获得活动的引用
if(activity instanceof OnFragmentListener){
// 2.1 活动实现了监听器,即可回调活动中的方法
callback = (OnFragmentListener) activity;
}
}
//-----Fragment 与 Activity 传递参数------------------------------------
private OnFragmentListener callback;
}
代码说明:
主活动要实现此碎片中定义的内部接口:
public class MainActivity extends Activity implements LeftFragment.OnFragmentListener{}
(6)LeftFragment。调用 onCreate() 方法:创建 Fragment 时调用,主要用来初始化数据(准备好要用的数据)。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
data = new ArrayList<>();
data.add("Android");
data.add("IOS");
data.add("Web");
data.add("C");
data.add("C#");
data.add("C++");
}
(7)LeftFragment。调用 onCreateView() 方法:画界面。
// 加载 Fragment 视图 (界面出来了)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment 填充指定布局文件
View view = inflater.inflate(R.layout.fragment_left, container, false);
adapter = new ArrayAdapter<String>(this.getActivity(),
android.R.layout.simple_list_item_1, data);
listView = (ListView) view.findViewById(R.id.listView);
listView.setAdapter(adapter);
// 注册监听事件:设置当前(我自己)即可。
listView.setOnItemClickListener(this);
return view;
}
代码说明:
simple_list_item_1 :有一个控件。一次只显示一行。
simple_list_item_2 :有两个控件。一次显示二行。
simple_list_item_activated_1 : 有一个控件。当选项选中时,背景色改变(即为激活状态)
simple_list_item_activated_2 : 有两个控件。当选项选中时,背景色改变(即为激活状态)
(8)MainActivity。获得碎片管理器,管理两个碎片。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获得 Fragment 管理器 (这两个碎片都被 MainActivity管了)
FragmentManager fm = this.getFragmentManager();
leftFragment = (LeftFragment)fm.findFragmentById(R.id.leftFragment);
rightFragment = (RightFragment) fm.findFragmentById(R.id.rightFragment);
}
(9)LeftFragment。写此碎片的事件处理方法:点击选项的事件。
/**
* Fragment 中的事件处理方法
* @param parent
* @param view
* @param position
* @param id
*/
// 在 Fragment 中点击选项 (Fragment 要先实现 AdapterView.OnItemClickListener 接口)
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 点击的文本 :要传给Activity
String text = data.get(position);
// 调用回调(Activity)中的方法
// callback 是 MainActivity的实例,因此它做事情,就是在 MainActivity 中做事情
callback.onItemClick(text);
}
代码说明:
此处,通过 callback 这个 MainActivity的实例,主布局已经获得了左边碎片要传递的值:text 。
Fragment 实现 AdapterView.OnItemClickListener 接口:
public class LeftFragment extends Fragment implements AdapterView.OnItemClickListener{}
(10)MainActivity。主布局要获得 左边的碎片 中的数据(通过调用 LeftFragment 内部接口定义的回调方法,获得 LeftFragment 中点击选项的文本)
/**
* LeftFragment 内部接口定义的回调方法
* @param text
*/
@Override
public void onItemClick(String text) {
// 获得 LeftFragment 中点击的选项的文本
rightFragment.displayContent(text);
}
其中, LeftFragment 内部接口定义的回调方法如下:
//-----Fragment 与 Activity 传递参数------------------------------------
private OnFragmentListener callback;
/**
* 从 Fragment 往 Activity 传递数据 : 通过调用内部的接口去传。
* 1. 在 Fragment 中定义接口 (内部接口)
* 2. Activity 实现 Fragment 中定义的接口
*/
interface OnFragmentListener {
// 点击当前 Fragment 中控件,回调的方法
void onItemClick(String text);
}
代码说明:
此处,通过 rightFragment 这个 右边碎片的对象,来调用 右边碎片的displayContent()方法,右边碎片就获得了左边碎片传递给主布局的值:text。
(11)RightFragment。右边的碎片 从主布局中已经获得了数据,在此定义 displayContent() 方法,让数据(文本:text)在右边碎片界面上面显示。
// 让文字在控件上面显示
public void displayContent(String text){
// 显示文本
tvContent.setText(text);
}
附 代码补充
1. fragment_left.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xiangdong.staticfragment.LeftFragment">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
2. fragment_right.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light"
tools:context="com.xiangdong.staticfragment.RightFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/app_name"
android:textColor="@android:color/white"/>
</RelativeLayout>
3. activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<!--fragment:是类型。
主界面上,显示两个 碎片(帧/片段) 界面
-->
<fragment
android:id="@+id/leftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.xiangdong.staticfragment.LeftFragment"
tools:layout="@layout/fragment_left"/>
<fragment
android:id="@+id/rightFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.xiangdong.staticfragment.RightFragment"
tools:layout="@layout/fragment_right"/>
</LinearLayout>
4. MainActivity
package com.xiangdong.staticfragment;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
/**
* Activity 实现 Fragment 中定义的接口
*/
public class MainActivity extends Activity implements LeftFragment.OnFragmentListener {
private LeftFragment leftFragment;
private RightFragment rightFragment;
/**
* LeftFragment 内部接口定义的回调方法
*
* @param text
*/
@Override
public void onItemClick(String text) {
// 7. 获得 LeftFragment 中点击的选项的文本
rightFragment.displayContent(text);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("FRAGMENT", "activity.onCreate............");
super.onCreate(savedInstanceState);
// 1. 加载主布局文件,就会加载两个碎片界面。(在配置文件中,布局文件与Activity关联了)
setContentView(R.layout.activity_main);
// 5. 获得 Fragment 管理器 (这两个碎片都被 MainActivity管了)
FragmentManager fm = this.getFragmentManager();
leftFragment = (LeftFragment) fm.findFragmentById(R.id.leftFragment);
rightFragment = (RightFragment) fm.findFragmentById(R.id.rightFragment);
}
//----------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
5. LeftFragment
package com.xiangdong.staticfragment;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class LeftFragment extends Fragment implements AdapterView.OnItemClickListener{
private static final String TAG = "FRAGMENT";
private ListView listView;
private List<String> data;
private ArrayAdapter<String> adapter;
// 3. 创建 Fragment 时调用,主要用来初始化数据(准备好要用的数据)
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG,"onCreate............");
super.onCreate(savedInstanceState);
data = new ArrayList<>();
data.add("Android");
data.add("IOS");
data.add("Web");
data.add("C");
data.add("C#");
data.add("C++");
}
// 4.加载 Fragment 视图 (界面出来了)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 附件:看 Fragment 生命周期
Log.v(TAG,"onCreateView............");
// Inflate the layout for this fragment 填充指定布局文件
View view = inflater.inflate(R.layout.fragment_left, container, false);
// simple_list_item_1:一次只显示一行文字
adapter = new ArrayAdapter<String>(this.getActivity(),
android.R.layout.simple_list_item_1, data);
listView = (ListView) view.findViewById(R.id.listView);
listView.setAdapter(adapter);
// 注册监听事件:设置当前(我自己)即可。
listView.setOnItemClickListener(this);
return view;
}
// AdapterView.OnItemClickListener :实现的接口
/**
* Fragment 中的事件处理方法
* @param parent
* @param view
* @param position
* @param id
*/
// 6. 在 Fragment 中点击选项
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 点击的文本 :要传给Activity
String text = data.get(position);
// 调用回调(Activity)中的方法
// 6.1 callback 是 MainActivity的实例,因此它做事情,就是在 MainActivity 中做事情
callback.onItemClick(text);
}
/**
* Fragment 与 Activity 关联时调用
* @param activity
*/
@Override
public void onAttach(Activity activity) {
Log.v(TAG, "onAttach............");
// 2. 关联时,会调用这个方法
super.onAttach(activity);
// 获得活动的引用
if(activity instanceof OnFragmentListener){
// 2.1 活动实现了监听器,即可回调活动中的方法
callback = (OnFragmentListener) activity;
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.v(TAG, "onActivityCreated............");
}
//-----Fragment 与 Activity 传递参数------------------------------------
private OnFragmentListener callback;
/**
* 从 Fragment 往 Activity 传递数据 : 通过调用内部的接口去传。
* 1. 在 Fragment 中定义接口 (内部接口)
* 2. Activity 实现 Fragment 中定义的接口
*/
interface OnFragmentListener {
// 点击当前 Fragment 中控件,回调的方法
void onItemClick(String text);
}
}
6. RightFragment
package com.xiangdong.staticfragment;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class RightFragment extends Fragment {
private TextView tvContent;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment 填充指定布局文件
View view = inflater.inflate(R.layout.fragment_right, container, false);
tvContent = (TextView) view.findViewById(R.id.tvContent);
return view;
}
// 让文字在控件上面显示
public void displayContent(String text){
// 8. 显示文本
tvContent.setText(text);
}
}
案例(二)、动态 Fragment
打开app后,默认加载的是“聊天”界面:
当点击“聊天”按钮的时候,加载“聊天”界面,“聊天”字体变绿:
当点击“联系人”按钮的时候,加载“联系人”界面,“联系人”字体变绿:
当点击“朋友圈”按钮的时候,加载“朋友圈”界面,“朋友圈”字体变绿:
(1)修改 activity_main.xml 。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/headLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="@string/chat"
android:layout_weight="1"
style="@android:style/Widget.Material.Button.Borderless"/>
<Button
android:id="@+id/btnContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="@string/contact"
android:layout_weight="1"
style="@android:style/Widget.Material.Button.Borderless"/>
<Button
android:id="@+id/btnDiscover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="@string/discover"
android:layout_weight="1"
style="@android:style/Widget.Material.Button.Borderless"/>
</LinearLayout>
<LinearLayout
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/headLayout"
android:orientation="horizontal">
</LinearLayout>
</RelativeLayout>
(3)创建三个碎片: ChatFragment & fragment_chat.xml,ContactFragment & fragment_contact.xml,DiscoverFragment & fragment_discover.xml 。并在三个碎片的布局文件中填入内容。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.xiangdong.dynamicfragment.ChatFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/chat"/>
</FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.xiangdong.dynamicfragment.ContactFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/contact"/>
</FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.xiangdong.dynamicfragment.DiscoverFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/discover"/>
</FrameLayout>
(4)修改 MainActivity 。
// 声明变量
private FragmentTransaction ft; // 事务
private FragmentManager fm;
private Button btnChat;
private Button btnContact;
private Button btnDiscover;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnChat = (Button) findViewById(R.id.btnChat);
btnContact = (Button) findViewById(R.id.btnContact);
btnDiscover = (Button) findViewById(R.id.btnDiscover);
// 获得 Fragment 管理器
fm = this.getFragmentManager();
// 开启事务
ft = fm.beginTransaction();
// 使用 Fragment 替换原来的界面(替换contentLayout:原来定义的线性布局。)
ft.replace(R.id.contentLayout,new ChatFragment());
// 提交事务
ft.commit();
}
/**
* 动态 Fragment:点击了谁,下面就显示相应的界面。
* 并没有涉及 碎片之间传递数据(静态 Fragment),因此更简单些。
* @param view
*/
public void onClick(View view){
// 开启事务
ft = fm.beginTransaction();
// 动态体现在这儿
switch (view.getId()){
case R.id.btnChat:
// 使用 Fragment 替换原来的界面(替换contentLayout:原来定义的线性布局。)
ft.replace(R.id.contentLayout,new ChatFragment());
btnChat.setTextColor(Color.GREEN);
btnContact.setTextColor(Color.BLACK);
btnDiscover.setTextColor(Color.BLACK);
break;
case R.id.btnContact:
ft.replace(R.id.contentLayout,new ContactFragment());
btnChat.setTextColor(Color.BLACK);
btnContact.setTextColor(Color.GREEN);
btnDiscover.setTextColor(Color.BLACK);
break;
case R.id.btnDiscover:
ft.replace(R.id.contentLayout,new DiscoverFragment());
btnChat.setTextColor(Color.BLACK);
btnContact.setTextColor(Color.BLACK);
btnDiscover.setTextColor(Color.GREEN);
break;
}
// 提交事务
ft.commit();
}
附 代码补充
1. strings.xml
<resources>
<string name="app_name">DynamicFragment</string>
<string name="action_settings">Settings</string>
<string name="chat">聊天</string>
<string name="contact">联系人</string>
<string name="discover">朋友圈</string>
</resources>
2. activity_main.xml
3. 三个碎片的布局文件
4. MainActivity
package com.xiangdong.dynamicfragment;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
// 动态 Fragment 步骤:
// 1. 新建 Module
// 2. 修改 activity_main.xml
// 3. 创建 XxxFragment 和 fragment_Xxx.xml
// 4. 修改 MainActivity
// 4.1 声明变量
private FragmentTransaction ft; // 事务
private FragmentManager fm;
private Button btnChat;
private Button btnContact;
private Button btnDiscover;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnChat = (Button) findViewById(R.id.btnChat);
btnContact = (Button) findViewById(R.id.btnContact);
btnDiscover = (Button) findViewById(R.id.btnDiscover);
// 4.2 获得 Fragment 管理器
fm = this.getFragmentManager();
// 4.3 开启事务
ft = fm.beginTransaction();
// 4.4 使用 Fragment 替换原来的界面(替换contentLayout:原来定义的线性布局。)
ft.replace(R.id.contentLayout,new ChatFragment());
// 4.5 提交事务
ft.commit();
}
/**
* 动态 Fragment:点击了谁,下面就显示相应的界面。
* 并没有涉及 碎片之间传递数据(静态 Fragment),因此更简单些。
* @param view
*/
public void onClick(View view){
// 4.3 开启事务
ft = fm.beginTransaction();
// 动态体现在这儿
switch (view.getId()){
case R.id.btnChat:
// 4.4 使用 Fragment 替换原来的界面(替换contentLayout:原来定义的线性布局。)
ft.replace(R.id.contentLayout,new ChatFragment());
btnChat.setTextColor(Color.GREEN);
btnContact.setTextColor(Color.BLACK);
btnDiscover.setTextColor(Color.BLACK);
break;
case R.id.btnContact:
ft.replace(R.id.contentLayout,new ContactFragment());
btnChat.setTextColor(Color.BLACK);
btnContact.setTextColor(Color.GREEN);
btnDiscover.setTextColor(Color.BLACK);
break;
case R.id.btnDiscover:
ft.replace(R.id.contentLayout,new DiscoverFragment());
btnChat.setTextColor(Color.BLACK);
btnContact.setTextColor(Color.BLACK);
btnDiscover.setTextColor(Color.GREEN);
break;
}
// 4.5 提交事务
ft.commit();
}
//------------------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}