回顾总结, MVP 简单封装,我理解的mvp模式(2)

回顾总结, MVP 初识,我理解的mvp模式(1)

上一篇文章写的是mvp的简单实现,这一篇是写mvp的简单封装,另外说一下,文章内容都是我个人的理解然后输出,有些东西可能说的不太准确,请注意甄别, 或者留言交流。当然, 本人也会尽最大能力写的正确,但是。。。请多包含,谢谢。

开始封装

上来我就直给,先搞BaseView

public interface BaseView {
    void showToast(String str);
}

先定义一个BaseView,然后里面写一个toast的方法给子类重写,暂时就先写这一个方法吧。然后重点来了,因为项目主要用的fragment,所以我这边用BaseFragment,activity同理;

public abstract class BaseFragment extends Fragment implements BaseView{
    protected T mPresenter;
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mPresenter = createPresenter();
        if (mPresenter!=null){
            mPresenter.attachView(this);
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }
    @Override
    public void onDestroyView() {
        if (mPresenter!=null){
            mPresenter.detach();
        }
        super.onDestroyView();
    }
    protected abstract T createPresenter();
    @Override
    public void showToast(String str) {
        Toast.makeText(getContext(), str, Toast.LENGTH_SHORT).show();
    }
}

1,直接加上个abstract来修饰, 变成抽象类, 这样就不能通过new的方式来实现BaseFragment,保证他是一个纯粹的基类。
2,实现了BaseView接口, 然后重写了showToast方法,子类就不需要多次重复的写这个方法了。
3,这里有一个 抽象方法 createPresenter,返回的是T,这个是泛型,T extends BasePresenter 就是BasePresenter的子类,需要在子类实现,我们在onCreateView里面调用后拿到对象, 然后通过mPresenter.attachView(this);绑定了presenter和view,先不要着急问attachView是哪里来的,马上解答。
上面搞完了BaseFragment,然后来看BasePresenter

public abstract class BasePresenter {

    protected T view;
    public void attachView(T view){
        this.view = view;
    }
    public void detach(){
        view = null;
    }
    protected boolean isAttached(){
        return view != null;
    }
}

1,依然是上来就写个abstract,不让new这个对象。
2,现在发现,这里有三个方法,attachView,detach,isAttached,就是上面第三个的答案,现在V-P已经连在一起了,p可以知道V有没有销毁回收

基类写完了,然而并没有写model的,因为没啥好写的,model都不太一样,没有BaseModel。

开始实现

先看MainPresenter

public class MainPresenter extends BasePresenter {
    
   public void getData(){
        MainModel.getList(new MainContract.CallBack() {
            @Override
            public void modelCallBack(String... str) {
                if (isAttached()){
                    view.upDateMsg(str[0]);
                    view.showToast(str[0]);
                }
            }
        });
   }
}

首先mainPresenter提供了一个getData,然后调用了model的获取数据的方法, 同时传了一个callback,在回调里面判断view没有销毁的话调用view的方法把数据传到view层。
MainFragment:

public class MainFragment extends BaseFragment implements MainView{

    Button button;
    TextView textView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.main_fragment,container,false);

        mPresenter = createPresenter();
        mPresenter.attachView(this);
        view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPresenter.getData();
            }
        });
        return view;
    }
    @Override
    protected MainPresenter createPresenter() {
        return new MainPresenter();
    }
    @Override
    public void showToast(final String str) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getContext(), str, Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    public void upDateMsg(String text) {
        Log.e("---", text);
    }
}

1,在这里实现了抽象方法createPresenter。
2,然后重写了showToast 因为这里其实是子线程, 在这里toast是会报错的。
3,你会发现多了一个方法 upDateMsg,其实是因为实现了一个MainView接口才多的,其实也可以把这个方法放在BaseView里面,但是总会有一些方法不通用, 放在这里是为了举例,下面是MianView的代码:

public interface MainView extends BaseView {
    void upDateMsg(String text);
}

存在的问题

上篇文章写到,如果在获取文章的时候页面销毁了,那么获取到数据回传然后更新时,发现view==null,此时就会发生空指针异常。已经在上面的代码里面解决了,如果没发现, 再读一下吧。
这篇文章就写到这里, 下一篇开始引入第三方框架,解决线程切换之类的问题。

你可能感兴趣的:(android,MVP,java,接口,设计模式,安卓,mvp)