最近项目忙完了,老大又不让我做android了,总之快速开发接触的东西会很多,只要能解决问题的都是好方法,但从个人的角度而言,快速的开发让人无法深入了解一些技术,虽然现在在项目中可能不会做android了,但是既然开始学习了就不要放弃,继续自己的学习。
Fragment在android中被称为碎片,该技术的引入主要是解决android开源的多种屏幕适配问题,在平板、手机、电视都在使用android的情况下,单纯的采用activity会导致UI的单一,Fragment为了解决这种问题在android sdk11中引入。fragment需要绑定到activity中才能运行。
Fragment和Activity在某种程度有一定的相似性,也有类似的生命周期。但是Fragment必须依附于Activity,同时Activity不能被替换、删除等操作,而Fragment允许被替换和删除。
Fragment可以通过UI控件fragment绑定对应的Fragment也可以采用动态的添加方式。两种方式,第一种相对比较简单,而第二种则更加的灵活,通常是实际使用中合理的选择其中的一种方式。Fragment的灵活性大于Activity,因此目前android的设计中推崇AUF,就是所有的都使用Fragment。
第一种方式的实现通常在XML的布局文件中显示的定义对应的Fragmet的信息。
-
<fragment xmlns:android=""
-
android:id="@+id/helloFragment"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:name="com.example.hell.HelloFragment">
-
</fragment>
其中的android就是对应的Fragment的类名,这种方式不能方便的进行扩展和取消。
在最近的学习中,较好的体验了android设计的MCV思想,M通常是指数据相关的模型,也就是设计相关的数据模块,这种将设计的会使得数据是独立于其他组件的,C是指控制模块,这个模块会实现UI显示与数据的关联,实现具体的控制关联,V是指显示功能,将相关的数据信息通过控制显示出来。因此在android的功能设计的过程中最好将相关的数据信息作为单独的类,并提供管理这些数据的单一实例工具类,通过这个工具类,控制相关的组件能够访问到这些数据信息。
这些也是在看了一些代码之后的感想而已。AUF的思想通常使得在创建一个activity的过程中都需创建一个对应的Fragment的对象,对应的activity的layout只是提供简单的Fragment容器。
-
<?xml version="1.0" encoding='utf-8'?>
-
<FrameLayout xmlns:android=""
-
android:id="@+id/fragmentContainer"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
/>
而关于fragment的布局则是实际需要显示的相关ui布局。
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android=""
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:orientation="vertical" >
-
-
<TextView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:text="@string/crime_title_label"
-
style="?android:listSeparatorTextViewStyle"
-
/>
-
-
<EditText
-
android:id="@+id/crime_title"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:hint="@string/crime_title_hint"
-
/>
-
-
<TextView
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:text="@string/crime_details_label"
-
style="?android:listSeparatorTextViewStyle"
-
/>
-
-
<Button
-
android:id="@+id/crime_date"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_marginLeft="16dp"
-
android:layout_marginRight="16dp"
-
/>
-
-
<CheckBox
-
android:id="@+id/crime_solved"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content"
-
android:layout_marginLeft="16dp"
-
android:layout_marginRight="16dp"
-
android:text="@string/crime_solved_label"
-
/>
-
-
</LinearLayout>
这样设计的好处是activity不需要针对特定的ui布局,更像是一个通用的布局,所有的fragment都可以再其中添加。而Fragment则需要实现具体的UI布局,这样也从实现上将activity和具体的UI显示独立开来,实现了Fragment的动态添加和UI切换。因此activity更多的是管理Fragment。
Fragment的绑定实现
在AUF的实现中有一种比较常用的方式就是单Fragment的Activity。也就是只有一个Fragment和Activity进行绑定,因此可以提供一个通用的方法用于实现fragment与activity的绑定关系,也就是实现一个单Fragment绑定的Activity类。这样所有的Fragment需要绑定到一个具体的Activity的过程中只需要创建对应的Fragment对象,关于绑定的操作就有该抽象类完成。在代码中添加Fragment的实现会使用到一个Fragment的管理器FragmentManager,这个管理器的操作有点儿类似数据库的事物处理操作过程。具体的实现过程如下所示:
-
public abstract class SingleFragmentActivity extends FragmentActivity {
-
protected abstract Fragment createFragment(); <<----该方法用于创建不同的Fragment对象
-
-
@Override
-
protected void onCreate(Bundle arg0) {
-
super.onCreate(arg0);
-
setContentView(R.layout.activity_fragment);
-
/* 获取管理器 */
-
FragmentManager fm = getSupportFragmentManager();
-
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer); //R.id.fragmentContainer就是容器
-
-
if (fragment == null) {
-
/* 在activity中添加对应的Fragment的过程 */
-
fragment = createFragment();
-
fm.beginTransaction() //具体的操作类似数据库的事务处理过程
-
.add(R.id.fragmentContainer, fragment)
-
.commit();
-
}
-
}
-
}
在具体的实现某一个activity的过程中只需要实现对应的抽象函数Fragment createFragment(),同时所有的activity可以通用同一个布局文件。以上的代码实现了一个Fragment和activity的绑定过程,也就是需要使用FragmentManager进行控制。
-
public class CrimeActivity extends SingleFragmentActivity {
-
-
@Override
-
protected Fragment createFragment() {
-
//实现具体的创建过程
-
}
-
}
这样的对于activity就非常的通用,因此在这种单一fragment的情况下可以采用通用的activity。
关于createFragment的实现方式,其实可以针对不同的activity分别实现代码,但是在实际使用过程中都是采用其中一个activity中的Fragment启动另一个activity的方式,因此可能会传递一些参数,而这些参数时针对activity的,而为了实现AUF的思想,在其实activity的过程中就应该启动对应的Fragment。
有时候Fragment有一些归属于当前对象的参数信息需要保存,当然可以保存到归属的activity中,但是考虑到统一性,通常会考虑添加Fragment的Bundle参数,关于Fragment的Bundle参数有点儿类似Activity的Bundle参数,用于保存一些重要的信息,但是Fragment的Bundle参数需要在添加到Acitvity之前绑定,考虑到Fragment的通用性,可以为每一个创建的Fragment都添加一个对应的Bundle argement。具体如下所示:
-
public class CrimeFragment extends Fragment{
-
...
-
/* 这是fragment实现bundle的基本规则,在创建fragment的过程中不要调用构造函数 */
-
/* 该函数必须为static方法,不然必须先创建对应的对象才能创建fragmet */
-
public static CrimeFragment newInstance(UUID crimeId) {
-
Bundle args = new Bundle(); //创建bundle参数对象
-
args.putSerializable(EXTRA_CRIME_ID, crimeId); //填充对应的key-word对
-
-
CrimeFragment fragment = new CrimeFragment(); //创建对应的Fragment类
-
fragment.setArguments(args); //邦对对应的bundle参数
-
-
return fragment;
-
}
-
...
-
}
这样就可以在对应的activity中去实现对应的createfragment方法了,具体实现如下所示:
-
public class CrimeActivity extends SingleFragmentActivity {
-
-
@Override
-
protected Fragment createFragment() {
-
UUID crimeId = (UUID) getIntent()
-
.getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
-
//该参数来自activity,通过newInstance将参数传递给了Fragment
-
return CrimeFragment.newInstance(crimeId);
-
}
-
}
虽然
newInstance()的实现方法也可以在Activity的createFragment函数实现中完成,但是考虑到可重用性,将Fragment的绑定关系由Fragment实现更加的通用。
通过这种方式,就可以在其中的一个Activity的Fragment中启动另一个Activity中的Fragment。因此基本的实现过程如下所示.
SinalFragmentActivity(完成Fragment与Activity的绑定操作)
|
V
XXXActivity (实现具体Fragment的创建操作)
|
V
获取activity的参数,然后调用Fragment的绑定Bundle的创建函数
XXXFragment
|
V
定义静态创建实例方法,该方法中实现bundle和Fragment的绑定关系
因此Activity的类的实现方法如下所示:
-
public class CrimeActivity extends SingleFragmentActivity {
-
-
@Override
-
protected Fragment createFragment() {
-
UUID crimeId = (UUID) getIntent()
-
.getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
-
//获取activity的参数,并通过newInstance函数将对应的参数与、Fragment进行绑定
-
return CrimeFragment.newInstance(crimeId);
-
}
-
}
这种实现方法较好的实现了AUF中单Activity和Fragment的绑定实现,这种绑定实现对于Activity的布局非常通用,定义的抽象类也实现了Fragment和Activity的绑定关系。只需要实现对应Fragment的创建操作,为了进一步的实现,要求Fragment提供一种绑定Bundle的静态方法实现一个对象的创建,并绑定了一个bundle的对象。
这种实现方法主要是为了遵循AUF的实现,其实并不需要实现的这么复杂,但是从可重用性的角度分析,这样的实现方法是非常不错的。
有一些优秀的分析可以去拜读一下。
http://www.cnblogs.com/xinye/archive/2012/08/28/2659712.html
http://blog.csdn.net/guolin_blog/article/details/8881711
参考文献:
Android Programming: The Big Nerd Ranch Guide 第10章
阅读(2356) | 评论(0) | 转发(0) |