├── modelos
└── Note.java
├── README.md
├── MainModel.java
├── MainMVP.java
├── MainActivity.java
├── MainPresenter.java
└── StateMaintainer.java
/modelos/Note.java:
--------------------------------------------------------------------------------
1 | package com.tinmegali.mvp_tutorial.modelos;
2 |
3 | /**
4 | * ---------------------------------------------------
5 | * Created by Tin Megali on 26/02/16.
6 | * Project: MVP_Tutorial
7 | * ---------------------------------------------------
8 | * tinmegali.com
9 | * Model View Presenter (MVP) no Android.
3 |
4 | Simplified implementation of Model View Presenter pattern in Android.
5 |
6 |
7 |
16 |
17 |
19 |
20 |
--------------------------------------------------------------------------------
/MainModel.java:
--------------------------------------------------------------------------------
1 | package com.tinmegali.mvp_tutorial;
2 |
3 | import android.util.Log;
4 |
5 | import com.tinmegali.mvp_tutorial.modelos.Note;
6 |
7 | /**
8 | * ---------------------------------------------------
9 | * Created by Tin Megali on 26/02/16.
10 | * Project: MVP_Tutorial
11 | * ---------------------------------------------------
12 | * tinmegali.com
13 | * tinmegali.com
11 | * tinmegali.com
18 | * (mView);
41 | this.mModel = new MainModel(this);
42 | }
43 |
44 | /**
45 | * Sent from Activity after a configuration changes
46 | *
47 | * Disparado por Activity após mudança de configuração
48 | *
49 | * @param view View reference
50 | */
51 | @Override
52 | public void onConfigurationChanged(MainMVP.RequiredViewOps view) {
53 | Log.d(TAG, "onConfigurationChanged()");
54 |
55 | mView = new WeakReference<>(view);
56 | }
57 |
58 | /**
59 | * Receives {@link MainActivity#onDestroy()} event
60 | * @param isChangingConfig Config change state
61 | *
62 | * Recebe evento {@link MainActivity#onDestroy()}
63 | * @param isChangingConfig Se está mudando de config
64 | */
65 | @Override
66 | public void onDestroy(boolean isChangingConfig) {
67 | Log.d(TAG, "onDestroy(isChangingConfig:"+isChangingConfig+")");
68 | mView = null;
69 | mIsChangingConfig = isChangingConfig;
70 | if ( !isChangingConfig ) {
71 | mModel.onDestroy();
72 | }
73 | }
74 |
75 |
76 | /**
77 | * Called by user interaction from {@link MainActivity}
78 | * creates a new Note
79 | *
80 | * Chamado por {@link MainActivity} com a
81 | * interação do usuário de pedido para inserção de
82 | * nova nota
83 | */
84 | @Override
85 | public void newNote(String noteText) {
86 | Log.d(TAG, "newNote()");
87 | Note note = new Note();
88 | note.setText(noteText);
89 | note.setDate(getDate());
90 | mModel.insertNote(note);
91 | }
92 |
93 | /**
94 | * Called from {@link MainActivity},
95 | * Removes a Note
96 | *
97 | * Chamado por {@link MainActivity}, pedido
98 | * para remoção de nota
99 | */
100 | @Override
101 | public void deleteNote(Note note) {
102 | Log.d(TAG, "deleteNote()");
103 | mModel.removeNote(note);
104 | }
105 |
106 | /**
107 | * Called from {@link MainModel}
108 | * when a Note is inserted successfully
109 | *
110 | * Recebe chamado de {@link MainModel} quando
111 | * Nota for inserida com sucesso no DB
112 | */
113 | @Override
114 | public void onNoteInserted(Note novaNote) {
115 | Log.d(TAG, "onNoteInserted()");
116 | mView.get().showToast("New " + novaNote.getDate());
117 | }
118 |
119 | /**
120 | * Receives call from {@link MainModel}
121 | * when Note is removed
122 | *
123 | * Recebe chamado de {@link MainModel} quando
124 | * Nota for removida do DB
125 | */
126 | @Override
127 | public void onNoteRemoved(Note removedNote) {
128 | Log.d(TAG, "onNoteRemoved()");
129 | mView.get().showToast("Note " + removedNote.getDate() + " removed");
130 | }
131 |
132 | /**
133 | * receive errors
134 | *
135 | * Recebe erros
136 | */
137 | @Override
138 | public void onError(String errorMsg) {
139 | Log.d(TAG, "onError()");
140 | mView.get().showAlert(errorMsg);
141 | }
142 |
143 |
144 | /**
145 | * Returns current date
146 | *
147 | * Retorna data atual
148 | */
149 | private String getDate(){
150 | Log.d(TAG, "getDate()");
151 | return new SimpleDateFormat("EEEE, dd/MM, kk:mm", Locale.getDefault()).format(new Date());
152 | }
153 |
154 | private Note getNote(String noteText){
155 | Log.d(TAG, "getNote()");
156 | Note note = new Note();
157 | note.setText(noteText);
158 | note.setDate( getDate() );
159 | return note;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/StateMaintainer.java:
--------------------------------------------------------------------------------
1 | package com.tinmegali.mvp_tutorial;
2 |
3 | import android.app.Fragment;
4 | import android.app.FragmentManager;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | import java.lang.ref.WeakReference;
9 | import java.util.HashMap;
10 |
11 | /**
12 | * ---------------------------------------------------
13 | * Created by Tin Megali on 26/02/16.
14 | * Project: MVP_Tutorial
15 | * ---------------------------------------------------
16 | * tinmegali.com
17 | * (fragmentManager);
40 | mStateMaintenerTag = stateMaintainerTAG;
41 | }
42 |
43 | /**
44 | * Create the state maintainer fragment
45 | * @return true: the frag was created for the first time
46 | * false: recovering the object
47 | *
48 | * cria o fragmento responsável por armazenar o objetos
49 | * @return true: criou o framentos e rodou pela primeira vez
50 | * false: o objeto já foi criado, portanto é apenas recuperado
51 | */
52 | public boolean firstTimeIn() {
53 | try {
54 | // Recovering the reference
55 | // Recuperando referência
56 | mStateMaintainerFrag = (StateMngFragment)
57 | mFragmentManager.get().findFragmentByTag(mStateMaintenerTag);
58 |
59 | // Creating a new RetainedFragment
60 | // Criando novo RetainedFragment
61 | if (mStateMaintainerFrag == null) {
62 | Log.d(TAG, "Creating a new RetainedFragment " + mStateMaintenerTag);
63 | mStateMaintainerFrag = new StateMngFragment();
64 | mFragmentManager.get().beginTransaction()
65 | .add(mStateMaintainerFrag, mStateMaintenerTag).commit();
66 | return true;
67 | } else {
68 | Log.d(TAG, "Returns a existent retained fragment existente " + mStateMaintenerTag);
69 | return false;
70 | }
71 | } catch (NullPointerException e) {
72 | Log.w(TAG, "Erro firstTimeIn()");
73 | return false;
74 | }
75 | }
76 |
77 |
78 | /**
79 | * Insert Object to be preserved during configuration change
80 | * @param key Object's TAG reference
81 | * @param obj Object to maintain
82 | *
83 | * Insere objeto a serem presenrvados durante mudanças de configuração
84 | */
85 | public void put(String key, Object obj) {
86 | mStateMaintainerFrag.put(key, obj);
87 | }
88 |
89 | /**
90 | * Insert Object to be preserved during configuration change
91 | * Uses the Object's class name as a TAG reference
92 | * Should only be used one time by type class
93 | * @param obj Object to maintain
94 | *
95 | * Insere objeto a serem presenrvados durante mudanças de configuração.
96 | * Utiliza a classe do Objeto como referência futura.
97 | * Só deve ser utilizado somente uma vez por classe, caso contrário haverá
98 | * possíveis conflitos na recuperação dos dados
99 | */
100 | public void put(Object obj) {
101 | put(obj.getClass().getName(), obj);
102 | }
103 |
104 |
105 | /**
106 | * Recovers saved object
107 | * @param key TAG reference
108 | * @param