继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Philm项目源码分解析(2): View与Presenter的设计

明月笑刀无情
关注TA
已关注
手记 104
粉丝 17
获赞 57

0.前言

本文是Philm源码分析系列的第二篇,重点分析Philm MVP结构中View与Presenter的设计。为了便于分析,本文选取了Philm中最简单的部分About,这部分用于展示Philm的关于信息,不包含任何Model代码。

1.绑定View和Presenter

在Philm中,View由Fragment和Activity实现,由于应用启动时首先启动Activity,因此,绑定Presenter的工作要在View中进行(也就是Activity/Fragment)。Philm在AboutFragment的onResume方法和onPause方法中进行View与Presenter的绑定与解绑。具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class AboutFragment extends ListFragment<ListView>
        implements AboutController.AboutListUi {
    ...
    @Override
    public void onResume() {
        super.onResume();
        getController().attachUi(this);
    }

    @Override
    public void onPause() {
        getController().detachUi(this);
        super.onPause();
    }
    ...
}


对于Philm的About部分,它的Presenter就是MainController中的AboutController(是的,Chris Banes将Presenter命名为了Controller)。

2.设置回调

下面来看Presenter(BaseUiController)中attachUi的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
abstract class BaseUiController<U extends BaseUiController.Ui<UC>, UC>
        extends BaseController {

    public interface Ui<UC> {

        void setCallbacks(UC callbacks);

        boolean isModal();
    }
    ...
    public synchronized final void attachUi(U ui) {
        Preconditions.checkArgument(ui != null, "ui cannot be null");
        Preconditions.checkState(!mUis.contains(ui), "UI is already attached");

        mUis.add(ui);

        ui.setCallbacks(createUiCallbacks(ui));

        if (isInited()) {
            if (!ui.isModal() && !(ui instanceof SubUi)) {
                updateDisplayTitle(getUiTitle(ui));
            }

            onUiAttached(ui);
            populateUi(ui);
        }
    }
    ...
}

这里最重要的两处代码是1)通过ui.setCallbacks(createUiCallbacks(ui))设置回调;和2)绘制Ui populateUi(ui)。


Philm在设置View回调是采用了一个非常精巧的设计:通过泛型来处理ViewInterface与回调。BaseUiController的泛型可以表示为BaseUiController<viewinterface, ViewCallbacs>,其中前一个泛型代表了前文所述用于解耦View和Presenter而实现的ViewInterface,而后一个是提供给ViewInterface的回调。ViewInterface本身提供了setCallbacks方法来进行ViewCallbacks与View的绑定。这样,所有的业务逻辑都可以在Presenter中实现,之后通过回调提供给View。View仅仅负责UI的表现,在需要处理业务逻辑时,通过调用之前Presenter设置的回调实现。

这里可以看一下About中响应List中某个item被点击的实现。这里onListItemClick继承自ListFragment,用于响应某个item的点击事件,AboutFragment将这个事件交给了Presenter设置的回调来处理。

1
2
3
4
5
6
7
8
9
10
11
12
public class AboutFragment extends ListFragment<ListView>
        implements AboutController.AboutListUi {
    ...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        AboutController.AboutItem item = (AboutController.AboutItem) l.getItemAtPosition(position);
        if (item != null && hasCallbacks()) {
            getCallbacks().onItemClick(item);
        }
    }
    ...
}


3.Display

这是Philm中一处比较新颖的设计,它本身应该算是Presenter的一部分,具体的实现在AndroidDisplay这个类中。它的作用是负责app中所有UI切换的工作,比如Activity跳转,现实Fragment,弹出Drawer等。听起来很不可以思议,但是由于这些代码都很短小,实际上这个类并不大,也不复杂。

原文链接:http://www.apkbus.com/blog-705730-60830.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP