fragment是Google在3.0版本号中推出的新功能,如今已经增加到V4包中,假设要使用V4兼容包中的Fragment须要将Activity换成FragmentActivity,调用的getSupportFragmentManager获取FragmentManager而不是getFragmentManager。

Fragment是Google大力推荐使用的一个功能。它和Activity功能事实上差点儿相同,只是比Activity更加的灵活和轻巧,Fragment寄存在Activity上面,他的生命周期直接受宿主Activity的影响,我们使用Fragment能够把它当做一个自己定义视图一样来使用,使用好Fragment的前提是了解其生命周期,以下一张图来显示其与宿主Activity生命周期的关系:

当然上面的生命周期中我们不须要都重写。甚至你一个生命周期方法不敲代码也能够正常执行。一般假设Fragment有视图的话我们须要重写onCreateView。更加须要你也能够重写其他的生命周期的方法。

与本节知识点相关的类主要有:FragmentManager、FragmentTransaction、Fragment这三个。这里我给大家提出来几个有用的类,都是Google帮我们分装好而且经常会使用到的类:DialogFragment、ListFragment、PreferenceFragment,第一个是用来创建Dialog的,第二个是一个含有ListView的Fragment。最后一个一般用来作为偏好方面的功能的设计,类似于手机里面的设置界面。

以下就来给这三个类中的经常用法列出来。

FragmentManager:

beginTransaction():用来得到事务对象,兴许对Fragment的加入删除等都是靠事务对象。

addOnBackStackChangedListener():给回退栈加入一个监听,回退栈中的Fragment数量变化都会调用这个监听。

findFragmentbyid():依据Fragment的id找到相应的Fragment。

findFragmentByTag():依据TAG找到相应的Fragment

popBackStack():将回退栈中的Fragment弹出也就是销毁。这种方法有非常多个重载方法,能够指定一个Fragment弹出。

FragmentTransaction:

add():将一个Fragment加入到事务中,该方法有多个重载。

replace():将Fragment替换指定的容器控件。假设是动态创建一个Fragment常常使用这种方法。

addtoBackStack():将Fragment加入到回退栈中。

remove():移除一个Fragment对象。

hide():隐藏一个Fragment对象。

commit():提交本次事务,仅仅要涉及到事务都会有这么一个方法,比方数据库中用到了事务也有这种方法。

show():跟hide相应使用。

Fragment:

setArguement():常常使用这种方法传递数据,相应的方法为getArgument();

我们用一个实例来演示Fragment的使用,实例仅仅有一个Activity,而Activity布局文件里左右各一个Fragment,左边的Fragment中仅仅有一个ListView,右边Fragment中仅仅有一个ImageView,点击左边的ListView让右边的Fragment中的ImageView显示不同的图片。

这里关键是左右Fragment交互的问题,解决问题我们有两种方式。一种是基于接口回调的方式。还有一种我们能够是观察者模式,能够使用我们先前讲过的第三方EvnetBus,这里我们就使用接口回调的方式来解决。我们先来上效果图

(这里ListView的线条不正确的问题是模拟器的原因。真机执行不存在这个bug)

Fragment的使用有两种方式

静态:直接在布局文件里声明Fragment。

动态:在布局文件里使用容器控件占位。然后使用前面说的replace方法替换掉。

由于第一种方式比較简单,这里的样例我们使用另外一种方式。

首先来看Activity的布局文件

<?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="horizontal"> <RelativeLayout
android:id="@+id/containerB"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:gravity="center"></RelativeLayout> <FrameLayout
android:id="@+id/containerA"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"></FrameLayout> </LinearLayout>

使用一个Relativelayout和一个framelayout作为占位控件。

当然我们先要有2个Fragment,以下贴出两个Fragment的代码:

左边的Fragment:

public class BFragment extends Fragment {
private ListView listView;
private OnClickItemListener onClickItemListener; @Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
onClickItemListener = (OnClickItemListener) getActivity();
View view = inflater.inflate(R.layout.bfragment_layout, null);
listView = ((ListView) view.findViewById(R.id.bfragment_listView));
List<String> names = new ArrayList<>();
{
names.add("可爱");
names.add("活泼");
names.add("成熟");
names.add("高贵");
names.add("文静");
}
ArrayAdapter adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, names);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<? > parent, View view, int position, long id) {
onClickItemListener.clickedItem(position);
Toast.makeText(getActivity(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
return view;
} //回调接口用于传递数据
public interface OnClickItemListener {
void clickedItem(int position);
} }

这里我们定义了一个接口OnClickItemListener用于和Activity通信。

右边的Fragment:

public class AFragment extends Fragment {
private View view;
private ImageView imageView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.afragment_layout, null);
imageView = (ImageView) view.findViewById(R.id.afragment_imgv);
imageView.setImageResource(R.drawable.girl);
return view;
}
@Override
public void onResume() {
super.onResume();
Bundle bundle = getArguments();
if (bundle != null) {
switch (bundle.getInt("position")) {
case 0:
imageView.setImageResource(R.drawable.loveliness);
break;
case 1:
imageView.setImageResource(R.drawable.lively);
break;
case 2:
imageView.setImageResource(R.drawable.ripe);
break;
case 3:
imageView.setImageResource(R.drawable.noble);
break;
case 4:
imageView.setImageResource(R.drawable.gentle);
break;
default:
imageView.setImageResource(R.drawable.girl);
}
}
}
}

这里代码非常easy我就不多说了。以下重点是怎样把这两个Fragment加入到Activity中和他们之间怎样通信的。

既然Activity是这两个Fragment的宿主。那么Activity和Fragment的通信自然是非常easy的,既然Activity和Fragment通信非常easy并且两个Fragment又是在同一个Activity中。那么他们之间的通信自然就非常方便了,没错,我们就是使用Activity作为中转类似于手机通信中的基站的作用。前面一个Fragment已经提供了一个接口,我们仅仅须要让Activity实现这个接口就能够了。至于把Fragment加入到Activity中的问题,我们前面已经提供了2个容器控件,这里就非常easy了,代码例如以下:

   getFragmentManager().beginTransaction().replace(R.id.containerA, new AFragment()).commit();
getFragmentManager().beginTransaction().replace(R.id.containerB, new BFragment()).commit();

没错。简单的我都不想再和你提什么了。来看Activity的完整代码

public class MainActivity extends Activity implements BFragment.OnClickItemListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getFragmentManager().beginTransaction().replace(R.id.containerA, new AFragment()).commit();
getFragmentManager().beginTransaction().replace(R.id.containerB, new BFragment()).commit();
} @Override
public void clickedItem(int position) {
AFragment aFragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putInt("position", position);
aFragment.setArguments(bundle);
getFragmentManager().beginTransaction().replace(R.id.containerA, aFragment).addToBackStack(null).commit();
}
}

扫描关注我的微信公众号:

是不是特别简单呢??我们仅仅须要在重写的方法中动态的去创建右边的Fragment就能够把点击的位置传过去了。非常微妙的一种方式,假设你对这个不太熟能够慢慢的体会当中的关系,这里我给大家说说大致的思路:左边的Fragment我们提供了一个接口,而里面又有一个属性是这个接口。属性指向Activity,当使用接口中的方法的时候系统会去找实现了这个接口的类,自然就找到了Activity了,也就是会运行Activity中重写的clickItem方法,由于这种方法在Activity中,我们自己能够在这种方法中动态的去创建又变的Fragment而且把点击的位置传给它。

回调接口的时候刚開始我也不是非常会,慢慢的无论他然后自己就回了,真是奇怪。!

Fragment的知识大致就是这么多吧。最后送上demo给大家:点击打开链接

Fragment使用具体解释的更多相关文章

  1. FragmentPagerAdapter刷新fragment最完美解决方案

    FragmentPagerAdapter刷新fragment最完美解决方案   先感谢kingjxl2006的博客文章<Android FragmentPagerAdapter数据刷新notif ...

  2. android Fragment与Activity交互,互相发数据(附图具体解释)

    笔者最近看官方training.发现了非常多实用又好玩的知识. 当中.fragment与Activity通信就是一个. fragment与Activity通信主要是两点: 1.fragment传递信息 ...

  3. Android Fragment——详细解释

    1.Fragment概述 在一个Activity中. Fragment代表UI的一个部分或者一个行为.一个Activity能够结合多个Fragment对象,也能够在多个activity中使用同样Fra ...

  4. Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复

    Android中的状态保存和恢复 Android中的状态保存和恢复, 包括Activity和Fragment以及其中View的状态处理. Activity的状态除了其中的View和Fragment的状 ...

  5. Fragment提交transaction导致state loss异常

    下面自从Honeycomb发布后,下面栈跟踪信息和异常信息已经困扰了StackOverFlow很久了. java.lang.IllegalStateException: Can not perform ...

  6. 【译】用Fragment解决屏幕旋转(状态发生变化)状态不能保持的问题

    这篇文章解决了在StackOverflow上一个经常被提到的问题. 在配置发生变化(Configuration changs)时,什么是最好的保存活动对象方法,比如运行中的线程,Sockets,Asy ...

  7. Fragment与FragmentActivity的关系

    前阵用viewpaper+fragment做滑动引导,查阅了下网上的资料,发现在有两种做法,一个是自建类直接继承Activity另一种是继承FragmentActivity,很是迷惑,在查了些goog ...

  8. fragment的切换(解决REPLACE的低效)

    在项目中切换Fragment,一直都是用replace()方法来替换Fragment.但是这样做有一个问题,每次切换的时候Fragment都会重新实列化,重新加载一次数据,这样做会非常消耗性能用用户的 ...

  9. getSelection、range 对象属性,方法理解,解释

    网上转了一圈发现没有selection方面的解释,自己捣鼓下 以这段文字为例子.. <p><b>法国国营铁路公司(SNCF)20日承认,</b>新订购的2000列火 ...

随机推荐

  1. Android 开源项目 eoe 社区 Android 客户端

    本文内容 环境 开源项目 eoe 社区 Android 客户端 本文介绍 eoe 社区 Android 客户端.它是一个开源项目,功能相对简单,采用侧边菜单栏.可以学习一下.点击此处查看 GitHub ...

  2. URAL 1224. Spiral (规律)

    1224. Spiral Time limit: 1.0 second Memory limit: 64 MB A brand new sapper robot is able to neutrali ...

  3. android中Snackbar(Design Support)的使用

    Snackbar是Android Design Support Library中的一个组件,想使用Snackbar,必须先引入Design Support,我这里引入的是当前的最新版本: implem ...

  4. docker toolbox在win7下的安装

    1.下载安装docker toolbox docker toolbox的下载地址: http://mirrors.aliyun.com/docker-toolbox/windows/docker-to ...

  5. Spring开发 - 通过实现ApplicationContextAware在Servlet中调用注解的Service

    用过Spring MVC的人都知道,我们如何在Controller中注入Service,可以使用@Resource注解的方法. 有时候,实际在项目的过程中,我们需要在某个Servlet中使用Servi ...

  6. ZH奶酪:Python按行读取文件

    1:readline() file = open("sample.txt") while 1: line = file.readline() if not line: break ...

  7. 磁盘I/O的性能评估方法

    磁盘I/O的性能评估方法 http://blog.synology.com/blog/?p=2086 通常,我们很容易观察到数据库服务器的内存和CPU压力.但是对I/O压力没有直观的判断方法.磁盘有两 ...

  8. HDU2717 Catch That Cow 【广搜】

    Catch That Cow Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  9. cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers

    上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...

  10. Sakila——MySQL样例数据库解析(已经迁移)

    一.Introduction Sakila可以作为数据库设计的参考,也可作为实验数据.我是用作数据仓库和ODI学习的实验数据. The Sakila sample database was devel ...