首页 技术 正文
技术 2022年11月13日
0 收藏 366 点赞 3,359 浏览 4873 个字

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,493
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,294