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. 提高Mxd地图渲染出图效率的方法

    测试 在ArcGIS地图渲染非常耗时,特别是标注较多时,下面是做的一些性能测试   小结 1.地图渲染的数据量是显示出图速度的关键.主要注意: (1)与数据库存储的数据量关系不大.例如数据库有1万条数 ...

  2. Format Conditions按条件显示表格记录

    标记特定记录 DevExpress强大得确实让人觉得它别具一格!现在,我有这样一个需求,把一个表中某字段为False的记录标记出来.下面是效果(某字段的可见性为否): 实现方式 如果是以前,我写个代码 ...

  3. Ant详解之-path、classpath和fileset

    转自:http://www.cnblogs.com/itech/archive/2011/11/01/2231206.html 一 .<path/> 和 <classpath/> ...

  4. 转:nginx基础概念(connection)

    在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件.利用nginx封装的connection,我们可以很方便的使用nginx来处理与连接相关的事情,比 ...

  5. 使用 loop device 制作安装镜像

    看了下,手上的镜像中,文件系统才 100 多兆,但是整个镜像居然要 4G, 这意味着,我每次安装这个镜像到 SD 卡都要花很多没必要的时间. 所以,我提取了一些关键内容,然后,准备重新打包镜像. 1. ...

  6. Struts 2相关配置与基本操作演示(案例Demo)

    基本介绍 Struts 2        Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2 ...

  7. emplace_back() 和 push_back 的区别(转)

    在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...

  8. cocos2d-js 调试办法 断点调试 Android真机调试

    一 使用浏览器chrome打开程序,进行调试.跟普通js程序一样. 要么自行搭建服务器,利用python脚本,或者用其他服务器程序(LAMP或XAMPP).然后用浏览器打开服务器地址. 要么直接使用c ...

  9. 2011的n次方

    题目:http://noi.openjudge.cn/ch0204/2991/ 总时间限制:1000ms  内存限制: 65536kB 描述 已知长度最大为200位的正整数n,请求出2011^n的后四 ...

  10. >/dev/null 2>&1 这句话的含义及使用的意义

    一般在shell包括dos下都可能会这样使用. null是一个名叫null小桶的东西,将输出重定向到它的好处是不会因为输出的内容过多而导致文件大小不断的增加.其实,你就认为null就是什么都没有,也就 ...