Android碎片(Fragment)简述
碎片(Fragment)是一种可以嵌入活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因此碎片在平板上的应用非常广泛。
你可以将碎片理解成一个迷你型的活动,水平同样可能包含布局,同样都有自己的生命周期。。。
上面的例子中,移动设备使用两个活动装载布局,而平板电脑的布局分别放在两个碎片中,然后在同一个活动里引入这两个碎片。
----------------------------------------------------碎片的简单用法--------------------------------------------------
新建两个布局,left_fragment.xml 和 right_fragment.xml(随便写点,能够区分开就行)
这是我创建的两个fragment:
接着创建一个LeftFragment类,继承自Fragment。重写onCreateView方法,代码如下:
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //return super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.left_fragment, container, false);
}
}
这里仅仅是重写了Fragment的onCreateView()方法。然后在这个方法中通过LayoutInflater的inflater()方法将刚才定义的left_fragment布局动态加载进来。
方法简单明了,试着用同样的原理新建一个RightFragment。
至此,碎片已经创建完毕,现在可以使用<fragment>标签在activity_main布局中添加碎片:
<?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"> <fragment
android:id="@+id/left_fragment"
android:name="com.example.dudon.fragmenttest.LeftFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" /> <fragment
android:id="@+id/right_fragment"
android:name="com.example.dudon.fragmenttest.RightFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
使用<fragment>向布局中添加碎片需要通过:android:name 属性来显示指明要添加的碎片类名,注意一定要将类的包名也加上。
最终效果:
-------------------------------------------------动态添加碎片--------------------------------------------------
动态添加碎片主要分为五步: 1. 创建待添加的碎片实例。 2. 获取到 FragmentManager,在活动中可以直接调用getFragmentManager()方法得到。 3. 开启一个事务,通过调用beginTransaction()方法开启。 4. 向容器内加入碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。 5. 提交事务,调用 commit()方法来完成。
新建一个布局 another_right_fragment.xml 效果如下:
然后新建一个AnotherRightFragment作为另一个右侧碎片,代码如下所示:
public class AnotherRightFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.another_right_fragment, container, false);
}
}
这样我们就准备好了另一个碎片,接下来将它动态的添加到活动中。
修改 activity_main.xml,代码如下所示:
<?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"> <fragment
android:id="@+id/left_fragment"
android:name="com.example.dudon.fragmenttest.LeftFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" /> <FrameLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"> <fragment
android:id="@+id/right_fragment"
android:name="com.example.dudon.fragmenttest.RightFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout> </LinearLayout>
现在将右侧碎片放在了一个FrameLayout中(FrameLayout中的所有控件都会摆放在布局的左上角)由于这里仅需要在布局里放入一个碎片,因此非常适合使用FrameLayout。
但是,我在这里使用FrameLayout并不表示 fragment 必须使用 FrameLayout。
修改MainActivity中的代码,从而实现动态添加碎片的功能。核心代码如下:
//实例化动态碎片
AnotherRightFragment fragment = new AnotherRightFragment();
//获取FragmentManger
FragmentManager fragmentManager = getFragmentManager();
//开启一个事务,通过调用beginTransaction开启
FragmentTransaction transaction = fragmentManager.beginTransaction();
//更改FrameLayout中的碎片,并提交
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
完整代码:
public class MainActivity extends Activity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView)findViewById(R.id.rocket);
imageView.setOnClickListener(this);
} @Override
public void onClick(View v) {
switch (v.getId()){
case R.id.rocket:
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
break;
default:
break;
}
}
}
最终效果(点击左侧小火箭之后):
====================Fragment扩展========================
-----------------------------------------模拟返回栈------------------------------------------
虽然现在成功实现了向活动中动态添加碎片的功能,但是添加完碎片之后,按下Back键程序就会直接退出。而我希望按下Back程序能够返回上一个碎片。
其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,代码如下:
private void analogStack() {
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getFragmentManager();
//开启一个事务,通过调用beginTransaction开启
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout, fragment);
//addToBackStack()方法用于将一个事务添加到返回栈中
transaction.addToBackStack(null);
transaction.commit();
}
重新运行程序,并点击按钮将 AnotherRightFragment 添加到活动中,然后按下Back键,你会发现程序并没有退出,而是回到了RightFragment界面,再次按下Back键程序才会退出。
----------------------------------------碎片与活动通信------------------------------------------
虽然碎片都是嵌入在活动中显示的,可实际上它们的关系并没有那么亲密。碎片和活动都是各自存在于一个独立的类当中的,它们之间并没有那么明显的方式来直接进行通信。
如果想要在活动中调用碎片的方法,或者在碎片中调用活动里的方法,应该如何实现呢?
为了方便碎片和活动之间进行通信,FragmentManager 提供了一个类似于 findViewById()的方法,专门用于从布局文件中获取碎片的实例:
RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById( R.id.right_fragment );
调用FragmentManager的findFragmentById()方法,可以在活动中得到相应碎片的实例,然后就能轻松地调用碎片里的方法了。
在每个碎片中都可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例:
MainActivity activity = (MainActivity) getActivity();
有了活动实例之后,就能够在碎片中调用活动里的方法了。当碎片中需要Context对象时,也可使用getActivity()方法,因为获取到的活动本身就是一个Context对象。
---------------------------------------碎片的生命周期----------------------------------------------
碎片的生命周期类似活动,每个碎片在其生命周期都会经历 运行状态、暂停状态、停止状态、销毁状态。
运行状态:
当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。
暂停状态:
当一个活动进入暂停状态时(由于另一个未占屏幕的活动被添加到了栈顶),与它关联的可见碎片就会进入到暂停状态。
停止状态:
当一个活动进入停止状态时,与它关联的碎片就会进入到停止状态。(或者通过FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除),停止状态的碎片对用户来说完全不可见,有可能会被系统回收。
销毁状态:
碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。
同样,Fragment类中也提供了一系列的回调方法,以覆盖碎片什么周期的每个环节。
onAttach(): 当碎片和活动建立关联的时候调用。
onCreateView(): 为碎片创建视图(加载布局)时调用。
onActivityCreated(): 确保与碎片相关的活动已经创建完毕的时候调用。
onDestroyView(): 当与碎片关联的视图被移除的时候调用。
onDetach(): 当碎片和活动解除关联的时候调用。
最新文章
- 【积累篇:他山之石,把玉攻】解决XP 系统 .Net Framework 4安装时出现严重错误 (0x80070643)
- C#编程语言与面向对象—— 多态
- EX:The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
- (十七)迭代器模式详解(foreach的精髓)
- Scala的sealed关键字
- I2C总线协议的简要说明
- QQ微信的备份
- 【转】MSSQLServer数据库事务锁机制分析
- Sqlserver 还原那些事
- 小心指针被delete两次
- [转]Android在eclipse中的快捷键
- Google Code项目代码托管网站上Git版本控制系统使用简明教程
- 转: pthread_detach()函数
- java 二叉树实现
- C#冒泡法排序源码
- Asp.Net SignalR 集线器不使用代理的实现
- [IOI2005]River 河流
- SQL-27 给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列。 提示:在sqlite中获取datetime时间对应的年份函数为strftime(&#39;%Y&#39;, to_date)
- Android 开发工具介绍-SDK工具和平台工具
- (转)log4j(六)——log4j.properties试过过程详解