对于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);

参数分别是:布局文件,父容器,是否关联

  1. package com.example.fragmentpractise;
  2.  
  3. import java.util.UUID;
  4.  
  5. import android.os.Bundle;
  6. import android.support.v4.app.Fragment;
  7. import android.util.Log;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.Button;
  12.  
  13. public class CrimeFragment extends Fragment{
  14.  
  15. private Crime mCrime;
  16.  
  17. public static CrimeFragment newInstance(int id){
  18. CrimeFragment c = new CrimeFragment();
  19. return c;
  20. }
  21.  
  22. @Override
  23. public void onCreate(Bundle savedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. mCrime = new Crime();
  26. }
  27.  
  28. @Override
  29. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
  30.  
  31. View v = (View) inflater.inflate(R.layout.crime_fragment,container,false);
  32. Button date = (Button) v.findViewById(R.id.date);
  33. date.setText(mCrime.getDate().toString());
  34. return v;
  35.  
  36. }
  37.  
  38. }

Crime_fragment

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:textSize="20dp"
  10. android:text="@string/title_label"/>
  11. <EditText
  12. android:id="@+id/title"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:textSize="16dp"
  16. />
  17. <TextView
  18. android:layout_width="match_parent"
  19. android:layout_height="wrap_content"
  20. android:textSize="20dp"
  21. android:text="@string/detail_label"/>
  22. <Button
  23. android:id="@+id/date"
  24. android:layout_width="match_parent"
  25. android:layout_height="wrap_content"
  26. />
  27. <CheckBox
  28. android:id="@+id/isSolved"
  29. android:layout_width="match_parent"
  30. android:layout_height="wrap_content"
  31. android:text="@string/isSolved"/>
  32.  
  33. </LinearLayout>

Fragment布局

在托管的活动类中实现通过FragmentManager调用 findFragmentById(id) 查找是否存在,最后通过事务提交Fragment

  1. 检测是否存在该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来搜索:

  1. @Override
  2. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
  3.  
  4. View v = (View) inflater.inflate(R.layout.crime_fragment,container,false);
  5. Button date = (Button) v.findViewById(R.id.date);
  6. date.setText(mCrime.getDate().toString());
  7. v.setId(R.id.test);
  8. return v;
  9.  
  10. }

为布局加入Id

  1. fragment = fm.findFragmentById(R.id.test);
  2. if(fragment != null){
  3. Log.i("information", "true");
  4. } else{
  5. Log.i("information","false");
  6. }

查询是否存在

结果是:10-13 23:10:16.267: I/information(2997): false

直到后来求助了高手和查阅资料后,终于发现了问题所在:这个提交的动作并不是同步的,由事务提交请求,再由系统自己去处理,为了验证这个问题,使用了以下代码来验证:

  1. FragmentManager fm = getSupportFragmentManager() ;
  2. Fragment fragment = fm.findFragmentById(R.id.fragment_container);
  3. if(fragment == null){
  4. FragmentTransaction tran = fm.beginTransaction ();
  5. tran.add(R.id.fragment_container,new CrimeFragment());
  6. tran.commit();
  7. }

先提交给事务

  1. Timer timer= new Timer();
  2. timer.schedule(new TimerTask() {
  3.  
  4. @Override
  5. public void run() {
  6. // TODO Auto-generated method stub
  7. FragmentManager fm = getSupportFragmentManager() ;
  8. Fragment fragment = fm.findFragmentById(R.id.fragment_container);
  9. if(fragment != null){
  10. Log.i("information", "true");
  11. } else{
  12. Log.i("information","false");
  13. }
  14. }
  15. }, 2000);

通过一个线程去延迟查找动作

结果是:10-14 22:18:47.436: I/information(1672): true

思路是使用线程,延迟2秒去检测。

附上一个自己Github上的简单Demo:https://github.com/lhppom/Fragment-Demo

Android之Fragment学习总结(1)的更多相关文章

  1. 33.Android之Fragment学习

    Fragment Android是在Android 3.0 (API level 11)开始引入Fragment的. 可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的 ...

  2. Android之Fragment学习笔记①

    Android Fragment完全解析,关于碎片你所需知道的一切 一. 什么是FragmentFragment(碎片)就是小型的Activity,它是在Android3.0时出现的.Fragment ...

  3. [android]p7-1 fragment学习笔记

    本文源自<android权威编程指南第3版>第7章UI fragment与fragment 第7章主要内容是实现一个记录不良行为的APP(部分实现),有列表,有具体的行为内容显示.第7章主 ...

  4. Android之Fragment学习笔记②(Fragment生命周期)

    一. Fragment生命周期图                                  二.Fragment生命周期方法介绍 Fragment的生命周期和activity生命周期很像,其生 ...

  5. Android应用开发学习笔记之Fragment

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Fragment翻译成中文就是“碎片”.“片断”的意思,Fragment通常用来作为一个Activity用户界面的一 ...

  6. [转]Android 使用Fragment界面向下跳转并一级级返回

      1.首先贴上项目结构图: 2.先添加一个接口文件BackHandledInterface.java,定义一个setSelectedFragment方法用于设置当前加载的Fragment在栈顶,主界 ...

  7. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  8. Android中Fragment和ViewPager那点事儿(仿微信APP)

    在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...

  9. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

随机推荐

  1. centos6.4安装VMwareTools

    centos6.4安装VMware Tools,同样适用于VMware.ESXi.Hypervisor #如果文件不存在需要创建 mkdir /mnt/cdrom #挂载光驱 mount -t aut ...

  2. win7以管理员身份运行bat提示系统找不到指定的路径。

    windows7“以管理员身份运行”bat提示“系统找不到指定的路径.” 使用批处理安装服务,直接双击运行没有权限,右键“以管理员身份运行”却提示“系统找不到指定的路径.”,反复查看路径是正确的. 打 ...

  3. RNN神经网络和英中机器翻译的实现

    本文系qitta的文章翻译而成,由renzhe0009实现.转载请注明以上信息,谢谢合作. 本文主要讲解以recurrent neural network为主,以及使用Chainer和自然语言处理其中 ...

  4. [转载]:Fortran字符串的故事

    一. Fortran 字符串与 C 字符串的区别  Fortran的字符串处理能力其实很弱,关于字符串的语法还很落后.它与 C 字符串最大的区别就是:Fortran字符串是固定长度的,没有 \0 结束 ...

  5. 关于隐藏input输入内容问题

    如果想通过获取焦点输入改变内容,type不能是hidden的 <input type="hidden" id="test"> // 这种是不行的,只 ...

  6. NUGET命令

    主题 about_NuGet 简短说明 提供有关 NuGet 程序包管理器命令的信息. 详细说明 本主题介绍 NuGet 程序包管理器命令.NuGet 是一种集成的程序包 管理工具,用于将库和工具添加 ...

  7. 2008server安装Intel I217V网卡驱动

    问题:由于在职的是小公司,公司服务器都是DIY的,拒绝采购品牌服务器,所以配件都是自己DIY的,这样就会出现很多兼容性问题,例如服务器主板是AUS B85-PRO-Gamer,装的是服务器系统wind ...

  8. PHP指定字段的多维数组排序方法

    PHP数组排序可以用array_multisort方法实现,但是如果是多维数组,并且我们要指定数组中的某个字段进行排序,那么这就需要我们自己写方法实现了. function sortArrByFiel ...

  9. NHibernate系列文章十二:Load/Get方法

    摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...

  10. projecteuler Problem 8 Largest product in a series

    The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = ...