美文网首页
Fragment 与 Activity 通信

Fragment 与 Activity 通信

作者: 珞神 | 来源:发表于2017-10-10 14:27 被阅读0次

    前言

    • 本来打算把 Fragment 的内容写完,结果写着写着发现这个篇幅已经够长了,所以就先写通信这一块了,其他的另起篇幅

    正文

    一、 Fragment 与 Activity 通信

    • 所有的 Fragment 都是依附于 Activity 存在的,而通信则是 Fragment 与 Activity 之间相互传递数据。

    • 一个 Activity 可以替换多个 Fragment ,Activity 就是这多个 Fragment 的管理者,考虑到 Fragment 的复用性,尽量降低 Fragment 与 Fragment 之间的耦合,不要用一个 Fragment 来操作另一个 Fragment,使用 Activity 来操作 Fragment

    1. Activity 向 Fragment 传递数据
    通过 bundle
    • 在动态添加 Fragment 的过程中,我们在 Activity 中通过 Fragment.setArguments() 的方法为 Fragment 提供数据,setArguments 方法需要传递一个 Bundle,把需要传递的数据放在 Bundle 中即可
    Bundle bundle = new Bundle();
    bundle.putString("name","zhangsan");
    firstFragment.setArguments(bundle);
    
    • 在 Fragment 中,在 onAttach() 函数中通过调用 getArguments() 获得一个 Bundle 对象,从而获取我们提供的数据。
        @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        name = (String) getArguments().get("name");
    }
    
    2. 在Fragment中可以通过 getActivity 得到当前绑定的 Activity 的实例,然后进行操作。
    • 假如 Fragment 依附的 Activity 中有这样一个方法:
    public String getName(){
    
        return "lisi";
    }
    
    • 在 Fragment 中可以这样获取
    HuiTuiZhanActivity activity = (HuiTuiZhanActivity) getActivity();
    String name = activity.getName();
    
    3. 实现Fragment 中改变 Activity 中的控件内容

    通过设置回调接口来实现该效果

    • Fragment 中的代码如下所示:
    package com.example.administrator.fragment_text.huituizhan;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    
    import com.example.administrator.fragment_text.R;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    import butterknife.Unbinder;
    
    
    /**
     * Created by Administrator on 2017/4/10.
     */
    
    public class FirstFragment extends Fragment {
    
        @BindView(R.id.editText)
        EditText editText;
        @BindView(R.id.btn)
        Button btn;
        Unbinder unbinder;
        @BindView(R.id.bt2n)
        Button bt2n;
    
        private String name;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
            Log.i("FirstFragment", "onCreateView");
            View inflate = inflater.inflate(R.layout.huituizhan_first_fragment, container, false);
            unbinder = ButterKnife.bind(this, inflate);
            return inflate;
        }
    
    
        /**
         * 点击第一个按钮切换到 SecondFragment
         *点击第二个按钮触发自定义接口中的方法,具体做什么就看宿主 Activity
         */
        @OnClick({R.id.btn, R.id.bt2n})
        public void onViewClicked(View view) {
    
            switch (view.getId()) {
                case R.id.btn:
                    FragmentManager fragmentManager = getFragmentManager();
    
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
                    SecondFragment secondFragment = new SecondFragment();
    
                    fragmentTransaction.hide(this);
    //        fragmentTransaction.remove(this);
                    fragmentTransaction.add(R.id.framelayout, secondFragment, "second");
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                    break;
                case R.id.bt2n:
                    //当需要切换 Activity 中的 TextView 的时候触发该接口中的方法
                    onBt2nClickListener.OnBt2nClick();
                    break;
            }
    
    
        }
    
        private OnBt2nClickListener onBt2nClickListener;
    
    
        public void setOnBt2nClickListener(OnBt2nClickListener onBt2nClickListener){
            this.onBt2nClickListener = onBt2nClickListener;
        }
    
        /**
         * 自定义回调接口
         */
        public interface OnBt2nClickListener{
    
            public void OnBt2nClick();
    
        }
    }
    
    
    • Activity 中的代码如下所示:
    package com.example.administrator.fragment_text.huituizhan;
    
    import android.os.Bundle;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.TextView;
    
    import com.example.administrator.fragment_text.R;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    
    public class HuiTuiZhanActivity extends AppCompatActivity {
    
        @BindView(R.id.framelayout)
        FrameLayout framelayout;
        @BindView(R.id.textView)
        TextView textView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_hui_tui_zhan);
            ButterKnife.bind(this);
    
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
    
            FirstFragment firstFragment = new FirstFragment();
    
            Bundle bundle = new Bundle();
            bundle.putString("name", "zhangsan");
            firstFragment.setArguments(bundle);
            fragmentTransaction.add(R.id.framelayout, firstFragment, "first").commit();
    
    
    
        }
    
    
        @Override
        protected void onResume() {
            super.onResume();
            FirstFragment first = (FirstFragment) getSupportFragmentManager().findFragmentByTag("first");
            first.setOnBt2nClickListener(new FirstFragment.OnBt2nClickListener() {
                @Override
                public void OnBt2nClick() {
                    textView.setText("珞神");
                }
            });
        }
    }
    
    

    这样就实现了,在点击 Fragment 中的按钮的时候,改变 Activity 中的 TextView 显示的内容,并且降低 Fragment 与 Activity 的耦合性,并增强了 Fragment 的复用性,哪个 Activity 都能用这个 Fragment

    4. 实现 Fragment 来操作另一个 Fragment

    Fragment1 操作另一个 Fragment2,不应在Fragment1 中直接来操作,应该交给他们共同的宿主 Activity 来操作,也是通过设置接口来实现。

    测试逻辑概述: FirstFragment 中的按钮切换 Activity 中的 TextView ,SecondFragment 中的按钮切换 ThreeFragment

    • FirstFragment 中的代码:
    package com.example.administrator.fragment_text.huituizhan;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    
    import com.example.administrator.fragment_text.R;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    import butterknife.Unbinder;
    
    
    /**
     * Created by Administrator on 2017/4/10.
     */
    
    public class FirstFragment extends Fragment {
    
        @BindView(R.id.editText)
        EditText editText;
        @BindView(R.id.btn)
        Button btn;
        Unbinder unbinder;
        @BindView(R.id.bt2n)
        Button bt2n;
    
        private String name;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
            Log.i("FirstFragment", "onCreateView");
            View inflate = inflater.inflate(R.layout.huituizhan_first_fragment, container, false);
            unbinder = ButterKnife.bind(this, inflate);
            editText.setText(name);
            return inflate;
        }
    
        /**
         * 点击按钮切换到 SecondFragment
         */
        @OnClick({R.id.btn, R.id.bt2n})
        public void onViewClicked(View view) {
    
            switch (view.getId()) {
                case R.id.btn:
                    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
                    SecondFragment secondFragment = new SecondFragment();
    
                    fragmentTransaction.hide(this);
                    fragmentTransaction.add(R.id.framelayout, secondFragment, "second");
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                    break;
                case R.id.bt2n:
                    //如果宿主 Activity 实现了此接口
                    if (getActivity() instanceof OnBt2nClickListener) {
    
                        //当需要切换 Activity 中的 TextView 的时候触发该接口中的方法
                        ((OnBt2nClickListener) getActivity()).OnBt2nClick();
                    }
                    break;
            }
    
    
        }
    
    //    private OnBt2nClickListener onBt2nClickListener;
    //
    //
    //    public void setOnBt2nClickListener(OnBt2nClickListener onBt2nClickListener){
    //        this.onBt2nClickListener = onBt2nClickListener;
    //    }
    
        /**
         * 自定义回调接口
         */
        public interface OnBt2nClickListener {
    
            public void OnBt2nClick();
    
        }
    }
    
    

    注意: 这里的回调采用了另一种方式:

    //如果宿主 Activity 实现了此接口
    if (getActivity() instanceof OnBt2nClickListener) {
    
        //当需要切换 Activity 中的 TextView 的时候触发该接口中的方法
        ((OnBt2nClickListener) getActivity()).OnBt2nClick();
        }
    
    • SecondFragment 中的代码:
    package com.example.administrator.fragment_text.huituizhan;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    
    import com.example.administrator.fragment_text.R;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    import butterknife.Unbinder;
    
    
    /**
     * Created by Administrator on 2017/4/10.
     */
    
    public class SecondFragment extends Fragment {
    
        @BindView(R.id.editText)
        EditText editText;
        @BindView(R.id.btn)
        Button btn;
        Unbinder unbinder;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View inflate = inflater.inflate(R.layout.huituizhan_second_fragment, container, false);
            unbinder = ButterKnife.bind(this, inflate);
            Log.i("SecondFragment", "onCreateView");
            return inflate;
        }
    
        @OnClick(R.id.btn)
        public void onViewClicked() {
            if (getActivity() instanceof OnBt22222nClickListener) {
    
                //当需要切换 Activity 中的 TextView 的时候触发该接口中的方法
                ((OnBt22222nClickListener) getActivity()).OnBt22222nClick();
            }
    
    
        }
    
        private OnBt22222nClickListener onBt22222nClickListener;-->
    
    
        public void setOnBt22222nClickListener(OnBt22222nClickListener onBt22222nClickListener) {-->
            this.onBt22222nClickListener = onBt22222nClickListener;-->
        }
    
        /**
         * 自定义回调接口
         */
        public interface OnBt22222nClickListener {
    
            public void OnBt22222nClick();
    
        }
    
    
    }
    
    

    注意: SecondFragment 中的回调设置与 FirstFragment 中的一样,我试过按照常规方式 ( setOnBt22222nClickListener 方式 ) 设置,切换 Fragment 的时候程序崩溃,而这种方式则没问题,不知道为嘛 - -!

    • Activity 中的代码:
    package com.example.administrator.fragment_text.huituizhan;
    
    import android.os.Bundle;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.TextView;
    
    import com.example.administrator.fragment_text.R;
    
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    
    public class HuiTuiZhanActivity extends AppCompatActivity implements FirstFragment.OnBt2nClickListener, SecondFragment.OnBt22222nClickListener {
    
        @BindView(R.id.framelayout)
        FrameLayout framelayout;
        @BindView(R.id.textView)
        TextView textView;
        private SecondFragment second;
        private FirstFragment firstFragment;
        private ThreeFragment three;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_hui_tui_zhan);
            ButterKnife.bind(this);
    
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
    
            firstFragment = new FirstFragment();
    
            Bundle bundle = new Bundle();
            bundle.putString("name", "zhangsan");
            firstFragment.setArguments(bundle);
            fragmentTransaction.add(R.id.framelayout, firstFragment, "first").commit();
    
    
        }
    
        //FirstFragment 中回调的点击事件
        @Override
        public void OnBt2nClick() {
            textView.setText("珞神");
            if (second == null) {
                second = new SecondFragment();
                second.setOnBt22222nClickListener(this);
            }
    
        }
    
        //SecondFragment 中回调的点击事件
        @Override
        public void OnBt22222nClick() {
            FragmentManager fragmentManager = getSupportFragmentManager();
    
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            if (three == null) {
    
                three = new ThreeFragment();
            }
            if (second == null) {
    
                second = new SecondFragment();
            }
    //        fragmentTransaction.hide(second);
    //        fragmentTransaction.add(R.id.framelayout,three,"three");
            fragmentTransaction.replace(R.id.framelayout, three, "three");
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }
    }
    
    
    5. 通过 getFragmentManager.findFragmentByTag() 或者 findFragmentById() 获得任何 Fragment 实例,然后来操作 Fragment 中的方法。
    • 假如 Fragment 中有这样一个方法:
        public String getName(){
    
            return "珞神";
        }
    
    • 在其宿主 Activity 中可以这样操作:
    FirstFragment first = (FirstFragment) getSupportFragmentManager().findFragmentByTag("first");
    String name = first.getName();
    

    至此,完结如有错误和遗漏,一经发现,必然改正!

    相关文章

      网友评论

          本文标题:Fragment 与 Activity 通信

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