一、概述
Fragment(碎片,片段)是在Android 3.0后才引入的,基本的目的是为了实如今大屏幕设备上的更加动态更加灵活的UI设计。

这是由于平板电脑的屏幕比手机大得多,所以屏幕上能够放很多其它的组件,而不是简单地仅仅是把手机上的组件放大。所以Fragment在应用中的是一个可重用的模块化组件,它有自己的布局、自己的生命周期,在一个Activity中能够包括多个Fragment。


二、在Activity中载入Fragment
Fragment的载入方式包括两种:静态载入和动态载入。静态载入非常easy,我们仅仅须要把Fragment(片段)当成普通UI控件放到界面Layout中即可;动态载入略微复杂一点,须要用到事务。


三、静态载入
在Activity中静态载入Fragment的过程分为三步:
1. 创建一个Layout文件,就是我们的Fragment的UI界面
2. 创建一个类继承Fragment,然后重写里面的onCreateView方法,将Fragment的Layout变成View
3. 在Layout布局文件里声明fragment,android:name属性里是我们上面创建的类,另外,fragment必须用id或tag作为唯一标识

综上。就是Fragment静态载入的内容。

以下来看一个演示样例:

首先,是Fragment的UI布局myfragment.xml文件,例如以下:
<?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" > <TextView
android:id="@+id/textView"
android:textSize="20sp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment演示样例" /> </LinearLayout>


然后,创建类MyFragment.java。继承Fragment:
package com.example.myfragment;

import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; @SuppressLint("NewApi")
public class MyFragment extends Fragment{ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("Fragment", "onCreateView");
// 将myfragment Layout文件转化为View
//返回转化来的View
return inflater.inflate(R.layout.myfragment, container, false);
}
}

最后,我们须要在activity_main.xml中声明fragment标签:
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.myfragment.MainActivity" > <fragment
android:name="com.example.myfragment.MyFragment"
android:id="@+id/myfragment_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/> </RelativeLayout>


android:name属性中是MyFragment.java的全名。android:id中是Fragment的唯一标识(这个必须得加,否则报错,也可用android:tag属性来作唯一标识)。


以下是MainActivity的代码,我们在这里将Fragment中的那行字改了一下,由"Fragment演示样例"改成了"床前明月光":

package com.example.myfragment;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.TextView; public class MainActivity extends ActionBarActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//做一个简单的UI操作,证明静态载入时我们能够直接获取到
//Fragment中的UI控件
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText("床前明月光");
}
}


执行后可看到结果:


四、动态载入
实现动态载入,我们须要先了解Fragment事务。

熟悉数据库的同学都知道,事务指的就是一种原子性、不可拆分的操作。

所谓的Fragment事务就是:对Fragment进行加入、移除、替换或运行其他动作。提交给Activity的每个变化。

这就是Fragment事务。


Fragment是UI模块,自然在一个Activity中能够不仅仅有一个模块。所以Android提供了FragmentManage类来管理Fragment,FragmentTransaction类来管理事务。

我们对Fragment的动态载入就是先将加入、移除等操作提交到事务,然后通过FragmentManage完毕的。


通过FragmentManager.beginTransaction()我们能够開始一个事务。在事务中,我们能够对Fragment进行的操作以及相应的方法例如以下:
加入:add()
移除:remove()
替换:replace()
提交事务:commit()
上面几个是比較经常使用的,还有attach()、detach()、hide()、addToBackStack()等方法。
我们须要注意的是,Fragment以ID或Tag作为唯一标识。所以remove和replace的參数是Fragment。这个Fragment目标Fragment一致。

在以下的演示样例里,我使用了一个栈记录全部加入的Fragment。然后在移除时使用。


演示样例:

在上面那个project的基础上,先改动一下activity_main.xml。主要是加了两个button:
<LinearLayout 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:orientation="vertical"
tools:context="com.example.myfragment.MainActivity" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<Button
android:id="@+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加入"
android:textSize="24sp"/>
<Button
android:id="@+id/remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除"
android:textSize="24sp"/> </LinearLayout> <!-- 这个LinearLayout里放置Fragment -->
<LinearLayout
android:id="@+id/fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
></LinearLayout> </LinearLayout>



MainActivity代码。细节写在了凝视里:
package com.example.myfragment;

import java.util.Stack;

import android.annotation.SuppressLint;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; public class MainActivity extends ActionBarActivity implements OnClickListener{ private Button add; // 加入Fragment
private Button remove; // 移除Fragment // Fragment管理器
private FragmentManager manager; // 使用一个栈记录全部加入的Fragment
private Stack<Fragment> fragmentStack = new Stack<Fragment>(); @SuppressLint("NewApi") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add = (Button) findViewById(R.id.add);
remove = (Button) findViewById(R.id.remove);
//给两个button注冊监听器
add.setOnClickListener(this);
remove.setOnClickListener(this);
//获取Fragment管理器
manager = this.getFragmentManager(); } @SuppressLint("NewApi") @Override
public void onClick(View v) {
// TODO Auto-generated method stub
MyFragment fragment;
FragmentTransaction transaction;
switch(v.getId()){
// 加入Fragment
case R.id.add:
// 新建一个Fragment
fragment = new MyFragment();
// 将ID加入到栈中
this.fragmentStack.push(fragment); // 开启一个新事务
transaction = manager.beginTransaction();
// 使用add方法加入Fragment,第一个參数是要把Fragment加入到的布局Id
// 第二个就是要加入的Fragment
transaction.add(R.id.fragments, fragment);
// 提交事务。否则加入就没成功
transaction.commit();
break;
// 移除Fragment
case R.id.remove:
// 新建一个Fragment
// 开启一个新事务
transaction = manager.beginTransaction();
// 使用add方法加入Fragment,第一个參数是要把Fragment加入到的布局Id
// 第二个就是要加入的Fragment
if(!this.fragmentStack.empty())
transaction.remove((
this.fragmentStack.pop()));
// 提交事务,否则加入就没成功
transaction.commit(); break;
}
}
}

最后的结果图:

Fragment能够加入也能够移除。




【Android进阶篇】Fragment的两种载入方式的更多相关文章

  1. 使用Fragment的两种方式:<fragment>与<FrameLayout>

    Android中使用Fragment的两种方式:<fragment>与<FrameLayout> 1.静态使用:自定义类,继承Fragment,在xml中使用<fragm ...

  2. Xamarin Android Fragment的两种加载方式

    android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...

  3. [Android] Android ViewPager 中加载 Fragment的两种方式 方式(一)

    Android ViewPager 中加载 Fragmenet的两种方式 一.当fragment里面的内容较少时,直接 使用fragment xml布局文件填充 文件总数 布局文件:view_one. ...

  4. Android中Fragment的两种创建方式

    fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认 ...

  5. [Android] Android ViewPager 中加载 Fragment的两种方式 方式(二)

    接上文: https://www.cnblogs.com/wukong1688/p/10693338.html Android ViewPager 中加载 Fragmenet的两种方式 方式(一) 二 ...

  6. [Android]Eclipse 安装 ADT[Android Development Tooling] 失败的两种解决办法

    原因 最近想在新装的 Win7 里搭建一下 Android 的开发环境,虽然现在有 Android Studio 了,不过还是习惯 Eclipse 一点.众所周知的原因,Eclipse 直接安装 AD ...

  7. Xamarin Android Activity全屏的两种方式

    方式一 直接在Activity的Attribute中定义 如下 在 MainActivity 中 [Activity(Label = "app", MainLauncher = t ...

  8. android 之 启动画面的两种方法

    现在,当我们打开任意的一个app时,其中的大部分都会显示一个启动界面,展示本公司的logo和当前的版本,有的则直接把广告放到了上面.启动画面的可以分为两种设置方式:一种是两个Activity实现,和一 ...

  9. (原创)android中使用相机的两种方式

    在社交类应用或扫描二维码的场合都需要用到手机上的摄像头 在程序中启用这一硬件主要有两类方法 1.发送intent启动系统自带的摄像应用 此应用的AndroidManifest中的intent-filt ...

随机推荐

  1. 洛谷 P1313 计算系数 (二项式定理)

    这道题正好复习了二项式定理 所以答案就是a^n * b^m * c(n, k) 然后注意一些细节 我一开始写组合数只写一行的组合数 即c[0] = 1; c[i] = c[i-1] * (n - i ...

  2. [luogu]P3572 [POI2014]PTA-Little Bird(单调队列)

    P3572 [POI2014]PTA-Little Bird 题目描述 In the Byteotian Line Forest there are nn trees in a row. On top ...

  3. Shiro:授权的相关实现

    Shiro:授权的相关实现 一.使用Shiro过滤器实现授权 设置好授权拦截跳转的请求地址 /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFi ...

  4. 洛谷 1156 dp

    洛谷1156 dp 类背包问题 老久没有自己想出来过dp方程了,,,虽然到最后还是只写了30分,,, 设dp[j]表示最大生命值为i时的最大高度,则对于每个物品,可以选择吃掉或者放上去,即转移为dp[ ...

  5. PatentTips - Cross-domain data transfer using deferred page remapping

    BACKGROUND OF THE INVENTION The present invention relates to data transfer across domains, and more ...

  6. Qt之窗体透明

    简述 关于窗体透明,经常遇到,下面我们针对常用的透明效果进行讲解: 全透明(主窗体.子窗体均透明) 主窗体透明(子窗体不透明) 子窗体透明(主窗体不透明) 简述 正常状态 全透明 效果 源码 主窗体透 ...

  7. FPGA中亚稳态——让你无处可逃

    1. 应用背景 1.1         亚稳态发生原因 在FPGA系统中,如果数据传输中不满足触发器的Tsu和Th不满足,或者复位过程中复位信号的释放相对于有效时钟沿的恢复时间(recovery ti ...

  8. 查看typedef类型

    typedef unsigned long int NUM; #include <iostream> using namespace std; NUM x; cout << t ...

  9. 浏览器输入一个url的过程,以及加载完html文件和js文件的标志

    简单理解: 当在浏览器地址栏输入一url时,浏览器会做以下几个步骤: 1.将url转化为ip地址,也就是DNS解析,(先找本地host文件中是否有对应的ip地址,如果有就直接用,没有的话,就按域名的二 ...

  10. JavaScript学习——JS事件总结

    回顾之前已经使用过的事件 (onsubmit.onclick.onload.onfocus.onblur.onmouseover.onmouseout) onfocus/onblur:聚焦离焦事件,用 ...