blob: dfd06e58078d6983ddd709fb6106bc95ab90f75b [file] [log] [blame] [view]
Matthew Jones871569f12019-04-03 16:25:481# So, you want to do MVC...
2
3### Overview
4A full explanation of the MVC framework can be found [here](https://docs.google.com/document/d/1nP9NjTvsSMZvkR_aWRZPdy67wRINomgQ7AfEtbsIwzg). This document is intended to go over the logistics of the most basic implementation of the framework in Chrome’s codebase.
5
6For this example, well be implementing a simple progress bar; a rectangle that changes length based on the loading state of the underlying webpage.
7
8#### Additional Resources
Matthew Jonesb514f982019-05-30 17:49:189[Simple MVC lists](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ui/android/mvc_simple_list_tutorial.md)
Matthew Jones871569f12019-04-03 16:25:4810[Testing MVC primer doc](https://docs.google.com/document/d/1Mel7f4lE_osFjnttkxu1wcUf_k9CmIzPv6oxwCw9tx4/edit#)
11
12#### File Structure
13The file structure of our component will be the following:
14* ./org/chromium/chrome/browser/simple_progress/
15 * [`SimpleProgressCoordinator.java`](#SimpleProgressCoordinator)
16 * [`SimpleProgressMediator.java`](#SimpleProgressMediator)
17 * [`SimpleProgressViewBinder.java`](#SimpleProgressViewBinder)
18 * [`SimpleProgressProperties.java`](#SimpleProgressProperties)
19 * `SimpleProgressView.java` (assuming it requires interesting logic)
20
21#### SimpleProgressCoordinator
22The class responsible for setting up the component. This should be the only public class in the component's package and is the only class with direct access to the mediator.
23
24```java
25public class SimpleProgressCoordinator {
26
27 private SimpleProgressMediator mMediator;
28
29 public SimpleProgressCoordinator (Tab tabProgressBarIsFor) {
30
31 PropertyModel model = new PropertyModel.Builder(SimpleProgressProperties.ALL_KEYS)
32 .with(SimpleProgressProperties.PROGRESS_FRACTION, 0f)
33 .with(SimpleProgressProperties.FOREGROUND_COLOR, Color.RED)
34 .build();
35
36 // This view can come from multiple places, in this case we find it in the existing
37 // view hierarchy.
38 View view = tabProgressBarIsFor.getActivity().findViewById(
39 R.id.my_simple_progress_bar);
40
41 PropertyModelChangeProcessor.create(model, view, SimpleProgressViewBinder::bind);
42
43 mMediator = new SimpleProgressMediator(model, tabProgressBarIsFor);
44 }
45
46 public void destroy() {
47 mMediator.destroy();
48 }
49}
50```
51
52#### SimpleProgressMediator
53The class that handles all of the signals coming from the outside world. External classes should never interact with this class directly.
54
55```java
56class SimpleProgressMediator extends EmptyTabObserver {
57
58 private PropertyModel mModel;
59
60 private Tab mObservedTab;
61
62 public SimpleProgressMediator(PropertyModel model, Tab tabProgressBarIsFor) {
63 mModel = model;
64 mObservedTab = tabProgressBarIsFor;
65 mObservedTab.addObserver(this);
66 }
67
68 @Override
69 public void onLoadProgressChanged(Tab tab, int progress) {
70 mModel.set(SimpleProgressProperties.PROGRESS_FRACTION, progress / 100f);
71 }
72
73 @Override
74 public void onDidChangeThemeColor(Tab tab, int color) {