Android编程权威指南读书笔记 - 第七章

第七章:UI Fragment和Fragment管理器

这一章我们将开发一个CriminalIntent的应用。可以详细记录种种办公室陋习。(需要13章的事件把这个应用做完)

适应用户或设备的需求,activity界面可以在运行时组装,甚至重新组装。

fragment是一种控制器对象,activity可以委派它完成一些任务,这些任务通常就是管理用户界面,受管理的用户界面可以使一整屏幕或者整屏幕的一部分。

根据用户需求,可以联合使用fragment及activity来组装货重新组装用户界面,在整个生命周期过程中,activity视图在技术上保持不变,因此不用担心会违反Android系统的activity使用规则。

左边列表fragment,右边明细fragment。(这样,视图切换的过程,就不用销毁activity了)

fragment本身不具备在屏幕上显示视图的能力。因此,只有将它的视图放置在activity的视图层级结构中,fragment视图才能显示在屏幕上。

Google在API 11级中引入了fragment,以前的开发者要考虑支持的SDK最低版本是API 8级,因此,必须设法保证应用了兼容旧版本设备。幸运的是,Android提供了开发支持库。支持库提供了完整的fragment相关的类实现,最低能兼容支持API 4级。相较于Android系统内置的fragment实现,本书选择使用支持库中的fragment实现。

我们要用到两个重要的支持库类:一个是Fragment类(android.support.v4.app.Fragment),另一个是FragmentActivity(android.support.v4.app.Fragment-Activity),使用fragment的前提是activity知道如何管理fragment,FragmentActivity类知道如何管理支持版本的fragment。

7.3.3 在Android Studio中增加依赖关系。

要使用支持库,项目必须将其列入依赖关系。(每个项目有两个build.gradle,一个用户整个项目,一个用于应用模块)我们要编辑的是app/build.gradle文件。

apply plugin: ‘com.android.application’

android {

}

dependencies {

compile fileTree(dir: ‘libs’, include: [‘*.jar’])

}

考虑到依赖项设置指令复杂难记,Android Studio维护了一份常用库列表。File -> Project Structure 菜单项打开项目结构对话框。选择左边的应用模板,然后右边点击dependencies选项页,可以看到应用模板的依赖项都列在这了。

单击+号按钮,选择Library dependency界面添加新的依赖项,在列表中选择中support-v4库后单击OK即可,这样,在app/build.gradle文件就会自动添加了相应的依赖库:

dependencies {

compile fileTree(dir: ‘ilbs’, include: [‘*.jar’])

compile ‘com.android.support:support-v4:22.1.1’

}

如果手动修改了app/build.gradle文件,就需要同步修改内容:Tools -> Andorid -> Sync Project with Gradel Files菜单可手动执行同步。

compile ‘com.android.support:support-v4:22.1.1’ 使用了Maven坐标模式:groupId:artifactId:version

groupId通常是类库的基础包名,如com.android.support

artifactId是包中的特定库名,我们这里指定了support-v4,com.android.suport包中有很多不同的库,如support-v7、appcompat-v7和gridlayout-v7。-vX指所支持的最低API级别,v4表示google兼容库可以应用到Android API 7及以上级别的设备

version:指类库的版本号。如22.1.1的support-v4库

1、将CrimeActivity的超类修改为FragmentActivity,

public class CrimeActivity extends FragmentActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

2、创建Crime类(Model层)

public class Crime {

pirvate UUID mId;

private Sting mTitle;

public Crime() {

mId = UUID.randomUUID();

}

// 生成getter和setter方法

// 右键,Generate -> Getter菜单

}

为了托管UI fragment,activity必须做到如下:

1、在布局中为fragment的视图安排位置

2、管理fragment实例的生命周期

fragment的生命周期:

可以看到,许多方法对应着activity的生命周期方法。因为fragment代表activity工作,它的状态应该反映activity的状态,显然,fragment需要相对应的生命周期方法来处理activity的工作。

fragment生命周期与activity生命周期的一个关键区别在于,fragment的生命周期方法是由托管activity而不是操作系统调用。fragment的使用是activity内部的事情。

activity托管UI fragment的两种方式:

1、在activity布局中添加fragment:简单但不够灵活,等同于视图绑定,在activity生命周期过程中,无法切换fragment

2、在activity代码中添加fragment:比较复杂,但是可以在运行时控制fragment

因此,为了追求真正的灵活性UI设计,使用第二种方式。

7.5 创建fragment:

1、通过定义布局文件中的组件,组装界面

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

3、通过代码的方式,组装在布局文件中实例化的组件。

7.5.1 创建CrimeFragment的布局

fragment_crime.xml

7.5.2 创建CrimeFragment类

记得需要选择集成的类来自com.android.support.v4.app.Fragment

点击Alt+Return可以选中需要导入的库

实现fragment的生命周期方法

public class CrimeFragment extends Fragment {

private Crime mCrime;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mCrime = new Crime();

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.fragment_crime, container, false);

return v;

// inflater用来传入资源id生成视图

// container是视图的父视图

// false表示是否将生成的视图添加给父视图

}

}

注意:Fragment.onCreate(Bundle)是公共方法,而Activity.onCreate(Bundle)是保护方法。Fragment生命周期方法必须是公共方法,因为托管fragment的activity要调用他们。

fragment的视图没有在onCreate方法中生成,创建和配置fragment视图是另一个fragment生命周期方法完成的:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

该方法实例化fragment视图的布局,然后将实例化的View返回给托管activity。

创建关联组件EditText(在onCreateView方法里面添加EditText)

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.fragment_crime, container, false);

mTitltField = (EditText)v.findViewById(R.id.crime_title);

mTitleField.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

// this space intentionally left blank

}

@Override

public void onTextChanged(ChaSequence s, int start, int before, int count) {

s代表用户输入

mCrime.setTitle(s.toSting());

}

@Override

public void afterTextChanged(Editable s) {

// this one too

}

});

return v;

}

Fragment.onCreateView方法中的组件几乎等同于Activity.onCreate方法的处理。

7.6 添加UI fragment到FragmentManager

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

具体管理:1、fragment队列。2、fragment事务回退栈

Activity -> FragmentManager -> 1、fragment队列。2、fragment回退栈

FragmentManager fm = getSupportFragmentManager();

Fragment fragment = fm.findFragmentById(R.id.fragment_container);

if (fragment == null) {

fragment = new CrimeFragment();

fm.beginTransation().add(R.id.fragment_container, fragment).commit();

}

fragment事务被用来添加、移除、附加、分离或者替换fragment队列中的fragment。这就是使用fragment在运行时组装和重新组装用户界面的关键。FragmentManager管理着fragment事务回退栈。

重新审视Fragment的生命周期:

activity的FragmentManager负责调度队列中fragment的生命周期方法。

1、添加fragment供FragmentManager管理时,onAttach(Activity),onCreate(Bundle)以及onCreateView(…)方法被调用

2、在activity处于运行状态时,添加fragment会发生什么呢?FragmentManager会立即驱动fragment行动,执行必要方法,快速跟上activity步伐。一旦fragment的状态与activity的状态保持了同步,托管activity的FragmentManager就会边接收操作系统的调用指令,边调用其他生命周期方法,以继续保持fragment与activity的状态一致。

封装可复用组件是Google设计fragment的本意。一个良好的使用原则是:应用单瓶之多使用2-3个fragment。

使用fragment的理由:我们坚持总是使用fragment的原则。

你可能感兴趣的:(Android编程权威指南读书笔记 - 第七章)