您的位置:首页 > 移动开发 > Android开发

Android Fragment学习笔记(1)———简单Fragment实现

2015-05-12 21:52 405 查看
我们使用某些app的时候可能会有类似经历,想连续翻看多个人的空间资料,却只能一个一个点击用户名打开,如果不需要返回,直接滑动翻看各个人的空间就好了。activity自身并不具有这样的灵活性。activity视图可以在运行时切换,但控制视图的代码必须在activity中实现。因此各个activity还是得和特定的用户屏幕紧紧绑定在一起。采用Fragment就可以绕开activity规则的限制。Fragment是一种控制器对象,activity可以委派它完成一些任务。通常这些任务就是管理用户界面。受管的可以是一整屏或是整屏的一部分。

--------------------------------------------------------------------------------我是分割线= =--------------------------------------------------------------------

我采用了《Android编程权威指南》中的例子:通过创建一个管理陋习的app来学习Fragment起初我们只需要简单实现三个类:Crime。CrimeFragment,CrimeAcivity。实例代表了某种陋习,比如乱扔垃圾,插队。一个crime只有一个标题(陋习描述)和标识ID(UUID唯一元素)。CrimeActivity视图由FrameLayout组件构成,FrameLayout组件为CrimeFragment要显示的视图安排了存放位置。CrimeFragment的视图由一个LinearLayout组件及一个EditText组成。CrimeFragment类中有一个存贮editText的成员变量(mTitleField)。mTitleField上设有监听器,当EditText的文字发生变化时,用来更新模型层数据。

一句话:用户界面由UI Fragment进行管理,而Fragment的实例将通过acitvity来托管。



1.创建Crime类(模型层)

import java.util.UUID;

public class Crime {
private UUID mId;
private String mTitle;

public Crime(){
//生成唯一标识
mId = UUID.randomUUID();
}

public String getTitle() {
return mTitle;
}

public void setTitle(String mTitle) {
this.mTitle = mTitle;
}

public UUID getId() {
return mId;
}

}


2.托管UI Fragment:

为托管UI Fragment,activity必须做到:

在布局文件中为fragment的视图安排位置;

管理fragment实例的生命周期;



因为fragment代表activity在工作,它的状态也应该反映了activity的状态。因而,fragment需要对用的生命周期方法来处理activity工作。

fragment生命周期与activity生命周期的一个关键区别就在于,fragment的生命周期的方法是由activity操作而不是操作系统调用的。操作系统无从知晓activity用来管理视图 的fragment。fragment的使用时activity自己内部的事情

托管的两种方式:

1:添加fragment到activity布局当中去;
2:在activity代码中添加fragment。

我们肯定要优先选择后者,因为第一种等同于把fragment 和activity绑定在一起,且在activity的生命周期的过程中,无法切换fragment视图。
第二种是唯一一种可以在运行时控制fragment方式,可以在任意时刻添加,删除,替换。因此,为了真正获得UI设计的灵活性,我们必须通过代码的方式添加fragment。这也是我们用CrimeActivity托管CrimeFragment的方式。

--------------------------------------------------------------------------我是分割线-----------------------------------------------------------------------------------------------------------------------

虽然我们窑子托管的activity代码中添加UI fragment,但是还是需要子activity视图中给fragment安排一个视图的
<span style="font-family:Microsoft YaHei;"><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.crimialintent.CrimeActivity" >

</FrameLayout></span>
注:FrameLayout是服务于CrimeFragment的容器视图。但注意容器视图是通用性视图,不局限于CrimeFragment类,我们可以并且也将使用用一个布局来托管其他的fragment

创建UI fragment

创建UI fragment 的过程和创建一个activity的步骤相同:

1.定义布局文件;

2.创建fragment类并设置其视图为定义的布局;

3.通过代码的方式,连接布局文件中生成的组件

定义CrimeFragment( fragment_crime)的布局:

<span style="font-family:Microsoft YaHei;"><?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" >

<EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/crime_title_hint" />

</LinearLayout></span>


3.创建CrimeFragment类

记得继承的是android.support.v4.app.Fragment包下的Fragment

<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

public class CrimeFragment extends Fragment {

private Crime mCrime;
private EditText mTitleField;

@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mCrime = new Crime();// 新增一个成员变量实例;

}

@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {// bundle包含供该方法在保存状态下重建视图所使用的数据
View v = inflater.inflate(R.layout.fragment_cime, container, false);// 第三个参数是是否将生成的视图添加给父视图
/**
* Fragment.onCreateView(...)方法中的组建引用几乎等同于Activity.onCreate(...)方法的处理。
* 唯一的区别是我们调用了fragment视图的View.findViewById(int)方法。
* 以前使用Activity.findViewById十分便利,能够在 后台自己调用View.findViewById(int)方法。
*而frament类没有对应的便利方法,因此我们必须完成调用
**/

mTitleField = (EditText) v.findViewById(R.id.crime_title);
mTitleField.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
mCrime.setTitle(s.toString());// 给crime设置陋习标题
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}
});

return v;
}

}
</span>
以上代码中注意以下几点:

Fragment.onCreate(Bundle)是公共方法,不同于activity.onCreate()的Protect方法,因此Fragment.onCreate(Bundle)方法及其他Fragment生命周期必须设计为公共方法

在onCreate方法中,并没有生成fragment视图,但是配置了fragment实例,但创建和配置fragment视图都是通过另一个生命周期方法onCreateView()来实现

----------------------------------------------------------我是fragment的分割线= =,下面是托管到activity的部分--------------------------------------------------------------------------

4.利用FragmentManager管理fragment



在activity中,FragmentManager类负责管理fragment并将它们的视图添加到activity的视图层级结构中。

上代码!...

<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class CrimeActivity extends FragmentActivity { //继承自FragmentActivity

@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime);

/*
* 将Fragment添加到activity中: 1.获取FragmentManager
* 2.获取一个Fragment交由FragmentManager管理
*/
FragmentManager fm = getSupportFragmentManager();// 获取FragmentManager本身
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);//通过资源ID向FragmentMananger请求获取Fragment

if (fragment == null) {
fragment = new CrimeFragment();

//创建一个新的Fragment事务,加入一个添加操作,然后提交事务
fm.beginTransaction().add(R.id.fragmentContainer, fragment)
.commit();
}

}

}
</span>
提示一点:FragmentManager是使用FrameLayout的资源ID去识别CrimeFragment的,资源ID主要有两点作用:一是告知FragmentManager视图 应该出现在activity视图什么地方;二是ID为FragmentManager队列中fragment的唯一标识符。

好了,一个简单的fragment就实现了,文字细节描述有点多,但是很精华(自认为)。。。



注:本文参考《Android编程权威指南》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: