您当前的位置: 首页 >  android

Kevin-Dev

暂无认证

  • 0浏览

    0关注

    544博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android -- 四大组件】Fragment 与 Activity 之间通信

Kevin-Dev 发布时间:2017-02-20 11:53:53 ,浏览量:0

不断学习,做更好的自己!💪

视频号CSDN简书欢迎打开微信,关注我的视频号:KevinDev点我点我 一、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 

    




    
    
    
    
    
    
    

四、问题点 4.1 Activity 如何传递数据到 Fragment?

答:采用 Bundle 方式。

  • 步骤1:Activity 的布局文件


    

    

  • 步骤2:设置 Fragment 的布局文件


    

    

    

  • 步骤3:设置 Activity 的类文件
public class Activity2Fragment extends AppCompatActivity {

    TextView text;

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

        text = (TextView) findViewById(R.id.text);

        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();

        // 步骤2:获取FragmentTransaction
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // 步骤3:创建需要添加的Fragment 
        final mFragment fragment = new mFragment();

        // 步骤4:创建Bundle对象
        // 作用:存储数据,并传递到Fragment中
        Bundle bundle = new Bundle();

        // 步骤5:往bundle中添加数据
        bundle.putString("message", "I love Google");

        // 步骤6:把数据设置到Fragment中
        fragment.setArguments(bundle);

        // 步骤7:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();


    }
}
  • 步骤4:设置 Fragment 的类文件
public class mFragment extends Fragment {
    Button button;
    TextView text;
    Bundle bundle;
    String message;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        // 设置布局文件

        button = (Button) contentView.findViewById(R.id.button);
        text = (TextView) contentView.findViewById(R.id.text);

        // 步骤1:通过getArgments()获取从Activity传过来的全部值
        bundle = this.getArguments();

        // 步骤2:获取某一值
        message = bundle.getString("message");

        // 步骤3:设置按钮,将设置的值显示出来
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 显示传递过来的值
                text.setText(message);

            }
        });

        return contentView;
    }
}
4.2 Fragment 如何传递数据到 Activity ?

答:采用 接口回调 方式。

  • 步骤1:在Activity的布局文件定义1占位符(FrameLayout)


    

    

    


  • 步骤2:设置 Fragment 的布局文件



    


  • 步骤3:设置回调接口
public interface ICallBack {
    void get_message_from_Fragment(String string);

}
  • 步骤4:设置 Fragment 的类文件
public class mFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        // 设置布局文件
        return contentView;
    }

    // 设置 接口回调 方法
    public void sendMessage(ICallBack callBack){

        callBack.get_message_from_Fragment("消息:我来自Fragment");

    }
}
  • 步骤5:设置 Acticvity 的类文件
public class MainActivity extends AppCompatActivity {

    Button button;
    TextView text;

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

        button = (Button)findViewById(R.id.button);
        text = (TextView)findViewById(R.id.text);

        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();

        // 步骤2:获取FragmentTransaction
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // 步骤3:创建需要添加的Fragment 
        final mFragment fragment = new mFragment();

        // 步骤4:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 通过接口回调将消息从fragment发送到Activity
                fragment.sendMessage(new ICallBack() {
                    @Override
                    public void get_message_from_Fragment(String string) {
                            text.setText(string);
                    }
                });

            }
        });
    }


}
关注
打赏
1658837700
查看更多评论
立即登录/注册

微信扫码登录

0.0481s