开发环境: Android 2.x
1 创建平板模拟器
在项目中点击 shift + F9, 这时会弹出模拟器选择框, 点击 Create New Virtual Device:
模拟器选择框
选择 Tablet, 尽量选大屏的模拟器哟, 因为这样看的清楚:
选择平板
一路 next, 最后点击运行我们刚创建的平板模拟器:
平板模拟器
2 基本用法
我们在一个活动当中添加两个碎片, 并让这两个碎片平分这个活动空间
首先新建一个左侧碎片布局:
- <?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">
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:text="按钮"></Button>
- </LinearLayout>
这个布局非常简单, 只放置了一个按钮, 并让它水平居中显示接着新建右侧碎片布局:
- <?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:background="#00a000"
- android:orientation="vertical">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:text="我是右边的碎片"
- android:textSize="25sp"
- android:textColor="#ffffff"
- />
- </LinearLayout>
这个布局把背景色设置为深绿色, 并放置了一个 TextView 用于显示一段文本
接着新建一个继承自 Fragment 的类注意, 这里会有两个不同包下的 Fragment 类供选择, 一个是系统内置的 android.app.Fragment, 一个是 support-v4 库中的
android.support.v4.app.Fragment
强烈建议使用 support-v4 库中的 Fragment, 因为它可以让碎片在所有 Android 系统版本中保持功能一致哟! 因为 appcomcat-v7 库会把 support-v4 库一起引入进来, 所以我们不必在 gradle 中引入这个库
- LeftFragment :
- public class LeftFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.left_fragment, container, false);
- }
- }
这里仅仅是重写了 Fragment 的 onCreateView() 方法, 然后在这个方法中通过 LayoutInflater 的 inflate() 方法将刚刚定义的 fragment_left 布局动态加载进来而已接着我们用同样的方法创建来 RightFragment 类:
- public class RightFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.right_fragment, container, false);
- }
- }
修改主活动类的布局文件:
- <?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="horizontal">
- <fragment
- android:id="@+id/left_fragment"
- android:name="net.deniro.android.fragmenttest.LeftFragment"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <fragment
- android:id="@+id/right_fragment"
- android:name="net.deniro.android.fragmenttest.RightFragment"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- </LinearLayout>
这里使用了 <fragment> 标签用于在布局中添加碎片, 通过 android:name 属性来显式指明要添加的碎片类名, 注意一 定要是类的全名哦 O(_)O~
碎片示例
2 动态添加碎片
碎片真正的强大之处在于, 它可以在程序运行时动态地被添加到活动当中根据具体情况来动态地添加碎片, 就可以实现程序界面的定制功能
我们新建一个布局文件:
- <?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"
- android:background="#ffff00"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textSize="20sp"
- android:text="我是另一个右碎片"
- />
- </LinearLayout>
这个碎片只是把背景色改为黄色然后再新建一个 Fragment:
- public class AnotherRightFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.another_right_fragment, container, false);
- }
- }
在主界面中加入一个 FrameLayout:
- <?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="horizontal">
- <fragment
- android:id="@+id/left_fragment"
- android:name="net.deniro.android.fragmenttest.LeftFragment"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <FrameLayout
- android:id="@+id/right_layout"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- ></FrameLayout>
- </LinearLayout>
我们打算只放一个碎片, 因为 FrameLayout 布局中的所有控件都会默认摆放在布局的左上角, 所以这里很适合使用 FrameLayout 布局
最后修改主活动中的代码:
- public class MainActivity extends AppCompatActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- replace(new AnotherRightFragment());
- }
- });
- }
- private void replace(Fragment fragment) {
- FragmentManager manager=getSupportFragmentManager();
- FragmentTransaction transaction=manager.beginTransaction();
- transaction.replace(R.id.right_layout,fragment);
- transaction.commit();
- }
- }
我们给左侧碎片中的按钮注册了一个点击事件, 事件内部会调用 replace() 方法动态添加碎片动态添加碎片分为 5 步:
创建待添加的碎片实例
获取 FragmentManager, 在活动中可以直接调用 getSupportFragmentManager() 方法获取
开启一个事务
向容器内添加或替换碎片, 一般使用 replace() 方法实现, 需要传入容器的 id 和待添加或替换的碎片实例
提交事务
动态添加碎片
3 在碎片中模拟栈
上面, 我们实现了向活动中动态添加碎片的功能, 但通过点击按钮添加了一个碎片之后, 按下 Back 键程序就会直接退出如何才能够模拟 返回栈 的效果, 让这个示例点击两次 Back 键才会退出程序呢?
FragmentTransaction 中有一个 addToBackStack() 方法, 可以将一个事务添加到栈中, 我们修改 Activity 中的代码:
- private void replace(Fragment fragment) {
- FragmentManager manager=getSupportFragmentManager();
- FragmentTransaction transaction=manager.beginTransaction();
- transaction.replace(R.id.right_layout,fragment);
- transaction.addToBackStack(null);
- transaction.commit();
- }
4 碎片和活动之间的通信
为了方便碎片和活动之间进行通信, FragmentManager 提供了一个类似于 findViewById() 的方法, 专用于从布局文件中获取碎片的实例:
- // 从布局文件中获取碎片实例
- RightFragment rightFragment = (RightFragment) getSupportFragmentManager().findFragmentById(R.id.right_layout);
** 注意: 要使用 getSupportFragmentManager() 来获取碎片管理器哦 **
从碎片中也可以直接返回相关的活动:
- // 从碎片中调用活动
- Activity activity = rightFragment.getActivity();
另外, 如果需要在碎片中获取 Context 对象时, 也可以直接调用 getActivity(), 因为 Activity 本身就是 Context 对象啦 O(_)O 哈哈~
从活动中也可以再调用碎片实例:
- // 从活动中再调用碎片实例
- + ((AppCompatActivity) activity).getSupportFragmentManager().findFragmentById(R.id.right_layout);
这里记得向下转型为 AppCompatActivity 哦
有了上面的方法, 我们就能让碎片与碎片之间通信啦:
从 A 碎片中得到相关联的活动
通过这个活动获取 B 碎片的实例
A 碎片 关联活动 B 碎片
是不是很清楚呀 O(_)O~
来源: http://www.jianshu.com/p/3d55afd77836