对于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)的更多相关文章

  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. 文件上传时jquery.form.js中提示form.submit SCRIPT5: 拒绝访问

    利用其它控件触发file的click事件来选择文件后,使用jquery.form.js中的submit方法提交时IE报错:form.submit SCRIPT5: 拒绝访问,其它浏览器正常, < ...

  2. javaSwing文本框组件

    public class JTextFieldTest extends JFrame{    private static final long serialVersionUID = 1L;    p ...

  3. Chap5: question: 29 - 31

    29. 数组中出现次数超过一半的数字. 方法a. 排序取中       O(nlogn). 方法b. partition 函数分割找中位数     >=O(n). 方法c. 设计数变量,扫描一遍 ...

  4. Windows下利用Windbg 分析dump

    概述: 注册生成dump文件的函数. 当程序收到没有捕获的异常时,调用上述函数,生成dump文件. 利用Windbg结合编译程序时生成的pdb和代码来分析dump文件,定位问题. 如下代码生成dump ...

  5. gcc与makefile编译 BY 四喜三顺

    gcc编译控制过程:(假设源代码为a.c)(1)源文件到预处理文件:    gcc -E -o a.cxx a.c    a.cxx显示调用哪些头文件(2)生成汇编代码:              g ...

  6. bash操作小结

    刚开始学写bash脚本,发现有很多需要注意的细节问题,在这里记录一下便于记忆: 1. help test  帮助 2. bash提供的数组数据结构,它是以数字为下标的,和C语言从0开始的下一样  参考 ...

  7. MSsql bcp

    --将test_1表导出在F盘根目录下/ reconfigure EXEC master..xp_cmdshell 'bcp test.dbo.test_1 out f:\abc.txt -c -q ...

  8. 【转】对抗拖库 ―― Web 前端慢加密

    0×00 前言 天下武功,唯快不破.但密码加密不同.算法越快,越容易破. 0×01 暴力破解 密码破解,就是把加密后的密码还原成明文密码.似乎有不少方法,但最终都得走一条路:暴力穷举.也许你会说还可以 ...

  9. c#基础-oop(面向对象理解)

    OOP-面向对象 封装,继承多态 一个桌子,用面向对象来描述一下它这个桌子项目 定义桌子类 对象:桌子 桌子的属性:名字,材质,体积 桌子的方法;放东西(方法) 现在桌子要放书,放花瓶,放文件(这里就 ...

  10. 数据库dump导入

    数据库dump导入 一.导入命令介绍: Oracle dump数据导入导出有两种方式:imp/exp.impdp/expdp.两者区别: 1.exp/imp客户端程序,受网络,磁盘的影响:impdp/ ...