Android之Fragment学习总结(1)
对于Fragment的学习:
近日初步学习了Fragment这以特殊的组件,其依托与一个Activity,与Activity的生命周期息息相关,为其设置的视图只有当其关联到一个Activity才会起效果。觉得其用处在于可以更改当前视图而不阻塞主线程,同时可以用于响应式布局,可使其在平板和手机这不同尺寸的设备上获得比较好的兼容效果。
学习写的是简易版的Fragment应用,实现在一个主页面(activty_main.layout)中手动添加一个自定义的fragment(其应用视图是Crime_fragment.layout)。需要继承的是 android.support.v4.app.Fragment
Fragment类 需要实现的主要方法:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
通过下列语句实现创建一个View实例并返回:View v = (View) inflater.inflate(R.layout.crime_fragment,container,false);
参数分别是:布局文件,父容器,是否关联
package com.example.fragmentpractise; import java.util.UUID; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; public class CrimeFragment extends Fragment{ private Crime mCrime; public static CrimeFragment newInstance(int id){ CrimeFragment c = new CrimeFragment(); return c; } @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); mCrime = new Crime(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View v = (View) inflater.inflate(R.layout.crime_fragment,container,false); Button date = (Button) v.findViewById(R.id.date); date.setText(mCrime.getDate().toString()); return v; } }
Crime_fragment
<?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="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20dp" android:text="@string/title_label"/> <EditText android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16dp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20dp" android:text="@string/detail_label"/> <Button android:id="@+id/date" android:layout_width="match_parent" android:layout_height="wrap_content" /> <CheckBox android:id="@+id/isSolved" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/isSolved"/> </LinearLayout>
Fragment布局
在托管的活动类中实现通过FragmentManager调用 findFragmentById(id) 查找是否存在,最后通过事务提交Fragment
检测是否存在该Fragment并加入
附加:对 ”View v = (View) inflater.inflate(R.layout.crime_fragment,container,false);“ 的探索
这里需要补充一点,就是上述参数中的关联的布尔值,在一般使用的inflate方法中可以值应用到上述的布局文件和父容器,不声明关联布尔值,这意味着视图会默认加入到当前指定的父容器中。这里可以做个实验:将A视图加到B布局中,如果传入关联布尔值为false,你会发现原先B布局中的组件都不显示了。这时候如果你想实现视图关联可以通过B.addView(A);来实现关联;但在这里有试过尝试选择默认参数或True布尔值,你会出现运行时报错:
10-19 20:11:40.846: E/AndroidRuntime(1956): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentpractise/com.example.fragmentpractise.CrimeActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
报错信息中可以看到当我们选择默认值或者True布尔值时会提醒我们指定的子视图已经加入某个父容器中了,提醒我们需要先将其从父容器中移除;
这里由于源码不可见,只能进行猜测,那便是系统在调用了onCreateView,得到视图并加入到之前设定的父容器,这一.addView() 方法已经由系统帮我们在背后实现了。(通过打印打印 onCreateView 中的container 的Id时发现是与提交事务时指定的container Id相同;)
附加:对于findFragmentById的探索
public abstract Fragment findFragmentById (int id)
Finds a fragment that was identified by the given id either when inflated from XML or as the container ID when added in a transaction. This first searches through fragments that are currently added to the manager's activity; if no such fragment is found, then all fragments currently on the back stack associated with this ID are searched.
Returns
The fragment if found or null otherwise.
这个方法实现了从FragmentManager实例中去寻找一个符合条件的Fragment,这里的条件受id制约,但API提到id究竟是什么呢?尝试使用了传入提交事务时的id,或者是生成布局时的给设置的id,最后在生成视图去检测都依旧不行;
为了验证这一方法,以下代码分别验证了通过Fragmentd XML的id来搜索:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View v = (View) inflater.inflate(R.layout.crime_fragment,container,false); Button date = (Button) v.findViewById(R.id.date); date.setText(mCrime.getDate().toString()); v.setId(R.id.test); return v; }
为布局加入Id
fragment = fm.findFragmentById(R.id.test); if(fragment != null){ Log.i("information", "true"); } else{ Log.i("information","false"); }
查询是否存在
结果是:10-13 23:10:16.267: I/information(2997): false
直到后来求助了高手和查阅资料后,终于发现了问题所在:这个提交的动作并不是同步的,由事务提交请求,再由系统自己去处理,为了验证这个问题,使用了以下代码来验证:
FragmentManager fm = getSupportFragmentManager() ; Fragment fragment = fm.findFragmentById(R.id.fragment_container); if(fragment == null){ FragmentTransaction tran = fm.beginTransaction (); tran.add(R.id.fragment_container,new CrimeFragment()); tran.commit(); }
先提交给事务
Timer timer= new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub FragmentManager fm = getSupportFragmentManager() ; Fragment fragment = fm.findFragmentById(R.id.fragment_container); if(fragment != null){ Log.i("information", "true"); } else{ Log.i("information","false"); } } }, 2000);
通过一个线程去延迟查找动作
结果是:10-14 22:18:47.436: I/information(1672): true
思路是使用线程,延迟2秒去检测。
附上一个自己Github上的简单Demo:https://github.com/lhppom/Fragment-Demo
Android之Fragment学习总结(1)的更多相关文章
- 33.Android之Fragment学习
Fragment Android是在Android 3.0 (API level 11)开始引入Fragment的. 可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的 ...
- Android之Fragment学习笔记①
Android Fragment完全解析,关于碎片你所需知道的一切 一. 什么是FragmentFragment(碎片)就是小型的Activity,它是在Android3.0时出现的.Fragment ...
- [android]p7-1 fragment学习笔记
本文源自<android权威编程指南第3版>第7章UI fragment与fragment 第7章主要内容是实现一个记录不良行为的APP(部分实现),有列表,有具体的行为内容显示.第7章主 ...
- Android之Fragment学习笔记②(Fragment生命周期)
一. Fragment生命周期图 二.Fragment生命周期方法介绍 Fragment的生命周期和activity生命周期很像,其生 ...
- Android应用开发学习笔记之Fragment
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Fragment翻译成中文就是“碎片”.“片断”的意思,Fragment通常用来作为一个Activity用户界面的一 ...
- [转]Android 使用Fragment界面向下跳转并一级级返回
1.首先贴上项目结构图: 2.先添加一个接口文件BackHandledInterface.java,定义一个setSelectedFragment方法用于设置当前加载的Fragment在栈顶,主界 ...
- Android:Activity+Fragment及它们之间的数据交换.
Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...
- Android中Fragment和ViewPager那点事儿(仿微信APP)
在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...
- Android中Fragment与Activity之间的交互(两种实现方式)
(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...
随机推荐
- (转)DataGridView多维表头及其扩展功能
dataGridView1.RowHeadersVisible = false;把整行选中那一列去掉.如果需要整行选中,新增一按钮列模拟实现.上源码:多维DataGridView 有个简易的方法: 1 ...
- ruby中proc和lambda的return区别
学习ruby有一段时间了,但是我看了好几遍proc和lambda的return区别的区别讲解,始终没明白到底什么区别,今天上午又看,终于感觉是茅塞顿开有点领悟了 一下内容部分来自<<rub ...
- Chap2: question: 1 - 10
1. 赋值运算符函数(或应说复制拷贝函数问题) class A { private: int value; public: A(int n) : value(n) {} A(A O) { value ...
- WinCE系统深度定制汇总
WinCE应用程序崩溃提示框的处理 WinCE6.0多国语言软键盘 定制WinCE6.0标准界面的一种方法 如何禁用WinCE下的沙漏图标 Silent RNAApp.exe for WinCE6.0 ...
- ZeroClipboard实现复制
今天利用ZeroClipboard实现了批量复制ip到剪贴版的公里,第一种方式总是有错,需要点击两次才能成功复制,第二种方法成功.在这里记录下,方法一: $('#copy_ips').zclip({ ...
- python中的装饰器
一.什么是装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能 ...
- U盘分区之后如何恢复
操作步骤: 1.插入U盘. 2.按windows键,右键点击“运行”,再左键点击以管理员身份运行. 3.输入diskpart,按enter. 4.输入list disk,按enter. 5.之后会看到 ...
- 0525 SCRUM项目7.0
主题:在下一个SPRINT中做的更好 一,实验回顾总结 当谈到在一个团队里的收获,首当其冲的便是对于团队工作流程的切身体会.亲力亲为.从申报材料.问卷设计.访谈提纲.团队建设.书签制作到实地访谈.问卷 ...
- 百度Ueditor
最近用到了百度Ueditor,也来写一写百度Ueditor的使用教程: 一.从官网下载百度Ueditor,http://ueditor.baidu.com/website/download.html, ...
- 关于yaha中文分词(将中文分词后,结合TfidfVectorizer变成向量)
https://github.com/jannson/yaha # -*- coding: utf-8 -*- """ Created on Wed Aug 10 08: ...