Activity与Fragment通信 多接口实现优化

来源:互联网 发布:windows 共享内存 编辑:程序博客网 时间:2024/05/20 05:06

1.问题

我们都知道Activity与Fragment通信的几种方式,推崇的应该是谷歌给出的接口方案。

地址:https://developer.android.com/training/basics/fragments/communicating.html#DefineInterface

当一个Activity与多个Fragment通信时,可能要定义多个接口,下面这种思想是减少接口的定义,可以编写出一套统一的代码。


2.思想

对方法对象的封装,key作为方法名字,value作为方法对象

使用效果和接口差不多


3.主要代码

方法的封装类

/** * key为Fragment的标示 * value为回调函数 */public class Functions{    private HashMap<String,FunctionWithParamAndResult> mFunctionWithParamAndResults ;    public static class Function{        String functionName;        public Function(String functionName){            this.functionName = functionName;        }    }    /**带有参数和返回值的抽象方法的类*/    public static abstract class FunctionWithParamAndResult<Param,Result> extends Function{        public FunctionWithParamAndResult(String functionName) {            super(functionName);        }        public abstract Result function(Param param);    }    /**添加带参数的函数*/    public Functions addFunction(FunctionWithParamAndResult function){        if(function == null){            return this;        }        if(mFunctionWithParamAndResults == null){            mFunctionWithParamAndResults = new HashMap<>();        }        mFunctionWithParamAndResults.put(function.functionName,function);        return this;    }    /** 调用具有参数的函数*/    public <Param, Result> Result invokeFunction(String funcName, Class<Result> classofR,                                                 Param param)throws NoFunctionException {        FunctionWithParamAndResult func = null;        if(mFunctionWithParamAndResults != null){            func = mFunctionWithParamAndResults.get(funcName);            if(func != null){                if(classofR != null){                    return classofR.cast(func.function(param));//安全的                }                return (Result)func.function(param);            } else {                throw new NoFunctionException("has no Function:" + funcName                        + "found in FunctionWithParamAndResult");            }        }        return null;    }}

BaseFragment 和 MainFragment

MainFragment中定义static FUNC_WPAR可以对应理解为接口回调方式中接口的定义

mFunctions.invokeFunction 是调用抽象方法

public class BaseFragment extends Fragment{    protected Functions mFunctions;    protected BaseActivity mBaseActivity;    /**     * activity调用此方法进行设置Functions     * @param functions     */    public void setFunctions(Functions functions){        this.mFunctions = functions;    }    @Override    public void onAttach(Context context) {        super.onAttach(context);        if(context instanceof BaseActivity){            mBaseActivity = (BaseActivity)context;            mBaseActivity.setFunctionsForFragment(getTag());        }    }}


public class MainFragment extends BaseFragment {    public static final String FUNCTION_WPAR = "MAIN_FUNCTION_WITH_PARAM_AND_RESULT";    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_main, null);        return view;    }    @Override    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        Button btn1 = (Button) view.findViewById(R.id.button1);        final TextView tv1 = (TextView) view.findViewById(R.id.textview1);        btn1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                try {                    String result = mFunctions.invokeFunction(FUNCTION_WPAR,                            String.class, "来自MainFragment参数");                    tv1.setText(result);                } catch (NoFunctionException e) {                    e.printStackTrace();                }            }        });    }}

MainActivity

其中new Functions.FunctionWithParamAndResult相当于接口方式里的实现接口

public class MainActivity extends BaseActivity {    private Functions mFunctions = new Functions();    private FragmentManager mFragmentManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    @Override    public void setFunctionsForFragment(String fragmentTAG) {        mFragmentManager = getSupportFragmentManager();        if("fragment_main".equals(fragmentTAG)){            BaseFragment mainFragment = (BaseFragment)mFragmentManager.findFragmentByTag(fragmentTAG);            mainFragment.setFunctions(mFunctions);            mFunctions.addFunction(new Functions.FunctionWithParamAndResult<String,                    String>(MainFragment.FUNCTION_WPAR) {                @Override                public String function(String str) {                    Toast.makeText(MainActivity.this,                            "收到MainFragment参数:" + str,                            Toast.LENGTH_SHORT).show();                    return "Activty处理参数:" + str;                }            });        } else if("fragment_second".equals(fragmentTAG)){            BaseFragment secondFragment = (BaseFragment)mFragmentManager.findFragmentByTag(fragmentTAG);            secondFragment.setFunctions(mFunctions);            mFunctions.addFunction(new Functions.FunctionWithParamAndResult<String,                    String>(SecondFragment.FUNCTION_WPAR) {                @Override                public String function(String str) {                    Toast.makeText(MainActivity.this,                            "收到SecondFragment参数:" + str,                            Toast.LENGTH_SHORT).show();                    return "Activty处理参数:" + str;                }            });        }    }}


如果使用这种方式来代替接口实现Activity与Fragment的通信,会使代码的阅读性变差,假如一个Fragment中有两个参数和返回类型相同,但是名字不同的方法,需要定义两个方法名字,阅读代码的时候,你就需要频繁查看调用处对应的方法名。

代码地址


参考文章:

Android:Activity与Fragment通信(99%)完美解决方案


其实个人觉得也没有特别完美,使用接口的方式,代码会更直观。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 倒车入库小于30公分怎么办 倒库大于30公分怎么办 有行车记录仪遇到碰瓷怎么办 狗换了主人不吃怎么办 遇到扔东西碰瓷怎么办 碰见碰瓷的人怎么办 开店遇上碰瓷的顾客怎么办 我刮到别人的车怎么办 新车被刮了漆怎么办 停车擦到别人车怎么办 骑自行车被汽车撞了怎么办 车停在小区被刮怎么办 机动车被自行车撞了怎么办 单车撞小车后被起诉怎么办 给小车撞到电动单车怎么办 车停在路边被自行车撞怎么办 撞了碰瓷的人怎么办 谷丙转氨酶46该怎么办 渣土车开飞机了怎么办 自己车撞自己车怎么办 撞了人没钱赔怎么办 闯红灯扣了6分怎么办 开共享汽车闯红灯了怎么办 新手如果不小心闯红灯怎么办 红绿灯左转车道直行了怎么办 跟着大车后面闯了红灯怎么办 宝宝私处好红怎么办呢 甲亢难怀孕怎么办才好 怀孕8周查出甲亢怎么办 电动车被交警拖走了怎么办 电动车车被城管拖走了怎么办 12123地理反编码失败怎么办 苹果手机地理反编码失败怎么办 城管执法过程被打怎么办 老婆看不起老公不让碰怎么办 老婆总不让碰该怎么办 机动车扣满12分怎么办 吊车吊运货物失控应该怎么办 车辆违章扣6分怎么办 最新交通法扣满12分怎么办 违章停车单丢了怎么办