Android 小技巧之 Fragment 与 Activity 之间通信

时间:2021-7-21 作者:qvyue

一、Activity 之间数据通信

1. Bundle

此方法可以传递基本数据类型和 String 类型的数据,如果传递的是对象就需要进行序列化(Parcelable)。

Bundle bundle = new Bundle();
bundle.putString("name", "chenjy");
bundle.putInt("age", 18);

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtras(bundle);
startActivity(intent);

2. 静态变量/全局变量及Application/Android 系统剪切板

这三种方式其实非常相似,静态变量和全局变量都可以采用 static 的方式来定义,如果采用这种方式还是推荐用一个专门的类结合单体模式进行管理,尽量减少对内存的消耗。

3. EventBus

EventBus 是一款针对 Android 的发布以及订阅事件总线,使用它可以很方便的进行信息传递,而且使用起来很方便。
首先是定义一个消息:

public class Event {
    private String message;
    public Event(){
        message = "EventBus message";
    }

    public void setMessage(String message){
        this.message = message;
    }

    public String getMessage(){
        return message;
    }
}

发送消息:
这里使用了postSticky,这是发送的粘性广播,使用这个发送就可以先发送信息再进行注册,后注册的也能接收到前面发送的广播。当然还有其他的使用方式,可以查查api文档。

EventBus.getDefault().postSticky(new Event());
startActivity(new Intent(MainActivity.this,ReceiveActivity.class));

注册事件的订阅者:

EventBus.getDefault().register(this);

接受粘性广播:

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEventThread(Event event) {
    textView.setText(event.getMessage());
}

二、Fragment 之间数据通信

1. 接口回调

step1. 在Menuragment中创建一个接口以及接口对应的set方法:

//MenuFragment.java文件中
public interface OnDataTransmissionListener {
    public void dataTransmission(String data);
}
public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
    this.mListener = mListener;
}

step2: 在MenuFragment中的ListView条目点击事件中进行接口进行接口回调

//MenuFragment.java文件中
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
   @Override
    public void onItemClick(AdapterView> parent, View view, int position, long id) {
        /**
         * 方法二:采取接口回调的方式进行数据传递
         */
        if (mListener != null) {
            mListener.dataTransmission(mDatas.get(position));
        }
    }
});

step3: 在MainActivity中根据menuFragment获取到接口的set方法,在这个方法中进行进行数据传递,具体如下:

//在MainActivity.java中
menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
    @Override
    public void dataTransmission(String data) {
        mainFragment.setData(data);  //注:对应的mainFragment此时应该要用final进行修饰
    }
});

2. EventBus

三、Fragment 与 Activity 之间数据通信

1. handler方案

public class MainActivity extends FragmentActivity{ 
      //声明一个Handler 
      public Handler mHandler = new Handler(){       
          @Override
           public void handleMessage(Message msg) { 
                super.handleMessage(msg);
                 ...相应的处理代码
           }
     }
     ...相应的处理代码
   } 

    public class MainFragment extends Fragment{ 
          //保存Activity传递的handler
           private Handler mHandler;
           @Override
           public void onAttach(Activity activity) { 
                super.onAttach(activity);
               //这个地方已经产生了耦合,若还有其他的activity,这个地方就得修改 
                if(activity instance MainActivity){ 
                      mHandler =  ((MainActivity)activity).mHandler; 
                }
           }
           ...相应的处理代码
     }

2. 广播方案

3. EventBus方案

4. 接口方案

//MainActivity实现MainFragment开放的接口 
  public class MainActivity extends FragmentActivity implements FragmentListener{ 
        @override
         public void toH5Page(){ }
       ...其他处理代码省略
   } 

    public class MainFragment extends Fragment{

         public FragmentListener mListener;  
        //MainFragment开放的接口 
        public static interface FragmentListener{ 
            //跳到h5页面
           void toH5Page();
         }

         @Override 
        public void onAttach(Activity activity) { 
              super.onAttach(activity); 
              //对传递进来的Activity进行接口转换
               if(activity instance FragmentListener){
                   mListener = ((FragmentListener)activity); 
              }
         }
         ...其他处理代码省略 
  } 

5. 封装Functions

FunctionException.java

public class FunctionException extends Exception {
    public FunctionException(String msg){
        super();
    }
}

Functions.java

public class Functions {
    /**
     * 带有参数和返回值的 方法
     * @param 
     * @param 
     */
    public static abstract class FunctionWithParamAndResult extends Function{
        public FunctionWithParamAndResult(String functionName) {
            super(functionName);
        }

        public abstract Result function(Param data);
    }

    /**
     * 没有参数和返回值的方法
     */
    public static abstract class Function{
        public String mFunctionName;
        public Function(String functionName){
            this.mFunctionName = functionName;
        }
    }

    /**
     * 有返回值,没有参数的方法
     * @param 
     */
    public static abstract class FunctionWithResult extends Function{
        public FunctionWithResult(String functionName) {
            super(functionName);
        }

        public abstract Result function();
    }

    /**
     * 带有参数没有返回值的方法
     * @param 
     */
    public static abstract class  FunctionWithParam extends Function{
        public FunctionWithParam(String functionName) {
            super(functionName);
        }

        public abstract void function(Param param);
    }

    /**
     * 没有参数和返回值的方法
     */
    public static abstract class  FunctionNoParamAndResult extends Function{
        public FunctionNoParamAndResult(String functionName) {
            super(functionName);
        }

        public abstract void function();
    }

    private HashMap mFunctionWithParam ;
    private HashMap mFunctionWithResult ;
    private HashMap mFunctionNoParamAndResult ;
    private HashMap mFunctionWithParamAndResult ;


    /**
     * 添加带参数的函数
     * @param function
     * @return
     */
    public Functions addFunction(FunctionWithParam function){
        if(function == null){
            return this;
        }
        if(mFunctionWithParam == null){
            mFunctionWithParam = new HashMap(1);
        }
        mFunctionWithParam.put(function.mFunctionName,function);

        return this;
    }

    /**
     * 添加带返回值的函数
     * @param function 
     * @return
     */
    public Functions addFunction(FunctionNoParamAndResult function){
        if(function == null){
            return this;
        }
        if(mFunctionNoParamAndResult == null){
            mFunctionNoParamAndResult = new HashMap(1);
        }
        mFunctionNoParamAndResult.put(function.mFunctionName,function);

        return this;
    }

    /**
     * 添加既有参数又有返回值的函数
     * @param function 
     * @return
     */
    public Functions addFunction(FunctionWithParamAndResult function){
        if(function == null){
            return this;
        }
        if(mFunctionWithParamAndResult == null){
            mFunctionWithParamAndResult = new HashMap(1);
        }
        mFunctionWithParamAndResult.put(function.mFunctionName,function);

        return this;
    }

    /**
     * 添加带有返回值的函数
     * @param function
     * @return
     */
    public Functions addFunction(FunctionWithResult function){
        if(function == null){
            return this;
        }
        if(mFunctionWithResult == null){
            mFunctionWithResult = new HashMap(1);
        }
        mFunctionWithResult.put(function.mFunctionName,function);

        return this;
    }

    /**
     * 根据函数名,回调无参无返回值的函数
     * @param funcName
     */
    public void invokeFunc(String funcName) throws FunctionException {
        FunctionNoParamAndResult f = null;
        if(mFunctionNoParamAndResult != null){
            f = mFunctionNoParamAndResult.get(funcName);
            if(f != null){
                f.function();
            }
        }

        if(f == null){
            throw new FunctionException("没有此函数");

        }
    }

    /**
     * 根据函数名,回调无参有返回值的函数
     * @param funcName
     */
    public  Result invokeFuncWithResult(String funcName, Class c) throws FunctionException {
        FunctionWithResult f = null;
        if(mFunctionWithResult != null){
            f = mFunctionWithResult.get(funcName);
            if(f != null){
                if(c != null){
                    return c.cast(f.function());
                }else{
                    return (Result)f.function();
                }

            }
        }

        if(f == null){
            throw new FunctionException("没有此函数");
        }
        return null;
    }

    /**
     * 调用具有参数的函数
     * @param funcName
     * @param param
     * @param 
     */
    public  void invokeFunc(String funcName,Param param)throws FunctionException{
        FunctionWithParam f = null;
        if(mFunctionWithParam != null){
            f = mFunctionWithParam.get(funcName);
            if(f != null){
                f.function(param);
            }
        }


    }

    /**
     * 调用具有参数,同时具有返回值的函数
     * @param funcName
     * @param param
     * @param 
     * @param 
     * @return
     */
    public  Result invokeFuncWithResult(String funcName,Param param,Class c) throws FunctionException {
        FunctionWithParamAndResult f = null;
        if(mFunctionWithParamAndResult != null){
            f = mFunctionWithParamAndResult.get(funcName);
            if(f != null){
                if(c != null){
                    return c.cast(f.function(param));
                }else{
                    return (Result)f.function(param);
                }
            }
        }

        if( f == null){
            throw new FunctionException("没有此函数");

        }
        return null;
    }

    /**
     * 函数的参数,当函数的参数涉及到多个值时,可以用此类,
     * 此类使用规则:存参数与取参数的顺序必须一致,否则报错
     */
    public static class FunctionParams {

        private Bundle mParams = new Bundle(1);
        private int mIndex = -1;
        private Map mObjectParams = new HashMap(1);

        FunctionParams(Bundle mParams,Map mObjectParams){
            this.mParams = mParams;
            this.mObjectParams = mObjectParams;
        }

        public  Param getObject(Class p){
            if(mObjectParams == null){
                return null;
            }
            return p.cast(mObjectParams.get((mIndex++) + ""));
        }

        /**
         * 获取int值
         * @return
         */
        public int getInt(){
            if(mParams != null){
                return mParams.getInt((mIndex++) + "");
            }
            return 0;
        }

        /**
         * 获取int值
         * @param defalut
         * @return
         */
        public int getInt(int defalut){
            if(mParams != null){
                return mParams.getInt((mIndex++) + "");
            }
            return defalut;
        }

        /**
         * 获取字符串
         * @param defalut
         * @return
         */
        public String getString(String defalut){
            if(mParams != null){
                return mParams.getString((mIndex++) + "");
            }
            return defalut;
        }

        /**
         * 获取字符串
         * @return
         */
        public String getString(){
            if(mParams != null){
                return mParams.getString((mIndex++) + "");
            }
            return null;
        }



        /**
         * 获取Boolean值
         * @return 默认返回false
         */
        public boolean getBoolean(){
            if(mParams != null){
                return mParams.getBoolean((mIndex++) + "");
            }
            return false;
        }

        /**
         * 该类用来创建函数参数
         */
        public static class FunctionParamsBuilder{
            private Bundle mParams ;
            private int mIndex = -1;
            private Map mObjectParams = new HashMap(1);

            public FunctionParamsBuilder(){

            }

            public FunctionParamsBuilder putInt(int value){
                if(mParams == null){
                    mParams = new Bundle(2);
                }
                mParams.putInt((mIndex++) + "", value);
                return this;
            }

            public FunctionParamsBuilder putString(String value){
                if(mParams == null){
                    mParams = new Bundle(2);
                }
                mParams.putString((mIndex++) + "", value);
                return this;
            }

            public FunctionParamsBuilder putBoolean(boolean value){
                if(mParams == null){
                    mParams = new Bundle(2);
                }
                mParams.putBoolean((mIndex++) + "", value);
                return this;
            }

            public  FunctionParamsBuilder putObject(Object value){

                if(mObjectParams == null){
                    mObjectParams = new HashMap(1);
                }
                mObjectParams.put((mIndex++) + "", value);
                return this;
            }

            public FunctionParams create(){
                FunctionParams instance = new FunctionParams(mParams,mObjectParams);
                return instance;
            }
        }

    }
}

使用

public class FirstFragment extends BaseFragment {
    public static FirstFragment newInstance() {
        return new FirstFragment();
    }

    /**
     * 没有参数没有返回值的函数
     */
    public static final String FUNCTION_NO_PARAM_NO_RESULT = "FUNCTION_NO_PARAM_NO_RESULT";
    /**
     * 没有参数有返回值的函数
     */
    public static final String FUNCTION_NO_PARAM_HAS_RESULT = "FUNCTION_NO_PARAM_HAS_RESULT";
    /**
     * 有参数没有返回值的函数
     */
    public static final String FUNCTION_HAS_PARAM_NO_RESULT = "FUNCTION_HAS_PARAM_NO_RESULT";
    /**
     * 有参数有返回值的函数
     */
    public static final String EVENT_HAS_PARAM_HAS_RESULT = "EVENT_HAS_PARAM_HAS_RESULT";

    /**
     * 具有多个参数的函数
     */
    public static final String FUNCTION_HAS_MORE_PARAM = "FUNCTION_HAS_MORE_PARAM";

    /**
     * 具有多个参数的函数
     */
    public static final String FUNCTION_HAS_MORE_PARAM_Bundle = "FUNCTION_HAS_MORE_PARAM_Bundle";

    private Button mBut1, mBut2, mBut3, mBut4;
    private TextView mResult;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mBut1 = (Button) getView().findViewById(R.id.click1);
        mBut2 = (Button) getView().findViewById(R.id.click2);
        mBut3 = (Button) getView().findViewById(R.id.click3);
        mBut4 = (Button) getView().findViewById(R.id.click4);
        mResult = (TextView) getView().findViewById(R.id.result);

        mBut1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mFunctions.invokeFunc(FUNCTION_NO_PARAM_NO_RESULT);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        });

        mBut2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String result = null;
                try {
                    result = mFunctions.invokeFuncWithResult(FUNCTION_NO_PARAM_HAS_RESULT, String.class);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
                mResult.setText(result);
            }
        });
        mBut3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mFunctions.invokeFunc(FUNCTION_HAS_PARAM_NO_RESULT, 100);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        });
        mBut4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List re = null;
                try {
                    re = mFunctions.invokeFuncWithResult(EVENT_HAS_PARAM_HAS_RESULT, 100, List.class);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
                if (re != null) {
                    String st = "";
                    for (int i = 0; i 

FirstActivity.java

public class FirstActivity extends BaseActivity {
    @Override
    public void setFunctionsForFragment(int fragmentId) {
        super.setFunctionsForFragment(fragmentId);
        switch (fragmentId) {
            case R.id.fragment_main:
                FragmentManager fm = getSupportFragmentManager();
                BaseFragment fragment = (BaseFragment) fm.findFragmentById(fragmentId);
                fragment.setFunctions(new Functions().addFunction(new Functions.FunctionNoParamAndResult(FirstFragment.FUNCTION_NO_PARAM_NO_RESULT) {
                    @Override
                    public void function() {
                        Toast.makeText(FirstActivity.this, "成功调用无参无返回值方法", Toast.LENGTH_LONG).show();
                    }
                }).addFunction(new Functions.FunctionWithResult(FirstFragment.FUNCTION_NO_PARAM_HAS_RESULT) {
                    @Override
                    public String function() {
                        Toast.makeText(FirstActivity.this, "成功调用无参有返回值方法", Toast.LENGTH_LONG).show();
                        return "恭喜你,调我成功!";
                    }
                }).addFunction(new Functions.FunctionWithParam(FirstFragment.FUNCTION_HAS_PARAM_NO_RESULT) {
                    @Override
                    public void function(Integer o) {
                        Toast.makeText(FirstActivity.this, "成功调用有参无返回值方法 参数值=" + o, Toast.LENGTH_LONG).show();
                    }
                }).addFunction(new Functions.FunctionWithParamAndResult(FirstFragment.EVENT_HAS_PARAM_HAS_RESULT) {

                    @Override
                    public List function(Integer data) {
                        Toast.makeText(FirstActivity.this, "成功调用有参有返回值方法 参数值=" + data, Toast.LENGTH_LONG).show();
                        List result = new ArrayList();
                        result.add("1");
                        result.add("2");
                        result.add("3");
                        return result;
                    }
                }).addFunction(new Functions.FunctionWithParam(FirstFragment.FUNCTION_HAS_MORE_PARAM) {

                    @Override
                    public void function(Functions.FunctionParams functionParams) {
                        if (functionParams != null) {

                            Toast.makeText(FirstActivity.this, "成功调用多个参数的方法 参数值=" + functionParams.getString()+" 参数1="+functionParams.getString()+" 参数2="+functionParams.getInt(), Toast.LENGTH_LONG).show();
                        }
                    }
                }).addFunction(new Functions.FunctionWithParam(FirstFragment.FUNCTION_HAS_MORE_PARAM_Bundle) {

                    @Override
                    public void function(Bundle bundle) {
                        if(bundle != null){
                            Toast.makeText(FirstActivity.this, "成功调用多个参数的方法 参数值=" + bundle.getString("p")+" 参数1="+bundle.getString("p1")+" 参数2="+bundle.getInt("p2"), Toast.LENGTH_LONG).show();

                        }
                    }
                }));
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
    }
}

布局文件


    
    
    
    
    
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。