Fragment和Activity之间通信万能接口

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

android自从Fragment出来以后就备受关注,但是Fragment是依赖Activity而存在,那么两者之间的交互式必不可少的,那么他们之间需要进行通信和数据交互,目前常用的方式有:

1、EventBus

2、静态变量

3、广播

4、接口方式

5、Handler

目前大致就这5种交互方式,除了接口外,其它三种都是单向的数据传递。而一般的接口方式我们也是不同的Fragment就会有不同的接口,这样Activity需要实现的接口就非常多,那么能否有统一的接口来实现这个功能,并且能够相互传递数据。我们看下面万能接口的定义

我们分析接口的特点:方法名,参数和返回值(这两者可能有也可能没有),因此

首先,我们定义一个抽象类,名为FunctionInterface

public abstract class FunctionInterface{

    public String functionName;

    public FunctionInterface(String functionName) {
        this.functionName = functionName;
    }
}

这个类很简单,就是一个方法名称而已,下面继承类需要按照参数和返回值的有无来定义

public abstract class FunctionNoParamNoResult extends FunctionInterface{

    public FunctionNoParamNoResult(String name) {
        super(name);
    }

    public abstract void function();
}

上面这个类申明的是没有参数也没有返回值的接口,有一个抽象方法function,它是我们需要回调实现具体逻辑的,另外还有有返回值没有参数的接口,有参数没有返回值和有参数有返回值的接口申明,下面贴一个有返回值的接口,其它的不贴了

public abstract class FunctionWithParamOnly 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 mFunctionNoParamNoResult;
private HashMap 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(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就能处理有参无参,有返回值无返回值的所有类型。

 

转载于:https://my.oschina.net/u/2409806/blog/1936002

你可能感兴趣的:(Fragment和Activity之间通信万能接口)