首先我们新建一个fragment,在onCreate()回调方法中

作者:美狮美高梅官方网站

Buggly 统计出FragmentDialog 报错

生命周期

Android日常研发中不可避免的肯定要用到Fragment,你如何使用的呢?Compare the two methods of use,是否觉得第二种更加简洁。这时很多人肯定提出疑问:这两种使用方式有何区别,我的代码中到底使用哪种方式更好一些,以及为什么要使用这种方式 and so on,各位看官稍安勿躁,且听老衲娓娓道来。

android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment 省略: make sure class name exists, is public, and has an empty constructor that is public 

图片 1

Usage 1:

说FragmentDialog必须要有公开的无参构造器。

image

@Override
    public void initView(Bundle savedInstanceState) {
        BlankFragment mFragment = new BlankFragment();
        Bundle bundle = new Bundle();
        bundle.putString("arg1", "a");
        bundle.putString("arg2", "b");
        bundle.putString("arg3", "c");
        mFragment.setArguments(bundle);
        getFragmentManager().beginTransaction().replace(R.id.frame, mFragment).commit();
    }

目测应该是初始化FragmentDialog的时候报错。除了我们自己代码创建FragmentDialog之外,系统也会帮我们创建FragmentDialog。这也是FragmentDialog与Dialog的最大区别!

使用Fragment时,必要构建一个无参构造函数,系统会默认带。但一但写有参构造函数,就必要构建无参构造函数。一般来说我们传参数给Fragment,会通过bundle,而不会用构造方法传,代码如下:

Usage 2:

Default constructor. Every fragment must have anempty constructor, so it can be instantiated when restoring itsactivity's state. It is strongly recommended that subclasses do nothave other constructors with parameters, since these constructorswill not be called when the fragment is re-instantiated; instead,arguments can be supplied by the caller with setArguments()and later retrieved by the Fragment with getArguments().
public static MyFragment newInstance(int index){  
  MyFragment mf = new MyFragment();  
  Bundle args = new Bundle();  
  args.putInt("index",index);  
  mf.setArguments(args);  
  return mf;  
}
@Override
    public void initView(Bundle savedInstanceState) {
        getFragmentManager().beginTransaction().replace(R.id.frame, BlankFragment.newInstance("a", "b")).commit();
    }

所有的Fragment必须有无参的构造器,这样在Activity恢复的时候,会去重新初始化Fragment。这个初始化操作,就是通过反射到无参构造器进行初始化的。

(1)onAttach:onAttach()回调将在Fragment与其Activity关联之后调用。需要使用Activity的引用或者使用Activity作为其他操作的上下文,将在此回调方法中实现。
需要注意的是:将Fragment附加到Activity以后,就无法再次调用setArguments()——除了在最开始,无法向初始化参数添加内容。

首先我们新建一个fragment,我们一起来看一下android建议的fragment如何编写(请严格按照截图的来步步创建哦)

还有一点需要注意:FragmentDialog 传参的时候,应该像Fragment一样,通过setArguments()、getArguments() 进行传参。

(2)onCreate(Bundle savedInstanceState):此时的Fragment的onCreat回调时,该fragmet还没有获得Activity的onCreate()已完成的通知,所以不能将依赖于Activity视图层次结构存在性的代码放入此回调方法中。在onCreate()回调方法中,我们应该尽量避免耗时操作。此时的bundle就可以获取到activity传来的参数

图片 2

这也是出现Bug的原因之一。

@Override public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  

        Bundle args = getArguments();  
        if (args != null) {  
            mLabel = args.getCharSequence("label", mLabel);  
        }  
    }

Create BlankFragment.png

(3)onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState): 其中的Bundle为状态包与上面的bundle不一样。
注意的是:不要将视图层次结构附加到传入的ViewGroup父元素中,该关联会自动完成。如果在此回调中将碎片的视图层次结构附加到父元素,很可能会出现异常。
这句话什么意思呢?就是不要把初始化的view视图主动添加到container里面,以为这会系统自带,所以inflate函数的第三个参数必须填false,而且不能出现container.addView(v)的操作。

package com.itbird.utils;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.hikvision.base.R;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link BlankFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link BlankFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class BlankFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public BlankFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment BlankFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static BlankFragment newInstance(String param1, String param2) {
        BlankFragment fragment = new BlankFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}
View v = inflater.inflate(R.layout.hello_world, container, false);

上述代码其实就是在一个Fragment的newInstance方法中传递两个参数,并且通过fragment.setArgument保存在它自己身上,而后通过onCreate()调用的时候将这些参数取出来。这样写没什么特殊的啊,不就是用静态工厂方法传个参数么,用构造器传参数不一样处理么?No,No,No,如果仅仅是个静态工厂而已,又怎么能成为谷歌推荐呢。

(4)onActivityCreated:onActivityCreated()回调会在Activity完成其onCreate()回调之后调用。在调用onActivityCreated()之前,Activity的视图层次结构已经准备好了,这是在用户看到用户界面之前你可对用户界面执行的最后调整的地方。
强调的point:如果Activity和她的Fragment是从保存的状态重新创建的,此回调尤其重要,也可以在这里确保此Activity的其他所有Fragment已经附加到该Activity中了

实践是检验真理的唯一标准,我们一起通过一个样例来实际操作一番
fragment_main.xml

(5)Fragment与Activity相同生命周期调用:接下来的onStart()onResume()onPause()onStop()回调方法将和Activity的回调方法进行绑定,也就是说与Activity中对应的生命周期相同,因此不做过多介绍。

<?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">

    <framelayout
        android:id="@+id/layout_top"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <framelayout
        android:id="@+id/layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
</LinearLayout>

(6)onDestroyView:该回调方法在视图层次结构与Fragment分离之后调用。

图片 3

(7)onDestroy:不再使用Fragment时调用。(备注:Fragment仍然附加到Activity并任然可以找到,但是不能执行其他操作)

fragment_main.png

本文由美狮美高梅官方网站发布,转载请注明来源

关键词: