Fragment在FrameLayout

来源:互联网 发布:mac桌面图标怎么靠左 编辑:程序博客网 时间:2024/05/18 07:14

Fragment

  • API11(Android3.0)中引入了Fragment,由FragmentManager来管理。
  • Fragment extends object 。
  • Fragment也是Activity中的一个普通控件而已,只不过它可以像Activity一样用于显示的同时还能用来盛装其它控件,并且有类似Activity的lifecycle。
  • 可被多个Acitivity重用, 在Acitivity运行中动态地移除、加入、交换等。
  • 兼容API11(Android3.0)以前版本使用 v4.app.Fragment,Acitivity需要继承AppCompatActivity,通过getSupportFragmentManager() 获得v4.app.FragmentManager 。
  • API11(Android3.0)以后可使用 app.Fragment,通过getFragmentManager()获得app.FragmentManager 。

生命周期lifecycle

  • 类似Acitivty,但是由Activity管理,由许多不同点。
    这里写图片描述

简单添加到Activity方法

 private void add() {        OneFragment oneFragment = OneFragment.newInstance("");        FragmentTransaction transaction = mManager.beginTransaction();        transaction.add(R.id.fl_container, oneFragment, "one");        transaction.commit();    }
  • 将Fragment添加到Activity中,并生效。
  • 重要的类有FragmentManager 和FragmentTransaction,在下面详细分析。

Fragment相关的类及其方法

FragmentManager

  • FragmentManager是一个抽象类, getFragmentManager()获取的是FragmentManagerImpl ,是一个实现类
//调用层级 最后是FragmentManagerImpl getFragmentManager()    -->FragmentController(Fragment's lifecycle)  -->getFragmentManagerImpl()  -->FragmentHostCallback   -->final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
  • FragmentManager.java中 定义FragmentManager /FragmentManagerImpl / FragmentManagerState三个类/接口

  • beginTransaction() 获得FragmentTransaction,FragmentManagerImpl 中的Override的beginTransaction()

 @Override    public FragmentTransaction beginTransaction() {        return new BackStackRecord(this);    }
  • findFragmentById(@IdRes int id) 相同id ,取第一个找到的,一般就是最上面的。
  • findFragmentByTag(String tag) 相同tag,取第一个找到的,一般就是最上面的。
  • getFragments() 返回ArrayList< Fragment > mActive; 可能存在null
  • 持有一个BackStackRecord的列表 ArrayList< BackStackRecord > mBackStackIndices

FragmentTransaction

  • add 和 replace 影响的只是界面,而控制回退的,是事务

  • FragmentTransaction 是一个抽象类, beginTransaction()获取的是BackStackRecord,是一个实现类

  • BackStackRecord extends FragmentTransaction

  • add 和 replace 影响的只是界面,而控制回退的是事务,add 和 replace最后调用addOp(Op op)
  • addOp(Op op) 添加到队列mOps中,通过commit才会提交

    void addOp(Op op) {      mOps.add(op);      op.enterAnim = mEnterAnim;      op.exitAnim = mExitAnim;      op.popEnterAnim = mPopEnterAnim;      op.popExitAnim = mPopExitAnim;  }
  • addToBackStack(将事务添加到回退栈里)

    @Override  public FragmentTransaction addToBackStack(String name) {      if (!mAllowAddToBackStack) {          throw new IllegalStateException(                  "This FragmentTransaction is not allowed to be added to the back stack.");      }      mAddToBackStack = true;      mName = name;      return this;  }
  • commit (提交到处理队列里,默认不会添加到回退栈,默认等待执行),调用commitInternal(false)

    int commitInternal(boolean allowStateLoss) {      if (mCommitted) throw new IllegalStateException("commit already called");      if (FragmentManagerImpl.DEBUG) {          Log.v(TAG, "Commit: " + this);          LogWriter logw = new LogWriter(TAG);          PrintWriter pw = new PrintWriter(logw);          dump("  ", null, pw, null);          pw.close();      }      mCommitted = true;      if (mAddToBackStack) {          mIndex = mManager.allocBackStackIndex(this);      } else {          mIndex = -1;      }      mManager.enqueueAction(this, allowStateLoss);      return mIndex;  }
add
  • add(@IdRes int containerViewId, Fragment fragment)
  • 可能出现 Fragment already added 错误,原因:add 已经add的fragment(hashcode一样)
  • lifecycle方法调用情况
10-23 17:01:58.737 13673-13673/com.wega.android E/Frag+Frame: OneFragment==null==OneFragment10-23 17:01:58.743 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onAttach10-23 17:01:58.744 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onCreate10-23 17:01:58.744 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onCreateView10-23 17:01:58.753 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onActivityCreated10-23 17:01:58.753 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onStart10-23 17:01:58.753 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onResume
  • 在add 前 需要new Fragment() ,但是new不会调起Framgent生命周期动作如:oncreate ,而 Acitivty不需要我们new的,是由系统创建的.
remove
  • remove(Fragment fragment)
  • Remove an existing fragment
  • 先获得已存在fragment才能remove 不能传空值
  • 通过findFragmentById() findFragmentByTag()获得已存在fragment
  • lifecycle方法调用情况
10-23 17:02:55.873 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onPause10-23 17:02:55.874 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onStop10-23 17:02:55.874 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onDestroyView10-23 17:02:55.874 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onDestroy10-23 17:02:55.874 13673-13673/com.wega.android E/Frag+Frame: OneFragment==0==onDetach
replace
  • replace(@IdRes int containerViewId, Fragment fragment)
  • 不能传空值
  • 先remove掉相同id的所有fragment,然后在add当前的这个fragment
  • add 和 remove 结合
  • lifecycle方法调用情况
10-23 17:07:11.092 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==OneFragment10-23 17:07:11.098 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onAttach10-23 17:07:11.098 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onCreate10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==0==onPause10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==0==onStop10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==0==onDestroyView10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==0==onDestroy10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==0==onDetach10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onCreateView10-23 17:07:11.099 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onActivityCreated10-23 17:07:11.100 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onStart10-23 17:07:11.100 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onResume
hide
  • hide(Fragment fragment)
  • 与show一起作用
  • hide 已经添加的fragment 不能传空值
  • hide fragment 不会调用生命周期
show
  • show(Fragment fragment)
  • 与hide一起作用
  • This is only relevant for fragments whose views have been added to a container
  • show已经hide的fragment
  • show fragment 不会调用生命周期
detach
  • detach(Fragment fragment)
  • 与attach一起作用
  • 不能传空值
  • lifecycle方法调用情况
10-23 17:07:41.687 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onPause10-23 17:07:41.687 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onStop10-23 17:07:41.687 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onDestroyView
attach

-attach(Fragment fragment)
- 与detach一起作用
- 不能传空值
- lifecycle方法调用情况

10-23 17:07:56.420 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onCreateView10-23 17:07:56.420 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onActivityCreated10-23 17:07:56.421 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onStart10-23 17:07:56.421 24280-24280/com.wega.android E/Frag+Frame: OneFragment==null==onResume

重建 切屏

  • Fragment也有onSaveInstanceState的方法,在此方法中进行保存数据,然后在onCreate或者onCreateView或者onActivityCreated进行恢复都可以。
 @Override    public void onSaveInstanceState(Bundle outState) {        outState.putString("name", "save");        super.onSaveInstanceState(outState);        Log.e("Activity", TAG +"=="+mTag1+"=="+"onSaveInstanceState"+"=="+outState.getString("name"));    } @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if(savedInstanceState!=null)        {            Log.e("Activity", TAG +"=="+mTag1+"=="+"onCreate"+"=="+savedInstanceState.getString("name"));        }        Bundle arguments = getArguments();        if(arguments!=null)        {            mTag1 = arguments.getString("tag");        }        Log.e("Activity", TAG +"=="+mTag1+"=="+"onCreate");    }

demo源码

FragmentActivity

package com.wega.android.fragment;import android.content.DialogInterface;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import com.wega.android.R;import java.util.List;public class FragmentActivity extends AppCompatActivity implements View.OnClickListener {    private String LOG_TAG="Frag+Frame";    private FragmentManager mManager;    private OneFragment mOneFragment;    private String TAG;    private int num;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_fragment);        mManager = getSupportFragmentManager();        TAG = this.getClass().getSimpleName();        if (savedInstanceState == null) {            Log.e(LOG_TAG, TAG + "==onCreate");        } else {            String name = savedInstanceState.getString("name");            Log.e(LOG_TAG, TAG + "==onCreate==name==" + name);        }        findViewById(R.id.add).setOnClickListener(this);        findViewById(R.id.remove).setOnClickListener(this);        findViewById(R.id.replace).setOnClickListener(this);        findViewById(R.id.log).setOnClickListener(this);        findViewById(R.id.show).setOnClickListener(this);        findViewById(R.id.hide).setOnClickListener(this);        findViewById(R.id.attach).setOnClickListener(this);        findViewById(R.id.detach).setOnClickListener(this);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.add:                add();                break;            case R.id.remove:                remove();                break;            case R.id.replace:                replace();                break;            case R.id.show:                show();                break;            case R.id.hide:                hide();                break;            case R.id.log:                getFragmentList();                break;            case R.id.attach:                attach();                break;            case R.id.detach:                detach();                break;        }    }    private void add() {        OneFragment oneFragment = OneFragment.newInstance("" + num++);        FragmentTransaction transaction = mManager.beginTransaction();        transaction.add(R.id.fl_container, oneFragment, "one");        transaction.commit();    }    private void remove(){        Fragment fragmentById = mManager.findFragmentById(R.id.fl_container);        FragmentTransaction transaction = mManager.beginTransaction();        if(fragmentById!=null)        {            transaction.remove(fragmentById);        }        transaction.commit();    }    private void replace() {        if (mOneFragment == null) {            mOneFragment = new OneFragment();        }        FragmentTransaction transaction = mManager.beginTransaction();        transaction.replace(R.id.fl_container, mOneFragment);        transaction.commit();    }    private void show() {        Fragment fragmentById = mManager.findFragmentById(R.id.fl_container);        FragmentTransaction transaction = mManager.beginTransaction();        transaction.show(fragmentById);        transaction.commit();    }    private void hide() {        Fragment fragmentById = mManager.findFragmentById(R.id.fl_container);        FragmentTransaction transaction = mManager.beginTransaction();        transaction.hide(fragmentById);        transaction.commit();    }    private void attach() {        Fragment fragmentById = mManager.findFragmentById(R.id.fl_container);        FragmentTransaction transaction = mManager.beginTransaction();        transaction.attach(fragmentById);        transaction.commit();    }    private void detach() {        Fragment fragmentById = mManager.findFragmentById(R.id.fl_container);        FragmentTransaction transaction = mManager.beginTransaction();        transaction.detach(fragmentById);        transaction.commit();    }    private void getFragmentList() {        Fragment fragment = mManager.findFragmentById(R.id.fl_container);        Fragment fragment1 = mManager.findFragmentByTag("one");        if (fragment != null) {            Log.e("fragment", "findFragmentById=" + fragment.toString());        }        if (fragment1 != null) {            Log.e("fragments1", "findFragmentByTag=" + fragment1.toString());        }        List<Fragment> fragments = mManager.getFragments();        if (fragments == null) {            return;        }        for (int i = 0; i < fragments.size(); i++) {            if (fragments.get(i) == null) {                Log.e("fragments", "null");            } else {                Log.e("fragments", fragments.get(i).toString());            }        }        Log.e("fragments", "==========");    }}

OneFragment

package com.wega.android.fragment;import android.content.Context;import android.os.Bundle;import android.support.annotation.Nullable;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.TextView;import com.wega.android.R;/** * A simple {@link Fragment} subclass. */public class OneFragment extends Fragment {    private String TAG;    private String LOG_TAG="Frag+Frame";    private String mTag1;    public OneFragment() {        TAG =this.getClass().getSimpleName();        Bundle arguments = getArguments();        if(arguments!=null)        {            mTag1 = arguments.getString("tag");        }        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"OneFragment");    }    public static OneFragment newInstance(String tag) {        Bundle args = new Bundle();        args.putString("tag",tag);        OneFragment fragment = new OneFragment();        fragment.setArguments(args);        return fragment;    }    @Override    public void onAttach(Context context) {        super.onAttach(context);        Bundle arguments = getArguments();        if(arguments!=null)        {            mTag1 = arguments.getString("tag");        }        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onAttach");    }    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if(savedInstanceState!=null)        {            Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onCreate"+"=="+savedInstanceState.getString("name"));        }        Bundle arguments = getArguments();        if(arguments!=null)        {            mTag1 = arguments.getString("tag");        }        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onCreate");    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        TAG =this.getClass().getSimpleName();        Bundle arguments = getArguments();        if(arguments!=null)        {            mTag1 = arguments.getString("tag");        }        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onCreateView");        View inflate = inflater.inflate(R.layout.fragment_one, container, false);        TextView viewById = (TextView) inflate.findViewById(R.id.tv_hashcode);        viewById.setText(this.toString()+"tag=="+mTag1);        return inflate;    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onActivityCreated");    }    @Override    public void onStart() {        super.onStart();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onStart");    }    @Override    public void onResume() {        super.onResume();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onResume");    }    @Override    public void onPause() {        super.onPause();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onPause");    }    @Override    public void onStop() {        super.onStop();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onStop");    }    @Override    public void onDestroyView() {        super.onDestroyView();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onDestroyView");    }    @Override    public void onDestroy() {        super.onDestroy();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onDestroy");    }    @Override    public void onDetach() {        super.onDetach();        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onDetach");    }    @Override    public void onSaveInstanceState(Bundle outState) {        outState.putString("name", "save");        super.onSaveInstanceState(outState);        Log.e(LOG_TAG, TAG +"=="+mTag1+"=="+"onSaveInstanceState"+"=="+outState.getString("name"));    }}

demo源码地址

github demo源码地址:https://github.com/LinweiJ/Android

backStack

未完待续

原创粉丝点击