美文网首页
Fragment(一)简介

Fragment(一)简介

作者: Cris_Ma | 来源:发表于2017-05-20 16:56 被阅读0次

    Fragment

    Fragment最初是为了适应不同屏幕尺寸诞生的,它可以加载一个视图,然后对视图进行管理操作,类似于Activity,而Fragment本身又可作为一个视图模块,托管给Activity来管理。 这样就减轻了Activity的负担,大部分的功能可以在Fragment里实现,Activity只负责加载管理就可以了。

    Fragment生命周期

    Fragment与Activity类似,生命周期也有相似之处,但是多了与View和托管对象Activity有关的方法:

    • 创建:
      1.onAttach() Fragment与Activity关联时调用
      2.onCreate() Fragment初始化创建
      3.onCreateView() 建立并返回Fragment的View
      4.onViewCreated()该方法官方没有介绍,实际上会调用,View创建完成时调用
      5.onActivityCreated() 当托管该Fragment的Activity完成创建(onCreate)时调用

    • 创建完成开始运行
      1.onStart()
      2.onResume()

    • 转入后台
      1.onPause()
      2.onStop()

    以上方法与Activity是一样的,Activity调用时,Fragment也会跟着调用。

    • 结束
      1.onDestroyView()与onActivityCreated()对应,Fragment视图被移除时调用
      2.onDestroy()
      3.onDetach()与onAttach对应,与Activity解除关联时调用。

    • 状态保存与恢复
      与Activity一样,非正常退出Fragment时,也会触发 onSaveInstanceState(Bundle outState)方法,将数据保存在Bundle中,恢复的时候会调用onViewRestrored(Bundle savedInstanceState)方法。在Activity中调用的方法是onRestoreInstanceState()。

    Fragment使用

    Fragment是API 11 才引入的,使用的时候有android.app.fragment和v4支持包两个选项。获取FragmentManager的API也不同,v4包中使用getSupportedFragmentManager,直接继承的使用getFragmentManager

    静态使用Fragment

    静态使用是指将Fragment当做一个空间,定义在Layout文件中。
    先定义一个Fragment引用的layout文件:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/item_content"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center"
              android:text="Item Frament">
    </TextView>
    

    然后新建Fragment,加载视图:

    public class ItemFragment  extends Fragment {
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.item,container,false);
            return v;
        }
    }
    

    到这里Fragment的部分完成了,可以把这个Fragment当做控件在XMl中直接引用,下面是Activity的layout文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">
        <fragment
            android:id="@+id/frag_item"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.cris.miniweather.model.fragment.ItemFragment"/>
    </LinearLayout>
    

    在Activity里setContentView设置这个layout就可以了。注意fragment控件必须指定id,否则会崩溃

    动态使用Fragment

    和静态使用步骤类似,都需要先建立好Fragment和它对应的layout文件,不同的是在Activity中引用时,使用FragmentManager来管理Fragment。

    先完成Fragment使用的layout(frag_list),这里用了Recyclerview:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.RecyclerView 
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/list_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
    </android.support.v7.widget.RecyclerView>
    

    Recyclerview的对应的layout文件(item.xml),一个TextView:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/item_content"
              android:layout_width="match_parent"
              android:layout_height="50dp"
              android:gravity="center"
              android:text="Item Frament">
    </TextView>
    

    然后建立Fragment(TitleListFragment.java),这里实现的是一个最简单的recyclerview

    public class TitleListFragment extends android.support.v4.app.Fragment{
        private List<String> mItems;
         @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
             mItems = new ArrayList<>();
             for(int i = 0; i<50; i++ ){
                 String item = "Title No." + i;
                 mItems.add(item);
             }
        }
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.list_title,container,false);
            RecyclerView mRecyclerView = (RecyclerView) v.findViewById(R.id.frag_list);
            RecyclerView.LayoutManager manager=new LinearLayoutManager(getActivity());
            manager.setAutoMeasureEnabled(true);
            mRecyclerView.setLayoutManager(manager);
            mRecyclerView.setAdapter(new RecycleAdapter());
            return v;
        }
        private class RecycleHolder extends RecyclerView.ViewHolder{
            private TextView mTextView;
            public RecycleHolder(View itemView) {
                super(itemView);
                mTextView = (TextView) itemView;
            }
        }
        private class RecycleAdapter extends RecyclerView.Adapter<RecycleHolder>
        {
            @Override
            public RecycleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View TitleItemView = LayoutInflater.from(getActivity()).inflate(R.layout.item,parent,false);
                return new RecycleHolder(TitleItemView);
            }
            @Override
            public void onBindViewHolder(RecycleHolder holder, int position) {
                holder.mTextView.setText(mItems.get(position));
            }
            @Override
            public int getItemCount() {
                return mItems.size();
            }
        }
    }
    

    到这里,Fragment的部分已经完成,可以在Activity里加载它了,先设置Activity的layout文件,一个空的FrameLayout,作为Fragment的容器:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/frag_container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent">
    </FrameLayout>
    

    在Activity里加载Fragment:

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_fragment_container);
            FragmentManager fm= getSupportFragmentManager();
            if(fm.findFragmentById(R.id.frag_container) ==null) {
                fm.beginTransaction()
                        .add(R.id.frag_container, new TitleListFragment())
                        .commit();
            }
        }
    

    注意:
    1.在Activity里是用FragmentManager来管理Fragment的,findFragmentById里的参数是Fragment容器的id,返回的是它所管理的Fragment。
    2.在add方法之前,需要加一个判断,如果为null才会去添加Fragment。因为Activity非正常退出,并且被回收的时候,FragmentManager 会将它所管理的Fragment队列保存下次,Activity重新建立的时候,FragmentManager 会先回复它所保存的队列,并重建Fragment。

    Fragment常用API

    与Fragment相关的API主要有以下两大类

    • FragmentManager
    1. beginTransaction() 获取FragmentTransaction对象,用来操作Fragment
    1. findFragmentById(id) 获取id对应的父容器中的当前Fragment
    2. findFragmentByTag(String tag) 获取tag对应的Fragment,tag在add时添加
    3. getFragment(Bundle bundle, String key) 与putFragment对应,将一个Fragment对象放在Bundle数据中
    4. isDestroyed() 托管该Fragment的Activity执行onDestroy后,会返回true。
    5. void popBackStack() 将栈顶对象弹出。相当于back键
    6. saveFragmentInstanceState(Fragment f) 存储f的状态。
    • FragmentTransaction
    1. add(Fragment fragment, String tag); 调用第三个方法,containerViewId为0
    1. add(int containerViewId, Fragment fragment) 调用第三个方法,tag为null
    2. add(int containerViewId, Fragment fragment, String tag);添加fragment到container中
    3. addToBackStack(String name)添加Fragment到name返回栈中,默认为null
    4. attach(Fragment fragment) 在使用detach方法与UI解除关联之后重新关联
    5. commit() 提交事物
    6. detach(Fragment fragment) 从UI中解除Fragment的绑定。
    7. remove(Fragment fragment) 移除一个已经存在了的Fragment。
    8. hide(Fragment fragment) 隐藏一个存在的Fragment
    9. show(Fragment fragment) 显示一个之前隐藏的Fragment。
    10. replace(int containerViewId, Fragment fragment, String tag);替换一个已经存在了的Fragment(先remove,在add)

    相关文章

      网友评论

          本文标题:Fragment(一)简介

          本文链接:https://www.haomeiwen.com/subject/alkjxxtx.html