android:碎片的使用方式
介绍了这么多抽象的东西,也是时候应该学习一下碎片的具体用法了。你已经知道,碎 片通常都是在平板开发中才会使用的,因此我们首先要做的就是新建一个平板电脑的模拟 器。由于 4.0 系统的平板模拟器好像存在 bug,这里我就新建一个 4.2 系统的平板模拟器,如 图 4.4 所示。
图 4.4
现在启动这个平板模拟器,效果如图 4.5 所示。
图 4.5
好了,准备工作都完成了,接着新建一个 FragmentTest 项目,然后开始我们的碎片探索
之旅吧。
4.2.1 碎片的简单用法
这里我们准备先写一个最简单的碎片示例来练练手,在一个活动当中添加两个碎片,并
让这两个碎片平分活动空间。
新建一个左侧碎片布局 left_fragment.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"
/>
</LinearLayout>
这个布局非常简单,只放置了一个按钮,并让它水平居中显示。然后新建右侧碎片布局
right_fragment.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is right fragment"
/>
</LinearLayout>
可以看到,我们将这个布局的背景色设置成绿色,并放置了一个 TextView 用于显示一
段文本。接着新建一个 LeftFragment 类,继承自 Fragment。注意,这里可能会有两个不同包 下的 Fragment 供你选择,建议使用 android.app.Fragment,因为我们的程序是面向 Android 4.0 以上系统的,另一个包下的 Fragment 主要是用于兼容低版本的 Android 系统。LeftFragment 的代码如下所示:
public class LeftFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_fragment, container, false);
return view;
}
}
这里仅仅是重写了 Fragment 的 onCreateView()方法,然后在这个方法中通过 LayoutInflater 的 inflate()方法将刚才定义的 left_fragment 布局动态加载进来,整个方法简单明了。接着我 们用同样的方法再新建一个 RightFragment,代码如下所示:
public class RightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
}
基本上代码都是相同的,相信已经没有必要再做什么解释了。接下来修改 activity_main.xml
中的代码,如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/right_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="0dp"
android:layout_height="match_parent" android:layout_weight="1"
/>
</LinearLayout>
可以看到,我们使用了<fragment>标签在布局中添加碎片,其中指定的大多数属性你都
是熟悉的,只不过这里还需要通过 android:name 属性来显式指明要添加的碎片类名,注意一 定要将类的包名也加上。
这样最简单的碎片示例就已经写好了,现在运行一下程序,效果如图 4.6 所示。
图 4.6
正如我们所期待的一样,两个碎片平分了整个活动的布局。不过这个例子实在是太简单
了,在真正的项目中很难有什么实际的作用,因此我们马上来看一看,关于碎片更加高级的 使用技巧。
4.2.2 动态添加碎片
在上一节当中,你已经学会了在布局文件中添加碎片的方法,不过碎片真正的强大之处
在于,它可以在程序运行时动态地添加到活动当中。根据具体情况来动态地添加碎片,你就
可以将程序界面定制得更加多样化。
我们还是在上一节代码的基础上继续完善,新建 another_right_fragment.xml,代码如下 所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00" android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is another right fragment"
/>
</LinearLayout>
这个布局文件的代码和 right_fragment.xml 中的代码基本相同,只是将背景色改成了黄 色,并将显示的文字改了改。然后新建 AnotherRightFragment 作为另一个右侧碎片,代码如
下所示:
public class AnotherRightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.another_right_fragment,
container, false);
return view;
}
}
代码同样非常简单,在 onCreateView()方法中加载了刚刚创建的 another_right_fragment
布局。这样我们就准备好了另一个碎片,接下来看一下如何将它动态地添加到活动当中。修
改 activity_main.xml,代码如下所示:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/right_layout" android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<fragment
android:id="@+id/right_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
可以看到,现在将右侧碎片放在了一个 FrameLayout 中,还记得这个布局吗?在上一章 中我们学过,这是 Android 中最简单的一种布局,它没有任何的定位方式,所有的控件都会 摆放在布局的左上角。由于这里仅需要在布局里放入一个碎片,因此非常适合使用 FrameLayout。
之后我们将在代码中替换 FrameLayout 里的内容,从而实现动态添加碎片的功能。修改
MainActivity 中的代码,如下所示:
public class MainActivity extends
Activity implements OnClickListener {
@Override
protected
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new
AnotherRightFragment(); FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.
beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
break;
default:
break;
}
}
}
可以看到,首先我们给左侧碎片中的按钮注册了一个点击事件,然后将动态添加碎片的
逻辑都放在了点击事件里进行。结合代码可以看出,动态添加碎片主要分为 5 步。
1. 创建待添加的碎片实例。
2. 获取到 FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。
3. 开启一个事务,通过调用 beginTransaction()方法开启。
4. 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器的 id
和待添加的碎
片实例。
5. 提交事务,调用 commit()方法来完成。 这样就完成了在活动中动态添加碎片的功能,重新运行程序,可以看到和之前相同的界
面,然后点击一下按钮,效果如图 4.7 所示。
图 4.7
4.2.3 在碎片中模拟返回栈
在上一小节中,我们成功实现了向活动中动态添加碎片的功能,不过你尝试一下就会发
现,通过点击按钮添加了一个碎片之后,这时按下 Back 键程序就会直接退出。如果这里我 们想模仿类似于返回栈的效果,按下 Back 键可以回到上一个碎片,该如何实现呢?
其实很简单,FragmentTransaction 中提供了一个 addToBackStack()方法,可以用于将一 个事务添加到返回栈中,修改 MainActivity 中的代码,如下所示:
public class MainActivity extends Activity implements
OnClickListener {
……
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new
AnotherRightFragment(); FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.
beginTransaction();
transaction.replace(R.id.right_layout,
fragment); transaction.addToBackStack(null); transaction.commit();
break;
default:
break;
}
}
}
这里我们在事务提交之前调用了 FragmentTransaction 的 addToBackStack()方法,它可以 接收一个名字用于描述返回栈的状态,一般传入 null
即可。现在重新运行程序,并点击按钮
将 AnotherRightFragment 添加到活动中,然后按下 Back 键,你会发现程序并没有退出,而 是回到了 RightFragment 界面,再次按下 Back 键程序才会退出。
4.2.4 碎片和活动之间进行通信
虽然碎片都是嵌入在活动中显示的,可是实际上它们的关系并没有那么亲密。你可以看 出,碎片和活动都是各自存在于一个独立的类当中的,它们之间并没有那么明显的方式来直
接进行通信。如果想要在活动中调用碎片里的方法,或者在碎片中调用活动里的方法,应该
如何实现呢?
为了方便碎片和活动之间进行通信,FragmentManager 提供了一个类似于 findViewById()
的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:
RightFragment rightFragment = (RightFragment)
getFragmentManager()
.findFragmentById(R.id.right_fragment);
调用 FragmentManager 的 findFragmentById()方法,可以在活动中得到相应碎片的实例,
然后就能轻松地调用碎片里的方法了。
掌握了如何在活动中调用碎片里的方法,那在碎片中又该怎样调用活动里的方法呢?其 实这就更简单了,在每个碎片中都可以通过调用 getActivity()方法来得到和当前碎片相关联 的活动实例,代码如下所示:
MainActivity activity = (MainActivity) getActivity();
有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要
使用
Context 对象时,也可以使用 getActivity()方法,因为获取到的活动本身就是一个 Context 对象了。
这时不知道你心中会不会产生一个疑问,既然碎片和活动之间的通信问题已经解决了, 那么碎片和碎片之间可不可以进行通信呢?
说实在的,这个问题并没有看上去的复杂,它的基本思路非常简单,首先在一个碎片中 可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样也就实 现了不同碎片之间的通信功能,因此这里我们的答案是肯定的。
android:碎片的使用方式的更多相关文章
- 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
腾讯优测是专业的android自动化测试平台,拥有上千款真机,彻底解决android碎片化问题! 这里我要说的不是闪光灯的硬件特征,也不是说底层驱动的原理,我只是跟大家聊一聊在项目中遇到的一些关于闪光 ...
- android 三种定位方式
http://www.cnblogs.com/oudi/archive/2012/03/22/2411509.html 最近在看android关于定位的方式,查了很多资料,也做了相关实验,在手机上做了 ...
- Android 修改屏幕解锁方式
Android 修改屏幕解锁方式 问题 在手机第一次开机的时候,运行手机激活的APP 在激活APP允许过程中,当用户按电源键的时候,屏幕黑掉,进入锁屏状态 手机默认的锁屏是滑动解锁 用户这个时候再一次 ...
- Android] Android XML解析学习——方式比较
[Android] Android XML解析学习——方式比较 (ZT) 分类: 嵌入式 (From:http://blog.csdn.net/ichliebephone/article/deta ...
- Android几种视频播放方式,VideoView、SurfaceView+MediaPlayer、TextureView+MediaPlayer,以及主流视频播放器开源项目
简单的说下一Android的几种视频播放功能: 1.VideoView:最简单的视频播放 <FrameLayout xmlns:android="http://schemas.andr ...
- [转]Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件
Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件. 1.为了防止拖动ListView时,在列表末尾重复数据显示.需要加入 HashMap<In ...
- 理解Android绘制视图的方式
在创建自定义ViewGroup前,读者首先需要理解Android绘制视图的方式.我不会涉及过多细节,但是需要读者理解Android开发文档(见3.5节)中的一段话,这段话解释如何绘制一个布局.内容如下 ...
- Android 查看Apk签名方式V1和V2
Android 查看Apk签名方式V1和V2 java -jar apksigner.jar verify -v my.apk -- Verifies Verified using v1 scheme ...
- Android 进程间通讯方式
Android 进程间通讯方式 1.通过单向数据管道传递数据 管道(使用PipedWriter/ 创建PipedReader)是java.io包的一部分.也就是说,它们是一般的Java功能,而不是An ...
随机推荐
- 利用pyecharts做地图数据展示
首先, pip install pyecharts 为了地图上的数据能显示完全,加载好需要的城市地理坐标数据. pip install echarts-countries-pypkg pip inst ...
- vuejs之v-if-ajax异步请求数据遇到的坑
场景: params是异步请求获得的数据是一个对象,对象中又有chefHealthInfos数组 渲染时候会报错: 分析: 这是因为可以把v-if看成渲染了两次,两次结果params分别为{},{ch ...
- Laravel 返回数据库中的随机一行数据
最佳方式 $total = Book::count() - 1; $skip = mt_rand(0, $total); $item = Book::select('name', 'author_id ...
- hdu4122
题目很长,有点恶心,但实际上是个单调队列 没搞出来,题解 https://blog.csdn.net/lvshubao1314/article/details/46910271 #include< ...
- poj3067 二维偏序树状数组
题解是直接对一维升序排列,然后计算有树状数组中比二维小的点即可 但是对二维降序排列为什么不信呢?? /* */ #include<iostream> #include<cstring ...
- windows Service程序的安装、启动、卸载命令
安装:%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe ServiceTest.exe 启动:Net Start serv ...
- HTML5游戏 看你有多“色” 开发
所有文章搬运自我的个人主页:sheilasun.me 在极客学院看到了这个游戏,在网上找到这个游戏玩了好久真的比较上瘾,于是自己也试着做了一下,可以戳这里试玩→看你有多色 游戏规则: 找出颜色不同的方 ...
- [转] 基于NodeJS的前后端分离的思考与实践(五)多终端适配
前言 近年来各站点基于 Web 的多终端适配进行得如火如荼,行业间也发展出依赖各种技术的解决方案.有如基于浏览器原生 CSS3 Media Query 的响应式设计.基于云端智能重排的「云适配」方案等 ...
- thinkphp注册验证
在model中新建一个UserModel //覆盖原本的设置 //一次性获得全部验证错误 protected $patchValidate = true; //实现表单项目验证 //通过重写父类属性_ ...
- git shell 命令大全
常用命令 git branch 查看本地所有分支 git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支 git branch -r 查看远程所有分 ...