Fragment与Activity通信

1.概括

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()。

2.Fragment与Activity通信的最佳实践

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

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

首先看FragmentOne

    public class FragmentOne extends Fragment implements OnClickListener  
    {  
        private Button mBtn;  

        /** 
         * 设置按钮点击的回调 
         * @author zhy 
         * 
         */  
        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();  
            }  
        }  

    }  

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

再看FragmentTwo

    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)。

最后看Activity :

    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();  
        }  

    }  

虽然Fragment和Activity可以通过getActivity与findFragmentByTag或者findFragmentById,进行任何操作,甚至在Fragment里面操作另外的Fragment,但是不提倡。
Activity担任的是Fragment间类似总线一样的角色,应当由它决定Fragment如何操作。另外虽然Fragment不能响应Intent打开,但是Activity可以,Activity可以接收Intent,然后根据参数判断显示哪个Fragment。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不对法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值