Fragment和Activity类似,同样是具备UI的属性;也就是都能用于规划UI布局...

Building a Dynamic UI with Fragments --> Fragments具备有动态UI的属性。为了在Android上为用户提供动态的、多窗口的交互体验,我们需要将UI组件和Activity操作封装成模块进行使用,使得我们可以在activity中对这些模块进行切入切出操作。可以用Fragment来创建这些模块,Fragment就像一个嵌套的activity,拥有自己的布局(layout)并管理自己的生命周期。

主题一:创建Fragment

You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities).

可能使用到的 Android API:Note: If you decide that the minimum API level your app requires is 11 or higher, you don't need to use the Support Library and can instead use the framework's built in Fragment class and related APIs. Just be aware that this lesson is focused on using the APIs from the Support Library, which use a specific package signature and sometimes slightly different API names than the versions included in the platform. 支持包中的Fragment类及相关API和Android系统内置的Fragment和API有不同。若使用Android API 11以上的系统,则不需要使用支持包。

Fragment和Activity类似,都具有自己的生命周期callbacks,以及相关的逻辑;创建Fragment实例时,首先要做的是继承Fragment类,必须覆写onCreateView(),已确定其Layout(具体的UI外表);同时该方法也是唯一需要覆写以便让Fragment运行。

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ArticleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.article_view, container, false);
}
}

Just like an activity, a fragment should implement other lifecycle callbacks that allow you to manage its state as it is added or removed from the activity and as the activity transitions between its lifecycle states. Fragment从Activity中添加或移除都能够获取到系统消息,同时执行相关的Fragment系统回调方法。

比如:如果Activity执行了onPause()回调,在Activity中的Fragment会收到消息以执行onPause()。

使用.xml文件为Activity添加Fragment实例

Fragments是可重用的、模块化的UI组件,每个Fragment的实例都必须与一个FragmentActivity关联。我们可以在Activity的XML布局文件中定义每一个fragment来实现这种关联。

Note: FragmentActivity is a special activity provided in the Support Library to handle fragments on system versions older than API level 11. If the lowest system version you support is API level 11 or higher, then you can use a regular Activity. 此处的LinearLayout相当于是一个容器,用于容纳Fragment。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>

上述是一个.xml文件实例,在Activity的.xml文件中添加了两个Fragment。并通过以下手法将该.xml文件布局到Activity中:

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
}
}

P.S. 上述MainActivity继承了FragmentActivity。Note: When you add a fragment to an activity layout by defining the fragment in the layout XML file, you cannot remove the fragment at runtime.使用静态方式(在.xml文件中定义了Fragment)添加了Fragment,不能实现动态添加和移除。

主题二:创建灵活的UI组件---Fragment

Fragment的一个可能的使用场景:When designing your application to support a wide range of screen sizes, you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space.

The FragmentManager class provides methods that allow you to add, remove, and replace fragments to an activity at runtime in order to create a dynamic experience.

运行状态下添加Fragment

这种方式不同于之前的使用.xml文件方式添加Fragment,而是可以在运行时动态进行添加和移除Fragment。This is necessary if you plan to change fragments during the life of the activity.

To perform a transaction such as add or remove a fragment, you must use the FragmentManager to create a FragmentTransaction, which provides APIs to add, remove, replace, and perform other fragment transactions.

If your activity allows the fragments to be removed and replaced, you should add the initial fragment(s) to the activity during the activity's onCreate() method. 如果需要在允许其移除或更换Fragment,必须要在Activity的onCreate()回调中初始化该Fragment。

An important rule when dealing with fragments—especially when adding fragments at runtime—is that your activity layout must include a container View in which you can insert the fragment. 另外一个需要注意的地方:Activity必须包含一个能够容纳Fragment的容器。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

上述就是一个“空”容器---the fragment container

Inside your activity, call getSupportFragmentManager() to get a FragmentManager using the Support Library APIs. Then call beginTransaction() to create a FragmentTransaction and call add() to add a fragment.

You can perform multiple fragment transaction for the activity using the same FragmentTransaction. When you're ready to make the changes, you must call commit().

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
HeadlinesFragment firstFragment = new HeadlinesFragment(); // In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras()); // Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}

将Fragment实例添加到R.id.fragment_container为标识的容器中。

运行状态下替换Fragment

The procedure to replace a fragment is similar to adding one, but requires the replace() method instead of add(). 使用的是replace()而不是add()。

Keep in mind that when you perform fragment transactions, such as replace or remove one, it's often appropriate to allow the user to navigate backward and "undo" the change. To allow the user to navigate backward through the fragment transactions, you must call addToBackStack() before you commit the FragmentTransaction. 为了编译较好的用户体验,需要提供“Undo”按键,方便退回到先前状态。可使用addToBackStack()方法让Fragment入栈,以便退回到先前状态。

Note: When you remove or replace a fragment and add the transaction to the back stack, the fragment that is removed is stopped (not destroyed). If the user navigates back to restore the fragment, it restarts. If you do not add the transaction to the back stack, then the fragment is destroyed when removed or replaced. 添加到BackStack的区别。

// Create fragment and give it an argument specifying the article it should show
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();

主题三:Fragment之间的交互

为了重用Fragment UI组件,我们应该把每一个fragment都构建成完全的自包含的、模块化的组件,定义他们自己的布局与行为。定义好这些模块化的Fragment后,就可以让他们关联activity,使他们与application的逻辑结合起来,实现全局的复合的UI。

Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly. Fragment之间的交互是通过其“宿主”---Activity,而不能直接进行交互。

为了让Fragment和Activity交互,可以在Fragment中定义一个Interface。

public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity); // This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
} ...
}

Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface. Fragment --> Activity 信息流走向

或者是通过点击事件,将该事件传递到Activity中:

    @Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}

并让Activity实现该接口:OnHeadlineSelectedListener,并处理相关接口中的方法

public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
... public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
}

如何让信息从 Activity --> Fragment 中

The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods. 也就是在Activity中获取到Fragment实例,直接调用其方法即可。

public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}

Fragment基础操作的更多相关文章

  1. 札记:Fragment基础

    Fragment概述 在Fragment出现之前,Activity是app中界面的基本组成单位,值得一提的是,作为四大组件之一,它是需要"注册"的.组件的特性使得一个Activit ...

  2. python基础操作以及hdfs操作

    目录 前言 基础操作 hdfs操作 总结 一.前言        作为一个全栈工程师,必须要熟练掌握各种语言...HelloWorld.最近就被"逼着"走向了python开发之路, ...

  3. MYSQL基础操作

    MYSQL基础操作 [TOC] 1.基本定义 1.1.关系型数据库系统 关系型数据库系统是建立在关系模型上的数据库系统 什么是关系模型呢? 1.数据结构可以规定,同类数据结构一致,就是一个二维的表格 ...

  4. 【Learning Python】【第二章】Python基础类型和基础操作

    基础类型: 整型: py 3.0解决了整数溢出的问题,意味着整型不必考虑32位,64位,有无符号等问题,你写一个1亿亿亿,就是1亿亿亿,不会溢出 a = 10 ** 240 print(a) 执行以上 ...

  5. Emacs学习心得之 基础操作

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Emacs学习心得之 基础操作 1.前言与学习计划2.Emacs基础操作 一. 前言与学习计 ...

  6. Git基础操作

    配置秘钥 1.检查本机有没有秘钥 检查~/.ssh看看是否有名为d_rsa.pub和id_dsa.pub的2个文件. $ ~/.sshbash: /c/Users/lenovo/.ssh: Is a ...

  7. activiti基础操作

    package activitiTest; import java.io.InputStream; import java.util.List; import java.util.zip.ZipInp ...

  8. 《Genesis-3D开源游戏引擎-官方录制系列视频教程:基础操作篇》

    注:本系列教程仅针对引擎编辑器:v1.2.2及以下版本 G3D基础操作   第一课<G3D编辑器初探> G3D编辑器介绍,依托于一个复杂场景,讲解了场景视图及其基本操作,属性面板和工具栏的 ...

  9. MYSQL 基础操作

    1.MySQL基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t1; --创建一个和t1一样的表,用like(表结构也一样 ...

随机推荐

  1. PHP基础之$_SERVER的详细参数与说明

    这几天准备静下心来看看平时忽略的一些PHP基础知识,也算是一个复习吧. 今天准备复习的是$_SERVER这个变量. 说明:$_SERVER 是一个包含了诸如头信息(header).路径(path).以 ...

  2. django系列7:修改404页面展示,优化模板,降低urlconf和模板之间的耦合,命名app将模板和app绑定

    为了增加程序的友好和健壮性,修改view代码,处理以下如果出现404,页面的UI展示. 修改view代码 from django.http import Http404 from django.sho ...

  3. bootstrap学习: 折叠插件和面板

    bootstrap提供了面板排版工具和折叠插件,能够用来实现新闻列表.留言板.博客分块等: 1.折叠插件: <a data-toggle="collapse" data-ta ...

  4. python去除html标签的几种方法

    import re from bs4 import BeautifulSoup from lxml import etree html = '<p>你好</p><br/& ...

  5. openstack项目【day23】:keystone组件网关协议

    本节内容 一 静态页面和动态页面 二 什么是web server 三 什么是网关协议 3.1 引子 3.2 网关协议 四 网关协议CGI.FastCGI.WSGI.UWSGI 五 网关协议与keyst ...

  6. 图解 CMS 垃圾回收机制原理,-阿里面试题

    最近在整理JVM相关的PPT,把CMS算法又过了一遍,每次阅读源码都能多了解一点,继续坚持. 什么是CMS CMS全称 ConcurrentMarkSweep,是一款并发的.使用标记-清除算法的垃圾回 ...

  7. [物理学与PDEs]第1章第2节 预备知识 2.1 Coulomb 定律, 静电场的散度与旋度

    1. Coulomb 定律, 电场强度 (1) 真空中 $P_1$ 处有电荷 $q_1$, $P$ 处有电荷 $q$, ${\bf r}_1=\vec{P_1P}$, 则 $q$ 所受的力为 $$\b ...

  8. Studio 5000指令IN_OUT管脚实现西门子风格

    习惯了西门子博途编辑风格的同学,乍一看到Studio 5000的编辑界面,一时不适应,尤其是功能块或指令的IN和OUT管脚在一起,不好分辨,本文简单几步搞定,实现像西门子IN和OUT分左右显示风格. ...

  9. UDP核心API讲解

  10. Vue技术内幕 出去看看吧 实例化+挂载

    实例化时挂载DOM 从 Vue.prototype.$mount 挂载函数开始 有 template配置项时生成 render函数