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. 20175221 实验一《Java开发环境的熟悉》实验报告

    20175221 实验一<Java开发环境的熟悉>实验报告 (一)Linux运行结果 (二)IDEA下Java程序开发.调试:学会通过调试(Debug)来定位逻辑错误   试验IDEA是否 ...

  2. 关于confluence上传文件附件预览查看时出现乱码的问题解决办法

    在confluence上传excel文件,预览时发现乱码问题主要是因为再上传文件的时候一般是Windows下的文件上传,而预览的时候,是linux下的环境,由于linux下没有微软字体,所以预览的时候 ...

  3. Spring Cloud使用样例

    Spring Cloud Demo 项目地址:https://github.com/hackyoMa/spring-cloud-demo 组件 基于Spring Boot 2.0.4.Spring C ...

  4. 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)

    一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

  5. 17、 利用扇贝网:https://www.shanbay.com/, 做个测单词的小工具。

    先说下,我可以说完全没有看题目要求,我只看了下扇贝网的单词测试工具就开始编码了,写出来的代码尽可能的模仿了网站上的效果. 因为把问题搞复杂了,在这个练习上耽误了很长时间,最后都不想写了,所以代码有些混 ...

  6. MyBatis集成到Spring时配置MapperScannerConfigurer出错

    问题描述 在web项目中同时集成了spring mvc和mybatis. 将jdbc配置参数独立在外部配置文件中,然后通过<context:property-placeholder>引入. ...

  7. 练习:javascript-setInterval动画运动平移,定时器动画练习

    常见问题:定时器加速问题,每次点击会启动一个定时器,解决先清除定时器 <!DOCTYPE html> <html lang="en"> <head&g ...

  8. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学

    题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵. 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设 ...

  9. 逻辑运算符、位运算符、三元运算符、判断语句(if,switch)

    逻辑运算符 逻辑与 &:由false则false 逻辑或 |:有true则true 逻辑异或 ^:相同为false,不同为true 逻辑非 !:非false则true,非true则false ...

  10. php in_array() 循环大量数组时效率特别慢问题

    in_array() 会循环数组内部元素逐个匹配,特别耗时,换成以下方式,效率大大提升