android自从Fragment出来之后就备受关注,可是Fragment是依赖Activity而存在,那么二者之间的交互式必不可少的,那么他们之间须要进行通讯和数据交互,目前经常使用的方式有:android
一、EventBus框架
二、静态变量ide
三、广播this
四、接口方式继承
五、Handler接口
目前大体就这5种交互方式,除了接口外,其它三种都是单向的数据传递。而通常的接口方式咱们也是不一样的Fragment就会有不一样的接口,这样Activity须要实现的接口就很是多,那么可否有统一的接口来实现这个功能,而且可以相互传递数据。咱们看下面万能接口的定义get
咱们分析接口的特色:方法名,参数和返回值(这二者可能有也可能没有),所以it
首先,咱们定义一个抽象类,名为FunctionInterfaceio
public abstract class FunctionInterface{ public String functionName; public FunctionInterface(String functionName) { this.functionName = functionName; } }
这个类很简单,就是一个方法名称而已,下面继承类须要按照参数和返回值的有无来定义ast
public abstract class FunctionNoParamNoResult extends FunctionInterface{ public FunctionNoParamNoResult(String name) { super(name); } public abstract void function(); }
上面这个类申明的是没有参数也没有返回值的接口,有一个抽象方法function,它是咱们须要回调实现具体逻辑的,另外还有有返回值没有参数的接口,有参数没有返回值和有参数有返回值的接口申明,下面贴一个有返回值的接口,其它的不贴了
public abstract class FunctionWithParamOnly<Param> extends FunctionInterface{ public FunctionWithParamOnly(String name) { super(name); } public abstract void function(Param data); }
接口申明完成后,咱们须要一个管理的类来保存接口,FunctionManager
由于全部的接口都保存在这个管理类中,因此咱们要将这个类定义为单例模式
private static final FunctionManager ourInstance = new FunctionManager(); public static FunctionManager getInstance() { return ourInstance; } private HashMap<String, FunctionNoParamNoResult> mFunctionNoParamNoResult; private HashMap<String, FunctionWithParamOnly> mFunctionWithParamOnly;
既然是管理接口的类,那么接口的添加和接口的调用都在这里实现,下面是其中一个接口类型的实现
public FunctionManager addFunction(FunctionNoParamNoResult function) { mFunctionNoParamNoResult.put(function.functionName, function); return this; } public void invokeFunction(String name) { if (TextUtils.isEmpty(name)) { return; } if (null != mFunctionNoParamNoResult) { FunctionNoParamNoResult f = mFunctionNoParamNoResult.get(name); if (null != f) { f.function(); } else { try { throw new FunctionException("Has no function exception: " + name); } catch (FunctionException e) { e.printStackTrace(); } } } }
到目前为止,接口的申明和接口的管理已经作完,剩下的是接口的实现和被调用方式,在Fragment中,咱们要先获取到管理接口类的实例,而后才能调用invokeFunction方法,那么在初始化时就要将实例注入到Fragment中,
protected FunctionManager mFunctionManager; protected MainActivity mActivity; public void setmFunctionManager(FunctionManager manager) { this.mFunctionManager = manager; }
注入完成后,就能够直接使用FunctionManager的方法来调用对应接口的方法,
public class Fragment1 extends BaseFragment { public static final String FUCTIOIN_NAME = Fragment1.class.getName() + "NPNR"; private Button btn; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment, container, false); btn = (Button) view.findViewById(R.id.button); btn.setText("First"); btn.setOnClickListener(clickListener); Button test = (Button) view.findViewById(R.id.test_button); test.setOnClickListener(testListener); return view; } private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { mFunctionManager.invokeFunction(FUCTIOIN_NAME); } };
这里调用很方便,只有一行代码便可实现,若是要调用带参数的方法呢,
private View.OnClickListener testListener = new View.OnClickListener() { @Override public void onClick(View v) { OperateModel model = new OperateModel(); model.num1 = 100; model.num2 = 12; Float result = mFunctionManager.invokeFunction(FUCTIOIN_NAME, model, Float.class); Toast.makeText(mActivity, model.num1 + "*" + model.num2 + "=" + result, Toast.LENGTH_SHORT).show(); } };
其实也就一行代码实现了。
那么剩下的工做就是Activity如何来处理这个接口和接口的实现了。在Activity初始化的时候,咱们就须要将FunctionManager的实例注入到Fragment中,而后针对不一样Fragment逻辑实现接口的逻辑,具体以下
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } public void inject(String tag) { Fragment fragment = fragmentTransaction.findFragmentByTag(tag); fragment.setmFunctionManager(FunctionManager.getInstance().addFunction(new FunctionNoParamNoResult(Fragment1.FUCTIOIN_NAME) { @Override public void function() { Toast.makeText(MainActivity.this, "Invoke No Param No Result function successfully", Toast.LENGTH_SHORT).show(); } }).addFunction(new FunctionWithParamAndResult<OperateModel, Float>(Fragment1.FUCTIOIN_NAME) { @Override public Float function(OperateModel data) { if (null != data) { return Float.valueOf(data.num1 * data.num2); } return 0.0f; } })); }
到这里,通用的接口框架已经完成,不一样的Fragment能够根据须要调用不一样类型的接口实现,在Activity中不须要去实现各类各样的接口实现,只用动态addFunction就能处理有参无参,有返回值无返回值的全部类型。