回调应用之activity与fragment

来源:互联网 发布:百度算法大全 编辑:程序博客网 时间:2024/05/23 00:10


  大家是否 对回调有了一点的认识。

所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web Service以及Java的RMI都用到回调机制,可以访问远程服务器程序。


 下面的是:C语言中回调函数解释:
回调函数(Callback Function)是怎样一种函数呢?
函数是用来被调用的,我们调用函数的方法有两种:
l         直接调用:在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应函数B的代码得以执行。这里,A称为“主叫函数”(Caller),B称为“被叫函数”(Callee)。
l         间接调用:在函数A的函数体里并不出现函数B的函数名,而是使用指向函数B的函数指针p来使内存中属于函数B的代码片断得以执行——听起来很酷,是吧。
比起直接调用来,间接调用的确麻烦,那为什么还要使用间接调用呢?原因很简单——直接调用把函数名都写进函数体了,经过编译器那么一编译,板上钉钉,A注定调用的是B了,这样的程序只能按照程序员事先设计好的流程执行下去,太呆板了。此时,间接调用的巨大灵活性就显现出来了。想一想,如果p是函数A的一个参数(参数是变量,是变量就可以变吗!),那么程序的最终用户完全可以通过操作来改变p的指向——这样,A在通过p调用函数的时候就有机会调用到不同的函数,这样程序的实用性和扩展性就强多了。



相信大家对activity 都很熟悉  ,在此就不累赘了,下面讲一下Fragment

  给一张 Activity 与 Fragment 生命周期的对比图片让大家加强 对Fragment 生命周期的记忆

                                    http://img.blog.csdn.net/20140719225005356?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG1qNjIzNTY1Nzkx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

       可以看到Fragment比Activity多了几个额外的生命周期回调方法:
1、onAttach(Activity);      //当Fragment与Activity发生关联时调用。
2、onCreateView(LayoutInflater, ViewGroup,Bundle) ; //创建该Fragment的视图
3、onActivityCreated(Bundle) ;    //当Activity的onCreate方法返回时调用
4、onDestoryView();     //与onCreateView想对应,当该Fragment的视图被移除时调用
5、onDetach();   //与onAttach相对应,当Fragment与Activity关联被取消时调用
    注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,


以下是FragmentTransaction的相关方法及说明:
       FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务
1、transaction.add()          //往Activity中添加一个Fragment
2、transaction.remove() //从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,Fragment将会被销毁。
3、transaction.replace()         //使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
4、transaction.hide()         //隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
5、transaction.show()         //显示之前隐藏的Fragment
6、detach()        //会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
7、attach()        //重建view视图,附加到UI上并显示。
8、transatcion.commit()//提交一个事务
注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。


Fragment与Activity通信

因为所有的Fragment都是依附于Activity的,所以通信起来并不复杂,大概归纳为:

a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法

b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。

c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。

注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。


因为要考虑Fragment的重复使用,所以必须降低Fragment与Activity的耦合,而且Fragment更不应该直接操作别的Fragment,毕竟Fragment操作应该由它的管理者Activity来决定。

下面我通过两种方式的代码,分别重构,FragmentOne和FragmentTwo的点击事件,以及Activity对点击事件的响应:

首先看FragmentOne

<span style="font-size:14px;">    package com.fx678.finace;            import android.app.Fragment;      import android.os.Bundle;      import android.view.LayoutInflater;      import android.view.View;      import android.view.View.OnClickListener;      import android.view.ViewGroup;      import android.widget.Button;        /**          * @author www.fx678.com         */     public class FragmentOne extends Fragment implements OnClickListener{          private Button mBtn;          /**          * 设置按钮点击的回调          */          public interface FOneBtnClickListener  {              void onFOneBtnClick();          }          @Override          public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){              View view = inflater.inflate(R.layout.fragment_one, container, false);              mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);              mBtn.setOnClickListener(this);              return view;          }          /**          * 交给宿主Activity处理,如果它希望处理          */          @Override          public void onClick(View v)  {              if (getActivity() instanceof FOneBtnClickListener)  {                  ((FOneBtnClickListener) getActivity()).onFOneBtnClick();              }          }            }  </span>

        可以看到现在的FragmentOne不和任何Activity耦合,任何Activity都可以使用;并且我们声明了一个接口,来回调其点击事件,想要管理其点击事件的Activity实现此接口就即可。可以看到我们在onClick中首先判断了当前绑定的Activity是否实现了该接口,如果实现了则调用。


再看FragmentTwo


    package com.<span style="font-size:14px;">fx678.finace</span>;            import android.app.Fragment;      import android.os.Bundle;      import android.view.LayoutInflater;      import android.view.View;      import android.view.View.OnClickListener;      import android.view.ViewGroup;      import android.widget.Button;        <span style="font-size:14px;">/**          * @author www.fx678.com         */ </span>    public class FragmentTwo extends Fragment implements OnClickListener{           private Button mBtn ;          private FTwoBtnClickListener fTwoBtnClickListener ;          public interface FTwoBtnClickListener  {              void onFTwoBtnClick();          }          //设置回调接口          public void setfTwoBtnClickListener(FTwoBtnClickListener fTwoBtnClickListener){              this.fTwoBtnClickListener = fTwoBtnClickListener;          }          @Override          public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){              View view = inflater.inflate(R.layout.fragment_two, container, false);              mBtn = (Button) view.findViewById(R.id.id_fragment_two_btn);              mBtn.setOnClickListener(this);              return view ;           }          @Override          public void onClick(View v){              if(fTwoBtnClickListener != null){                  fTwoBtnClickListener.onFTwoBtnClick();              }          }            }  



与FragmentOne极其类似,但是我们提供了setListener这样的方法,意味着Activity不仅需要实现该接口,还必须显示调用mFTwo.setfTwoBtnClickListener(this)。

最后看MainActivity :

<span style="font-size:14px;">    package com.fx678.finace;            import android.app.Activity;      import android.app.FragmentManager;      import android.app.FragmentTransaction;      import android.os.Bundle;      import android.view.Window;      import com.zhy.zhy_fragments.FragmentOne.FOneBtnClickListener;      import com.zhy.zhy_fragments.FragmentTwo.FTwoBtnClickListener;             /**          * @author www.fx678.com         */     public class MainActivity extends Activity implements FOneBtnClickListener, FTwoBtnClickListener  {                private FragmentOne mFOne;          private FragmentTwo mFTwo;          private FragmentThree mFThree;                @Override          protected void onCreate(Bundle savedInstanceState)  {              super.onCreate(savedInstanceState);              requestWindowFeature(Window.FEATURE_NO_TITLE);              setContentView(R.layout.activity_main);                    mFOne = new FragmentOne();              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.add(R.id.id_content, mFOne, "ONE");              tx.commit();          }          /**          * FragmentOne 按钮点击时的回调          */          @Override          public void onFOneBtnClick(){             if (mFTwo == null){                  mFTwo = new FragmentTwo();                  mFTwo.setfTwoBtnClickListener(this);              }              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.replace(R.id.id_content, mFTwo, "TWO");              tx.addToBackStack(null);              tx.commit();          }          /**          * FragmentTwo 按钮点击时的回调          */          @Override          public void onFTwoBtnClick(){              if (mFThree == null){                  mFThree = new FragmentThree();              }              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.hide(mFTwo);              tx.add(R.id.id_content, mFThree, "THREE");              // tx.replace(R.id.id_content, fThree, "THREE");              tx.addToBackStack(null);              tx.commit();          }            }  </span>


0 0
原创粉丝点击