生命周期方法的对应非常重要。因为fragment代表activity工作,它的状态应该反映activity的状态。显然,fragment需要相对应的生命周期方法来处理activity的工作。
fragment生命周期与activity生命周期的一个关键区别就在于,fragment的生命周期方法是由托管activity而不是操作系统调用。操作系统不关心activity用来管理视图的fragment。fragment的使用是activity内部的事情。
支持库和内嵌库区别:
不过我们仍然优先使用支持库版fragment。为什么?因为要升级支持库版fragment的话,我们只需要下载升级包,重新编译发布一个新版本应用就行了。Google每年会多次更新支持库,并借此引入新特性、修复bug。享受这些好处,我们只需要升级项目的支持库版本即可。举个例子,Google自Android 4.2开始支持fragment嵌套使用(在fragment中托管fragment)。如果开发基于Android操作系统内置版fragment,并且面向Android 4.0及以上版本的设备,应用就无法使用这个新特性了。假如用了支持库版fragment,就能轻松升级应用的支持库版本,随意使用fragment嵌套新特性,只要设备内存足够大。
此外,使用支持库版fragment没有显著的缺点。它和系统内置版本的代码实现几乎完全一样。唯一的真正缺点就是导入支持库包会占用空间。不过考虑到上述诸多优点,牺牲几兆字节空间并不算什么。
添加支持库:
考虑到依赖项设置指令复杂难记, Android Studio维护了一份常用库列表。选择File → Project Structure...菜单项打开项目结构对话框。 选择左边的应用模板,然后在右边点击Dependencies选项页。可以看到,应用模板的依赖项都列在这了 。单击+号按钮,在选择Library dependency界面添加新的依赖项,如图7-11所示。从列表中选中support-v4库后单击OK按钮确认。
fragment是一种类似在界面上插入小界面的东西
一,fragment的托管:
ctivity托管UI fragment有如下两种方式:
在activity布局中添加fragment;
在activity代码中添加fragment。
第一种方式就是使用布局fragment。这种方式简单但不够灵活。在activity布局中添加fragment,就等同于将fragment及其视图与activity的视图绑定在一起,并且在activity的生命周期过程中,无法切换fragment视图。
第二种方式比较复杂,但也是唯一可以在运行时控制fragment的方式。我们自行决定何时添加fragment以及随后可以完成何种具体任务;也可以移除fragment,用其他fragment代替当前fragment,然后重新添加已移除的fragment。因而,为追求真正的灵活性UI设计,就必须通过代码的方式添加fragment。这也是我们使用CrimeActivity托管CrimeFragment的方式。本章稍后会介绍代码的实现细节。现在,先来学习定义CrimeActivity的布局。
二,添加 UI fragment到FragmentManager
在Fragment类引入Honeycomb的时候,为协同工作,Activity类中相应添加了FragmentManager类。FragmentManager类负责管理fragment并将它们的视图添加到activity的视图层级结
构中。
FragmentManager类具体管理的是:
fragment队列;
fragment事务回退栈。
例子:
1. 托管fragment的ActivityXml文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
2. fragment的布局XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/crime_TitleLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_TitleLabel"
style="?android:listSeparatorTextViewStyle"/>
<EditText
android:id="@+id/crime_TitleEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/crime_TitleEdit"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
<TextView
android:id="@+id/crime_TimeLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_DateLabel"
style="?android:listSeparatorTextViewStyle"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp">
<Button
android:id="@+id/crime_DateButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<CheckBox
android:id="@+id/crime_FlagCheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_FlagCheck"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
3. 用于托管fragment的Activity的超类,目的通用多个Activity防止重复代码:
//创建通用的ActivityFragmentManager的抽象类,防止重复代码
public abstract class CrimeActivity extends FragmentActivity {
protected abstract Fragment createFragment();//抽象创建Fragment布局接口
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.crime_layout);
FragmentManager fm = getSupportFragmentManager();
Fragment yFragment = fm.findFragmentById(R.id.fragment_container);
if(null == yFragment){
yFragment = createFragment();//用抽象接口创建Fragment布局,可以根据需要创建不同接口
fm.beginTransaction()
.add(R.id.fragment_container,yFragment)
.commit();
}
}
}
4. 用于托管fragment的Activity:
//在Activity建立fragmentmanager来托管xml布局,此时继承的是通用ActivityFragmentManager抽象类
//注意:抽象类的抽象方法必须实现
public class MainActivity extends CrimeActivity {
@Override
protected Fragment createFragment(){
return new CrimeFragment();
}
}
5. fragment类的代码,实现fragment的布局:
//建立xml布局来被在Activity建立的fragmentmanager来托管
public class CrimeFragment extends Fragment{
private Crime yCrime;
private EditText TitleText;
private Button DateButton;
private CheckBox FlagCheck;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
yCrime = new Crime();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_crime, container, false);//
TitleText = (EditText)v.findViewById(R.id.crime_TitleEdit);
DateButton = (Button) v.findViewById(R.id.crime_DateButton);
FlagCheck = (CheckBox)v.findViewById(R.id.crime_FlagCheck);
//输入框
TitleText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
//按钮
DateButton.setText(yCrime.getyDate().toString());
DateButton.setEnabled(false);//禁用用户按下事件
//选项口
FlagCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// Set the crime's solved property
yCrime.setCrimeFlag(isChecked);
}
});
return v;
}
}
6. 其他,元素类Crime,数据模型:
//基本元素单位类
public class Crime {
private UUID yID;
private String yTitle;
private Date yDate;
private boolean CrimeFlag;
public Crime() {
yID = UUID.randomUUID();
yDate = new Date();
}
public UUID getyID() {
return yID;
}
public String getyTitle() {
return yTitle;
}
public void setyTitle(String yTitle) {
this.yTitle = yTitle;
}
public Date getyDate() {
return yDate;
}
public void setyDate(Date yDate) {
this.yDate = yDate;
}
public boolean getCrimeFlag() {
return CrimeFlag;
}
public void setCrimeFlag(boolean crimeFlag) {
CrimeFlag = crimeFlag;
}
}
额外:返回值
界面退出时将返回值退给上个界面
此处都以fragmnet方法实现,位于fragment里
设置返回值:
//设置返回值,返回时退给上个fragment
public void returnResult() {
getActivity().setResult(Activity.RESULT_OK, null);
}
接受返回值:
//用于获取返回值
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CRIME) {
/* Handle result */
}
}
REQUEST_CRIME是自己定义的标志值,用于比较返回值:
//用于比较Activity的返回值
private static final int REQUEST_CRIME = 1;