Fragment_学习1

什么是Fragment


Fragment更像是Activity的简化版,而且他必需是Activity的一部分。可以组合多个Fragment放在一个Activity中,也可以多个Activity共用一个Fragment.

Fragment是Activity的一个模块化,他有自己的生命周期,接受自己的输入事件,可以在Activity运行时期(onResume)添加或删除。所以我们可以把之前写在Activity中的UI拆分到Fragment中,使UI代码模块话。

Fragment也解决了不同分辨率的UI显示问题



生命周期


Fragment有一套自己的生命周期


                    

当一个fragment被创建的时候,它会经历以下状态

onAttach()                和Activity进行关联,此时可以获得Acitivity

onCreate()                系统创建Fragments 时调用,可做执行初始化工作或者当程序被暂停或停止时用来恢复状态,跟Activity 中的onCreate相当

onCreateView()         用于首次绘制用户界面的回调方法,必须返回要创建的Fragments 视图View。假如你不希望提供Fragments 用户界面则可以返回NULL。 

onActivityCreated()          

当这个fragment对用户可见的时候,它会经历以下状态。

onStart()

onResume()              在运行的activity中,并且可见。

当这个fragment进入“后台模式”的时候,它会经历以下状态。

onPause()                 用户离开这个Fragments 的时候或fragment所在的activity被不完全覆盖,这时你要提交任何应该持久的变化.

onStop()                  可能是它所在的activity处于stoped状态或是fragment被删除并添加到后退栈中了。此状态的fragment仍然存在于内中。

当这个fragment被销毁了(或者持有它的activity被销毁了),它会经历以下状态。

onPause()                          

onStop()

onDestroyView()        当fragment中的视图被移除的时候,调用这个方法。

onDetach()                当fragment和activity分离的时候,(fragment被从activity中删掉时)调用这个方法。

这里需要注意

只有当Activity进入onResumed状态后,Fragment才可以独立执行生命周期。除此之外Fragment会随着Activity的生命周期的改变而改变,比如Acitivity进入onPause,那么Fragment也会onPause.

并且当切换到另一个fragment的时候,会调用onPause-->onStop-->onDestroyView  切换回来时,onCreateView-->onActivityCreated-->onStart-->onResume   也就是说onAttach 和onCreate只调用了一次。

保存状态

Fragment也可以通过Bunlde来保存状态,当调用Activity的onSaveInstanceState()时,会调用Fragments.saveAllState()函数,把fragment状态的加到Activity的Bundle中,在下次onCreate()时Fragments.restoreAllState()。


Fragment使用


继承Fragment

public class MyFragment extends Fragment {

    public static final String ARG_ITEM_ID = "item_id";


    public MyFragment(bundle arguments) {
    setArguments(arguments);  //放入参数
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       Bundle bundle=getArguments(); //取出参数
      
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
        if (mItem != null) {
            ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.content);
        }
        return rootView;
    }
}

传入 onCreateView() 的 container 参数是你的fragment layout将被插入的父ViewGroup(来自activity的layout)。savedInstanceState 是一个 Bundle, 如果fragment是被恢复的,它提供关于fragment的之前的实例的数据。 (传入container是很重要的, 目的是为了让系统接受所要加载的layout的根view的layout参数)

inflate() 方法有3个参数:

  • 1.想要加载的layout的resource ID.
  • 2.加载的layout的父ViewGroup.
  • 3.布尔值指示在加载期间, 展开的layout是否应当附着到ViewGroup (第二个参数).
  • (在这个例子中, 指定了false, 因为系统已经把展开的layout插入到container – 传入true会在最后的layout中创建一个多余的view group.)

加载Fragment有两种方式

1.直接加入到XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		    android:layout_width="match_parent"
		    android:layout_height="match_parent"
		    android:orientation="horizontal" >


		   <fragment class="com.xuzhi.MyFragment
		     " android:id="@+id/titles" android:layout_weight="1"
		       android:layout_width="0px" android:layout_height="match_parent"
		   />
</LinearLayout>

当系统创建这个activity layout时, 它实例化每一个在layout中指定的fragment,并调用每一个上的onCreateView()方法。

注意: 每一个fragment都需要一个唯一的标识, 如果activity重启,系统可以用来恢复fragment(并且你也可以用来捕获fragment来处理事务,例如移除它.)  

有3种方法来为一个fragment提供一个标识:

.为 android:id 属性提供一个唯一ID.

.为 android:tag 属性提供一个唯一字符串.

.如果以上2个你都没有提供, 系统使用容器view的ID.


2.通过FragmentTransaction.add进Activity的GroupView中

FragmentManager fragmentManager = getFragmentManager();//获得Manager
FragmentTransaction ft = fragmentManager.beginTransaction();//获得Transaction,fragment的add,replace都是Transcation来控制
                                     
MyFragment fragment = new MyFragment();  
ft.add(R.id.fragment_container, fragment);//第一个参数为容器的ID
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);//设置切换动画
ft.addToBackStack(null);
ft.commit();//执行事务处理 

一旦用FragmentTransaction做了改变,为了使改变生效,必须调用commit()


添加一个无UI的fragment

可以添加没有View的Fragment,使用重载方法add(Fragment,Tag String) 来添加 fragment (为fragment提供一个唯一的字符串"tag", 而不是一个view ID).但因为它没有关联到一个activity layout中的一个view, 所以不会接收到onCreateView()调用. 因此不必实现此方法.

Tag并不是专门针对无UI的fragment的 – 也可以提供字符串tag给有UI的fragment – 但是如果fragment没有UI,那么这个tag是仅有的标识它的途径. 如果随后你想从activity获取这个fragment, 需要使用 findFragmentByTag()。


FragmentManager管理Fragment

.使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag() (适用于有或没有UI的fragment)获取activity中存在的fragment

.将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).

.使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.


处理Fragment事务

我们可以对fragment进行add(),remove(),replace(),以及执行其他动作.提交给Activity的每一套变化被称为一个事务, 可以使用在 FragmentTransaction 中的 API 处理.而且可以保存每一个事务到一个Activity管理的back stack,允许用户经由fragment的变化往回导航(类似于通过activity往后导航).

注意,这里保存到BackStack中的是操作过程,而不是Fragment对象。


添加变化到 FragmentTransaction的顺序不重要, 除以下例外:

.必须最后调用 commit().

.如果添加多个fragment到同一个容器, 那么添加的顺序决定了它们在view hierarchy中显示的顺序.

.当执行一个移除fragment的事务时, 如果没有调用 addToBackStack(), 那么当事务提交后, 那个fragment会被销毁. 有鉴于此, 如果调用了 addToBackStack(), 那么    fragment会被onStop(), 如果用户导航回来,它将会被恢复.


commit()

调用 commit() 并不立即执行.它将事务安排排期, 一旦准备好, 就在activity的UI线程上运行(主线程). 也可以从UI线程直接调用executePendingTransactions() 来立即执行由commit()提交的事务. 但这么做通常不必要,。

注意:只能在activity保存它的状态(当用户离开activity)之前使用commit().


与Activity通信


获得对象

一个给定的Fragment之对应他绑定的Acitivty,Fragment可以使用 getActivity() 访问Activity实例, 并且容易地执行比如在activity layout中查找一个view的任务.

View listView = getActivity().findViewById(R.id.list);

Activity也可以通过从FragmentManager获得一个到Fragment的引用来调用fragment中的方法, 使用 findFragmentById() 或 findFragmentByTag().
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment); 

为Activity创建事件回调方法

在这个例子中, OnArticleSelectedListener 接口在fragment A中声明:
public static class MyFragment extends Fragment {
		OnArticleSelectedListener mListener = null;

		// Container Activity must implement this interface
		public interface OnArticleSelectedListener {
			public void onArticleSelected(Uri articleUri);
		}

		@Override
		public void onAttach(Activity activity) {
			super.onAttach(activity);
			try {
				mListener = (OnArticleSelectedListener) activity;
			} catch (ClassCastException e) {
				throw new ClassCastException(activity.toString()
						+ " must implement OnArticleSelectedListener");
			}
		}
	}







































如果activity没有实现接口, fragment会抛出 ClassCastException 异常. 

添加项目到Action Bar
 
Fragment可以通过实现 onCreateOptionMenu() 提供菜单项给activity的选项菜单(以此类推, Action Bar也一样).为了使这个方法接收调用,无论如何, 你必须在 onCreate() 期间调用 setHasOptionsMenu() 来指出fragment愿意添加item到选项菜单(否则, fragment将接收不到对 onCreateOptionsMenu()的调用)
 
随后从fragment添加到Option菜单的任何项,都会被追加到现有菜单项的后面.当一个菜单项被选择, fragment也会接收到 对 onOptionsItemSelected() 的回调.也可以在你的fragment layout中通过调用 registerForContextMenu() 注册一个view来提供一个环境菜单.当用户打开环境菜单, fragment接收到一个对 onCreateContextMenu() 的调用.当用户选择一个项目, fragment接收到一个对onContextItemSelected() 的调用.
 
注意: 尽管你的fragment会接收到它所添加的每一个菜单项被选择后的回调,  但实际上当用户选择一个菜单项时, activity会首先接收到对应的回调.如果activity的on-item-selected回调函数实现并没有处理被选中的项目, 然后事件才会被传递到fragment的回调.


          Be Continue 







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













  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值