先從字面意義上來了解MVP
M——Model 模型
V——View 視圖
P——Presenter 呈獻者
*這裏的View不是Android 組件,而是MVP模式的一部分
從Android控件方面來說,View部分都是一些Fragment以及View,其中不包括數據、邏輯,只做單純的顯示,這樣大大地簡化了View的代碼量,而且與Model完全解耦。**The view contains almost no logic: it converts the presenter’s commands to UI actions and listens to user actions, which are passed to the presenter。**View部分不含邏輯,主要作用是將Presenter中的代碼命令轉化成界面行爲,並且監聽用戶操作並將此操作傳遞到Presenter層進行邏輯處理。View和Presenter之間用接口來聯繫。
這裏的P主要將V呈現在大家面前。爲了把View和Model測底隔開,以往View中的數據變更等代碼都放到了Presenter中,因此該模塊中的代碼就顯得比較擁擠。基本業務邏輯也是存放在Presenter中。
接下來分析google提供的TODOAPP代碼
先定義View和Presenter的基類
public interface BaseView<T> {
void setPresenter(T presenter);
}
public interface BasePresenter {
void start();
}
TasksContract類用來聯繫二者。
public interface TasksContract {
interface View extends BaseView<Presenter> {
...
}
interface Presenter extends BasePresenter{
...
}
}
具體的View繼承自Fragment並且實現了TaskContract.View接口
public class TasksFragment extends Fragment implements TasksContract.View {
private TasksContract.Presenter mPresenter;
private TasksAdapter mListAdapter;
private View mNoTasksView;
private ImageView mNoTaskIcon;
private TextView mNoTaskMainView;
private TextView mNoTaskAddView;
private LinearLayout mTasksView;
private TextView mFilteringLabelView;
...
public TasksFragment() {
// Requires empty public constructor
}
public static TasksFragment newInstance() {
return new TasksFragment();
}
...
@Override
public void setPresenter(@NonNull TasksContract.Presenter presenter) {
mPresenter = checkNotNull(presenter);
}
...
}
具體的Presenter實現了TaskContract.Presenter接口
public class TasksPresenter implements TasksContract.Presenter {
private final TasksRepository mTasksRepository;
private final TasksContract.View mTasksView;
private TasksFilterType mCurrentFiltering = TasksFilterType.ALL_TASKS;
private boolean mFirstLoad = true;
public TasksPresenter(@NonNull TasksRepository tasksRepository, @NonNull TasksContract.View tasksView) {
mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
mTasksView = checkNotNull(tasksView, "tasksView cannot be null!");
mTasksView.setPresenter(this);
}
...
@Override
public void start() {
loadTasks(false);
}
...
//實例化之後,一旦顯示,立即執行start()方法
@Override
public void onResume() {
super.onResume();
mPresenter.start();
}
}
Activity中的相關代碼
public class TasksActivity extends AppCompatActivity {
private static final String CURRENT_FILTERING_KEY = "CURRENT_FILTERING_KEY";
private DrawerLayout mDrawerLayout;
private TasksPresenter mTasksPresenter;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tasks_act);
...
//實例化TasksFragment
...
//實例化TasksPresenter,內部開始運行start()方法
}
}