引入fragment
采用fragment而不是activity来管理应用UI,可绕开Android系统activity使用规则的限制。
fragment是一种控制器对象,activity可委派它执行任务。这些任务就是管理用户界面。受管理的用户界面可以是一整屏或是整屏的一部分。
为了更好的展开讲解,这里简单的开发一个名为CriminalIntent的应用。该应用可详细的记录各种陋习。开发一个由两个activity组成的列表明细类应用,一个activity负责管理记录列表界面,另一个负责管理记录明细界面。
1.创建新项目
本项目取名为CriminalIntent,新增CrimeActivity.java和activity_crime.xml。创建项目后,我们需要在app/build.gradle中添加依赖
dependencies {
......
compile 'com.android.support:appcompat-v7:25.3.1'
......
}
当然也可以使用Android Studio提供的工具添加。选择File->Project Structure,选择左边的应用模块,然后选择Dependencies选项页,点击+号按钮,搜索需要的依赖项
点击ok按钮完成添加,再打开app/build.gradle可查看到已经添加完成了。
2.创建模型层,Crime类
public class Crime {
private UUID mId; //UUID是Android框架里的Java工具类
private String mTitle;
private Date mDate;
private boolean mSolved;
public Crime() {
mId=UUID.randomUUID(); //产生一个随机唯一ID值
mDate=new Date();
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
public boolean isSolved() {
return mSolved;
}
public void setSolved(boolean solved) {
mSolved = solved;
}
}
3.定义容器视图(修改activity_crime.xml)
<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">
</FrameLayout>
此时运行应用,是一片空白,稍后我们会给这个容器添加点东西。
4.创建UI fragment
1. 定义CriminalFragment布局,新建xml文件,取名fragment_crime.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"
android:layout_margin="16dp">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_title_label"/>
<EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/crime_title_hint"/>
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_details_label"/>
<Button
android:id="@+id/crime_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/crime_solved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_solved_label"/>
</LinearLayout>
效果如图所示
这时你的代码提示有错误,不用担心,因为你还需在string.xml中进行一些配置。
<resources>
<string name="app_name">CriminalIntent</string>
<string name="crime_title_hint">Enter a title for the crime.</string>
<string name="crime_title_label">Title</string>
<string name="crime_details_label">Details</string>
<string name="crime_solved_label">Solved</string>
</resources>
2. 创建CrimeFragment类
CrimeFragment类用来管理fragment_crime.xml视图。注意要继承Fragment(导入android.support.v4.app包)
选择New->Java Class菜单来新建吧。稍后修改成代码如下。
public class CrimeFragment extends Fragment {
private Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox;
@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);
//生成并使用EditText组件
mTitleField=(EditText)v.findViewById(R.id.crime_title);
mTitleField.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) {
mCrime.setTitle(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
//
}
});
//生成并使用Button组件
mDateButton=(Button)v.findViewById(R.id.crime_data);
mDateButton.setText(mCrime.getDate().toString());
mDateButton.setEnabled(false);
//生成并使用CheckBox组件
mSolvedCheckBox=(CheckBox)v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setChecked(mCrime.isSolved());
mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCrime.setSolved(isChecked);
}
});
return v;
}
}
fragment自己无法在屏幕上显示视图,所以方法就是把CrimeFragment添加给CrimeActivity。
为了协同工作,Activity类中相应添加了FragmentManager类,Fragment类负责管理fragment并将其添加到activity的视图层级结构中。
5.获取FragmentManager并使用其处理fragment的相关事务
修改CrimeActivity.java代码
public class CrimeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime);
//获取FragmentManager
FragmentManager fm=getSupportFragmentManager();
//获取一个fragment交给FragmentManager管理
Fragment fragment=fm.findFragmentById(R.id.fragment_container);
//进行fragment的相关事务处理
if (fragment==null){
fragment=new CrimeFragment();
fm.beginTransaction().add(R.id.fragment_container,fragment).commit();
}
}
}
这时运行程序,能够将CrimeFragment的视图展现出来了!大家不妨试试。
最后来总结一下:
1. 一开始我们新建了CrimeActivity.java和activity_crime.xml。
- CrimeActivity.java继承AppCompatActivity
- activity_crime.xml是CrimeActivity.java的视图布局,在activity_crime.xml中只定义了一个FrameLayout布局。
2. 后来创建了UI fragment。
- 定义了CrimeFragment.java和fragment_crime.xml。
- CrimeFragment.java继承Fragment
- fragment_crime.xml是CrimeFragment.java的视图布局。
3. 最后应用显示视图
- 因为fragment自己无法在屏幕上显示视图,所以引入了FragmentManager来负责将fragment添加到activity的视图层级结构中,以这种方式显示出视图。
- 为托管UI fragment,activity必须:
- 在其布局中为fragment的视图安排位置。
- 管理fragment实例的生命周期。
fragment生命周期的一个关键区别就在于,fragment的生命周期方法由托管activity而不是操作系统调用。操作系统不关心activity用来管理视图的fragment。fragment的使用是activity内部的事情。
看到这里相信大家对fragment一定的初步的了解了吧!!!