android——Fragment

谷歌官方文档的介绍:html

https://developer.android.com/guide/components/fragments.html#Designjava

Fragment 表示 Activity 中的行为或用户界面部分。您能够将多个片断组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个片断。您能够将片断视为 Activity 的模块化组成部分,它具备本身的生命周期,能接收本身的输入事件,而且您能够在 Activity 运行时添加或移除片断(有点像您能够在不一样 Activity 中重复使用的“子 Activity”)。android

片断必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。 例如,当 Activity 暂停时,其中的全部片断也会暂停;当 Activity 被销毁时,全部片断也会被销毁。 不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您能够独立操纵每一个片断,如添加或移除它们。 当您执行此类片断事务时,您也能够将其添加到由 Activity 管理的返回栈 — Activity 中的每一个返回栈条目都是一条已发生片断事务的记录。 返回栈让用户能够经过按返回按钮撤消片断事务(后退)。ide

当您将片断做为 Activity 布局的一部分添加时,它存在于 Activity 视图层次结构的某个 ViewGroup 内部,而且片断会定义其本身的视图布局。您能够经过在 Activity 的布局文件中声明片断,将其做为 <fragment> 元素插入您的 Activity 布局中,或者经过将其添加到某个现有 ViewGroup,利用应用代码进行插入。不过,片断并不是必须成为 Activity 布局的一部分;您还能够将没有本身 UI 的片断用做 Activity 的不可见工做线程。模块化

 

1、使用Fragment的两种方式布局

一、在Activity的布局中加入fragmentui

  这种方式就是在Activity的布局中把fragment看成一个控件来使用,不过这等因而将视图和Activity的视图绑在一块儿,在Activity的生命周期内没法切换fragment。this

  先新建一个继承Fragment的类,重写onCreateView决定Fragemnt的布局,onCreateView里面还须要一个布局文件,右键layout→new→file 建立一个fragment.xml的布局文件  spa

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

    <EditText
        android:id="@+id/crime_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/crime_tittle_hint"/>

</LinearLayout>

  这个布局是怎样,是无所谓的,只根据需求来编写便可。线程

  而后在继承Fragment的类里,重写onCreateView将这个加载这个布局

public class Fragment1 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.fragment, container, false);
        return view;
    }
}

调用LayoutInflater的inglate()方法加载布局,第一个参数是布局资源的ID,第二个参数是视图的父视图。

而后在活动的布局文件中Activity中使用这个Fragment,就当和普通的View同样

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    

    <fragment
        android:id="@+id/id_fragment_content"
        android:name="xbt.exp22.Fragment1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

 

二、在Activity的代码中加入fragment

  这种能够在运行时控制fragment能够自行决定加载那一个fragment,也能够移除,换一个fragment

修改活动的布局,把以前的碎片view删掉,加入一个按钮和一个FrameLayout,给FrameLayout设置一个ID

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:id="@+id/fragment"
        android:layout_below="@id/button1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

修改活动的代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1= (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.FrameLayout,new Fragment1());
                transaction.commit();
            }
        });
    }
}

按钮响应的内容是:使用getFragmentManager();获取FragmentManager,使用beginTransaction();开启一个事务transaction,而后向容器添加或替换片断,须要传入容器的id和片断,而后使用commit()提交事务。其中FragmentTransaction()的replace方法第一个参数是想要放片断的布局的id,第二个参数就是想要放入的片断的一个对象。这样就能实现点击按钮以后片断才出现。

这里的添加碎片fragment还能够这样写:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1= (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction()
                            .add(R.id.FrameLayout,new Fragment1())
                            .commit();
            }
        });
    }
}

 

总的来讲过程其实大致都是同样的,

一、Activity使用FragmentManager来管理fragment队列,

二、FragmentManager调用beginTransation()建立一个FragmentTransaction(),

三、调用add()或replace()告诉FragmentManager,fragment视图应该出如今activity视图的那个位置,使用那一个fragment。

四、最后提交事务调用commit()

 

2、将一个片断替换成另外一个片断:

须要新建一个fragment类和它的布局:

fragment类Fragment2.class:

public class Fragment2 extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view =  inflater.inflate(R.layout.fragment2, container, false);
            return view;
        }
}

布局:fragment2.xml:

<?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:id="@+id/crime_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="第二个片断"/>

</LinearLayout>

活动的java代码:

  Button button2 = (Button) findViewById(R.id.button2);
  button2.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
           FragmentManager fragmentManager = getFragmentManager();
           fragmentManager.beginTransaction()
               .replace(R.id.FrameLayout,new Fragment2())
               .addToBackStack(null)
               .commit();
            }
        });

新的Fragment替换在 R.id.fragment_container ID 所标识的布局容器中的任何片断(若有),经过调用 addToBackStack() 可将替换事务保存到返回栈,以便用户可以经过按返回按钮撤消事务并回退到上一片断。

若是您向事务添加了多个更改(如又一个 add() 或 remove()),而且调用了 addToBackStack(),则在调用 commit() 前应用的全部更改都将做为单一事务添加到返回栈,而且返回按钮会将它们一并撤消。

向 FragmentTransaction 添加多个更改的顺序可有可无,不过:

  • 必须最后调用 commit()
  • 若是要向同一容器添加多个片断,则您添加片断的顺序将决定它们在视图层次结构中的出现顺序

若是没有在执行移除片断的事务时调用 addToBackStack(),则事务提交时该片断会被销毁,用户将没法回退到该片断。 不过,若是您在删除片断时调用了 addToBackStack(),则系统会中止该片断,并在用户回退时将其恢复。

 

2、fragment的生命周期

图片.Activity 生命周期对片断生命周期的影响

 

片断生命周期与管理 Activity 生命周期很类似。和 Activity 同样,片断也以三种状态存在:

Resumed

  片断在运行中的 Activity 中可见。

Paused

  另外一个 Activity 位于前台并具备焦点,但此片断所在的 Activity 仍然可见(前台 Activity 部分透明,或未覆盖整个屏幕)。

Stoped

  片断不可见。宿主 Activity 已中止,或片断已从 Activity 中移除,但已添加到返回栈。 中止片断仍然处于活动状态(系统会保留全部状态和成员信息)。 不过,它对用户再也不可见,若是 Activity 被终止,它也会被终止。

 

和Activity 同样,假使 Activity 的进程被终止,在重建 Activity 时须要恢复片断状态,也可使用 Bundle 保留片断的状态。能够在片断的 onSaveInstanceState() 回调期间保存状态,并可在 onCreate()onCreateView() 或 onActivityCreated() 期间恢复状态。

Activity 生命周期与片断生命周期之间的最显著差别在于它们在其各自返回栈中的存储方式。 默认状况下,Activity 中止时会被放入由系统管理的 Activity 返回栈(也就是打开另外一个活动以后当前活动就会处于中止状态,点击返回按钮后就会自动恢复)。不过,可是若是在执行移除片断的事务执行期间不经过调用 addToBackStack() 显式请求保存实例时,系统不会将片断放入由宿主 Activity 管理的返回栈,也就是说按返回就不会恢复。

 

一个例子:新建一个拥有一个按钮的SecondActivity,这个按钮的响应是使用Intent启动一个MainActivity, 将MainActivity中的两个按钮的响应修改成启动一个SecondActivity和销毁本活动,在MainActivity中静态加载一个片断,在该片断中将器生命周期内的每个方法都重写输出日志方法名字

活动的java代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = (Button) findViewById(R.id.button1);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });

        Button button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        Log.d("message","MainActivity:onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("message","MainActivity:onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("message","MainActivity:onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("message","MainActivity:onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("message","MainActivity:onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("message","MainActivity:onDestroy");
    }
}

片断的java代码:

public class Fragment1 extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("message","Fragment1:onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("message","Fragment1:onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.fragment, container, false);
        Log.d("message","Fragment1:onCreateView");
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d("message","Fragment1:onActivityCreated");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d("message","Fragment1:onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("message","Fragment1:onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("message","Fragment1:onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("message","Fragment1:onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("message","Fragment1:onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("message","Fragment1:onDestroy");

    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("message","Fragment1:onDetach");
    }
}

刚启动应用程序时:

启动SecondActivity:

在SecondActivity启动一个MainActivity:

点击返回到SecondActivity

再点击返回

点击第二个按钮销毁活动

以上就是片断跟随活动的生命周期状态变化自身状态随之变化并调用相应方法的验证。

相关文章
相关标签/搜索