`

用Fragments在Android中进行多窗格开发

 
阅读更多

本文翻译于vogella.com

 

在Android应用程序中使用Fragments

这篇教程描述了怎样在Android 应用程序中使用Fragment类来创建多窗格布局,也就是可以缩放到设备的可用宽度的应用程序。它基于Eclipse 4.3(Kepler),Java1.6和Android4.4。

 

1.Android基础

下面的描述假设了你已经掌握了基本的Android开发知识。

请查看Android开发教程来学习基础知识。也可以看Android开发教程来获取更多的关于Android开发的信息。

2.Fragments

2.1 什么是Fragments?

fragment是一个可以被Activity使用的独立的部件。Fragment将功能进行封装所以它更见易于被重用在actvities和layouts之中。

fragment运行在一个Activity的Context中,但拥有它自己的生命周期以及作为特色的用户界面。也可以定义没有用户界面的fragment,也就是headless fragment。

Fragment可以被动态或者静态地添加到一个Activity中。

2.2 使用fragment的好处

Fragment使在不同的布局中重用部件变的容易,例如,你可以为创建单窗格的手机布局和多窗格的平板布局。这没有限制到平板设备上;例如,你也可以使用fragment在智能手机上来支持横屏和竖屏的不同布局。

典型的例子是一个Activity中展示item的一个列表。在平板设备上如果你在item上点击,你可以立即在同一块屏幕的右侧看到item的详情。在智能手机上你会跳转到一个新的详情界面。下面的图片就描述了这些。



 接下来的讨论将假设你有两个fragment(main和detail),你也可以有更多。我们将会有一个main activity和一个detailed activity。在平板上main activity的布局中包含两个fragment,在手持设备上只包含main fragment。

下面的截图表明了这样的用法。


 2.3 如何使用fragment

用fragment创建不同的布局,你可以:

 

  • 使用一个activity,平板上显示两个fragment。在这种情况下你将在任何必要的时候在activity中切换fragment。这就需要fragment不能声明在layout文件中因为那样的fragment不能在运行期间被移除。
  • 在手机上使用各自的activity来持有每一个fragment。例如,但平板电脑UI在一个activity中使用两个fragment的时候,在手机上使用同一个activity,但提供一个可供选择的仅包含一个fragment的布局。当你需要切换fragment,启动另一个持有其他fragment的activity。
第二种途径是最灵活的,通常也是使用fragment的最好方式。在这样的情况下main activity检查在布局中detail fragment是否是可用的。如果detailed fragment存在,mian activity会告诉fragment,它应当自己更新自己。如果detail fragment不可用,main activity就启动detailed activity。

3. fragment生命周期

fragment的生命周与持有它的activity的生命周期相关联。



 表 1. Fragment 生命周期



 

4. 定义和使用Fragment

4.1 定义Fragment

定义一个新的fragment,你要么继承android.app.fragment类要么一个它的子类,例如,ListFragment,DialogFragment,PreferenceFragment或者WebViewFragment。下面的代码展示了一种实现。

package com.example.android.rssfeed;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class DetailFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rssitem_detail,
        container, false);
    return view;
  }

  public void setText(String item) {
    TextView view = (TextView) getView().findViewById(R.id.detailsText);
    view.setText(item);
  }
} 

 4.2 静态添加Fragment

使用你的新的fragment,你可以静态地将它添加到XML布局中。

检查fragment是否已经是你的布局的一部分,你可以使用FragmentManager类。

DetailFragment fragment = (DetailFragment) getFragmentManager().
  findFragmentById(R.id.detail_frag);
if (fragment==null || ! fragment.isInLayout()) {
  // start new Activity
  }
else {
  fragment.update(...);
} 

 如果fragment定义在XML布局文件中,那么android:name属性指向对应的类。

4.3 Fragment生命周期

Fragment有它自己的生命周期。但是它总是与用这个fragment的activity的生命周期有联系。

onCreate()方法在activity的onCreate方法之后但在fragment的onCreateView()方法之前被调用。

一旦fragment应该创建它的用户界面时,onCreateView()方法就被Android调用。这里你可以通过这个方法传递来的Inflator对象调用inflate()方法来inflate布局。在headless fragment中没有必要去实现这个方法。

当宿主activity创建完毕,在onCreateView()方法之后,onActivityCreate()方法就会被调用。这个方法里,你可以实例化那些需要Context对象的对象。

Fragment不是Context的子类,你必须使用getActivity()方法来得到parent activity。

一旦fragment可见了,onStart()方法将被调用。

如果一个activity停止了(stop),它的fragment也会停掉;如果一个activity被销毁了,它的fragment也就销毁掉了。

4.4 应用与fragment通信

为了增加fragment的重用,他们不应当直接与彼此通信。fragment的每一次通信的完成都应该通过它的宿主activity。

为了这个目的,fragment应该定义一个内部接口并要求那些用这个fragment的activity必须实现这个接口。这种方式下你就避免了fragment对用它的activity有任何认识。在它的onAttach()方法中可以检查activity是否正确地实现了这个接口。

例如,假设你有一个应该传递一个值给它的父activity的fragment。这样的情形可以像下面那样实现。

package com.example.android.rssfeed;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class MyListFragment extends Fragment {

  private OnItemSelectedListener listener;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rsslist_overview,
        container, false);
    Button button = (Button) view.findViewById(R.id.button1);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        updateDetail();
      }
    });
    return view;
  }

  public interface OnItemSelectedListener {
    public void onRssItemSelected(String link);
  }

  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof OnItemSelectedListener) {
      listener = (OnItemSelectedListener) activity;
    } else {
      throw new ClassCastException(activity.toString()
          + " must implemenet MyListFragment.OnItemSelectedListener");
    }
  }

  @Override
  public void onDetach() {
    super.onDetach();
    listener = null;
  }

  // may also be triggered from the Activity
  public void updateDetail() {
    // create a string just for testing
    String newTime = String.valueOf(System.currentTimeMillis());

    // inform the Activity about the change based
    // interface defintion
    listener.onRssItemSelected(newTime);
  }
} 

5. fragment中的数据保持

5.1 保持应用重新启动之间的数据

在fragment中,你也需要保存你的应用数据。鉴于此你可以保持你的数据在一个中心位置。例如,

  • SQLite数据库
  • File文件
  • Application对象,这种情况下,应用需要处理存储。

5.2 保持配置改变之间的数据

如果你想要保持数据在配置改变的时候,你也可以使用application对象。

另外,你也可以调用在fragment的setRetainState(true)方法。配置改变之间的这个保留的fragment实例只在fragment没有被添加到backstack才会有效。对那些有用户界面的fragment,Google不推荐使用这个方法。在这种情况下数据必须保存为成员变量。

如果Bundle类支持那些应该被保存的数据,你也可以使用onSaveInstanceState()方法来放置数据到Bundle里,在onActivityCreated()方法恢复这些数据。

6. 在运行时修改Fragment

FragmentManager和FragmentTransaction类可以让你添加,移除以及替换你的activity布局中的fragment。

Fragment可以通过事务被动态地修改。动态地添加一个fragment到一个已存在的布局中,你通常地在XML布局文件中定义一个容器,在其中添加你的fragment。为了达到这样的效果你可以使用,例如,一个FrameLayout元素。

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.your_placehodler, new YourFragment());
ft.commit(); 

 一个新的Fragment将会替换掉之前添加到容器里的已存在的Fragment。

如果你想添加事务到Android的backstack,你可以使用addToBackStack()方法。这将会添加动作到activity的历史stack中,也就是这将允许通过返回键还原Fragment的改变。

7. Fragment过渡动画

在fragment事务处理间你可以通过setCustonAnimations()方法定义应该被基于属性动画API使用的动画。

你也可以通过setTransition()方法的调用使用几个由Android提供的标准的动画。这些通过常量开头于FragmentTransation.TRANSITION_FRAGMENT_*的方式定义的。

两个方法都允许你来定义一个条目动画和一个已存在的动画。

8. 添加Fragment事务到backstack

你可以添加一个FragmentTransaction到backstack来让用户使用返回键来还原(或回滚)事务。

为了达到此目的你可以使用FragmentTransaction对象的addToBackStack()方法。

9. 进行后台处理的Fragment

9.1 Headless Fragment

Fragment可以不定义用户界面来使用。

来实现一个headless fragment,简单地在你的fragment中onCreateView()方法中返回null就行。

Tip:推荐联合着setRetainInstance方法来使用headless fragment进行后台处理。这种方式下你在你的异步处理期间你自己不必处理配置变化。

9.2 保留的headless fragment来处理配置改变

Headless fragment通常用来在经历配置改变的时候封装一些数据或者后台处理任务。为了这样的目的你应将你的headless fragment设置成保留的。一个保留的fragment在配置改变期间不会被销毁。

 

设置你的fragment被保留,调用它的setRetainInstance()方法。

添加这样的fragment到一个activity中,你要使用FragmentManager类中的add()方法。如果你以后需要找到这个Fragment,你需要给它添加一个tag来做到可以用FragmentManger类的findFragmentByTag()方法查找到。

注意:onRetainNonConfigurationInstance()的用法已经弃用了,应该用保留的headless fragment来代替。

  • 大小: 20.4 KB
  • 大小: 7.2 KB
  • 大小: 22 KB
  • 大小: 65.3 KB
  • 大小: 16.6 KB
分享到:
评论

相关推荐

    Android Fragments

    在Android中,可以轻松地在Fragments中集成对话框,从而增强应用的功能性和用户体验。 - **创建对话框**:介绍如何创建和显示对话框,包括简单的提示对话框和自定义对话框。 - **使用对话框进行交互**:讨论如何使...

    Android 管理Activity中的fragments

    在Android开发中,管理Activity中的Fragments是构建复杂用户界面的关键。Fragments是可重用的UI组件,可以在Activity的不同部分展示独立的功能。本篇将深入讲解如何利用FragmentManager有效地管理和控制Fragment。 ...

    Android Fragments 使用的一些建议demo

    在Android应用开发中,Fragments是重要的组件,用于构建可重用、动态的用户界面,尤其是在平板电脑和大屏幕设备上。本示例"Android Fragments 使用的一些建议demo"提供了一些最佳实践,帮助开发者更高效地使用...

    [Android] 动态 UI 开发教程 Android Fragments 实现 英文版

    [Packt Publishing] 动态 UI 开发教程 Android Fragments 实现 英文版 [Packt Publishing] Creating Dynamic UI with Android Fragments E Book ☆ 图书概要:☆ Leverage the power of Android fragments to ...

    android-tutorial, 在android中,特性动画和 Fragments 教程.zip

    android-tutorial, 在android中,特性动画和 Fragments 教程 Android教程这里项目包含两个部分。 属性动画与 fragment 在Android中的应用。属性动画一个简单而完整的演示,可以在安卓中实现。 获取更多信息在 ...

    谈谈Android Fragments 详细使用

    Android Fragments 是Android开发中的一个重要概念,自Android 3.0(API级别11)引入,主要用于解决不同屏幕尺寸设备上的UI适配问题。Fragments 提供了一种灵活的方式来构建动态和可重构的用户界面,特别是在平板...

    android sdk3.0 activity 之子 fragments

    在Android开发中,Activity是应用程序的基本构建块,它负责与用户进行交互。然而,随着大屏幕设备的普及,单个Activity往往无法满足复杂的界面布局需求。此时,Fragments的引入成为了解决方案的关键。Fragment是一个...

    Creating.Dynamic.UI.with.Android.Fragments.2nd.Edition.1785889

    Create engaging apps with fragments to provide a rich user interface that dynamically adapts to the individual characteristics of your customers' tablets and smartphones About This Book From an ...

    fragments游戏框架

    Fragments可以被看作是应用程序中的一个片段,它可以被多个Activity所共享,并且能够根据不同的设备特性进行动态调整。 #### 二、Fragments 的定义与作用 **1. 定义** Fragments本质上是Activity的一部分,它们...

    nested fragments

    在Android开发中,Fragments是构建用户界面的重要组成部分,特别是在设计大屏幕如平板电脑的应用时。"Nested Fragments"是Android SDK提供的一种高级特性,允许我们在一个Fragment内部嵌套其他Fragment,极大地增强...

    使用Fragments取代tabActivity开发网易新闻客户端框架

    在Android应用开发中,随着平台的发展和用户需求的多样化,传统的TabActivity已经逐渐被淘汰,取而代之的是更灵活、功能更强的Fragments。本文将深入探讨如何利用Fragments构建一个类似网易新闻客户端的框架。 **...

    Creating Dynamic UI with Android Fragments - Second Edition 2016 {PRG}.pdf

    通过阅读《使用Android Fragments创建动态UI》第二版,开发者可以深入理解Fragment的使用,并掌握如何利用这一强大的工具来构建高性能、适应性强的用户界面,从而提升开发的应用在市场中的竞争力。

    fragments

    在IT行业中,尤其是在Android开发领域,"Fragments"是一个至关重要的概念。Fragment是Android系统提供的一种组件,它允许开发者在应用程序中实现更复杂的界面布局和交互。Fragment最初被引入是为了应对大屏幕设备,...

    Android--Fragments基础

    在Android开发中,Fragments是实现复杂用户界面的重要组件,特别是在平板电脑和大屏幕设备上。Fragments允许我们在一个活动中包含多个独立的UI部分,每个部分可以有自己的生命周期和交互逻辑。下面将详细介绍...

    Android-Depth给你的fragments添加一些Depth

    在Android应用开发中,Fragments是构建用户界面的重要组成部分,特别是在设计适应不同屏幕尺寸和设备的界面时。"Android-Depth给你的fragments添加一些Depth"这个项目旨在帮助开发者为他们的Fragment实现更丰富的...

    Android App开发入门范例程序

    - fragments:用于构建可重用的UI模块,可以在多个活动中使用。 - Intent和Intent Filter:用于启动其他组件和服务,如跳转到其他活动或启动服务。 10. **FlagAPI**:这可能是练习或示例代码中使用的特定API,...

Global site tag (gtag.js) - Google Analytics