├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wolearn │ │ └── mvpframe │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── wolearn │ │ │ └── mvpframe │ │ │ ├── MyApplication.java │ │ │ └── login │ │ │ ├── contract │ │ │ └── LoginContract.java │ │ │ ├── model │ │ │ └── LoginHttp.java │ │ │ ├── presenter │ │ │ └── LoginPresenter.java │ │ │ └── ui │ │ │ └── LoginActivity.java │ └── res │ │ ├── drawable │ │ ├── bg_btn_normal.xml │ │ ├── bg_edt_normal.xml │ │ └── side_nav_bar.xml │ │ ├── layout │ │ └── activity_login.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── wolearn │ └── mvpframe │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mvpframelib ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wolearn │ │ └── mvpframelib │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── wolearn │ │ │ └── mvpframelib │ │ │ ├── base │ │ │ ├── BasePresenter.java │ │ │ └── BaseView.java │ │ │ └── frame │ │ │ ├── Mvp.java │ │ │ ├── MvpActivity.java │ │ │ ├── MvpFragment.java │ │ │ ├── MvpModel.java │ │ │ ├── MvpPresenter.java │ │ │ └── MvpView.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── wolearn │ └── mvpframelib │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MvpFrame -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Abstraction issuesJava 39 | 40 | 41 | Android 42 | 43 | 44 | Android > Lint > Accessibility 45 | 46 | 47 | Android > Lint > Correctness 48 | 49 | 50 | Android > Lint > Correctness > Messages 51 | 52 | 53 | Android > Lint > Internationalization 54 | 55 | 56 | Android > Lint > Internationalization > Bidirectional Text 57 | 58 | 59 | Android > Lint > Performance 60 | 61 | 62 | Android > Lint > Security 63 | 64 | 65 | Android > Lint > Usability 66 | 67 | 68 | Android > Lint > Usability > Icons 69 | 70 | 71 | Assignment issuesJava 72 | 73 | 74 | C/C++ 75 | 76 | 77 | Class metricsJava 78 | 79 | 80 | Class structureJava 81 | 82 | 83 | Cloning issuesJava 84 | 85 | 86 | Code style issuesJava 87 | 88 | 89 | Concurrency annotation issuesJava 90 | 91 | 92 | Control FlowGroovy 93 | 94 | 95 | Control flow issuesJava 96 | 97 | 98 | Data flow analysisC/C++ 99 | 100 | 101 | Data flow issuesGroovy 102 | 103 | 104 | Data flow issuesJava 105 | 106 | 107 | Declaration redundancyGroovy 108 | 109 | 110 | Declaration redundancyJava 111 | 112 | 113 | DeclarationGroovy 114 | 115 | 116 | Dependency issuesJava 117 | 118 | 119 | Encapsulation issuesJava 120 | 121 | 122 | Error handlingGroovy 123 | 124 | 125 | Error handlingJava 126 | 127 | 128 | Finalization issuesJava 129 | 130 | 131 | FunctionsC/C++ 132 | 133 | 134 | General 135 | 136 | 137 | GeneralC/C++ 138 | 139 | 140 | Groovy 141 | 142 | 143 | HTML 144 | 145 | 146 | ImportsJava 147 | 148 | 149 | Inheritance issuesJava 150 | 151 | 152 | Initialization issuesJava 153 | 154 | 155 | Internationalization issues 156 | 157 | 158 | Internationalization issuesJava 159 | 160 | 161 | J2ME issuesJava 162 | 163 | 164 | JSON 165 | 166 | 167 | JUnit issuesJava 168 | 169 | 170 | Java 171 | 172 | 173 | Java language level issuesJava 174 | 175 | 176 | Java language level migration aidsJava 177 | 178 | 179 | JavaBeans issuesJava 180 | 181 | 182 | Javadoc issuesJava 183 | 184 | 185 | Logging issuesJava 186 | 187 | 188 | Manifest 189 | 190 | 191 | Memory issuesJava 192 | 193 | 194 | Method MetricsGroovy 195 | 196 | 197 | Method metricsJava 198 | 199 | 200 | Modularization issuesJava 201 | 202 | 203 | Naming ConventionsGroovy 204 | 205 | 206 | Naming conventionsJava 207 | 208 | 209 | Numeric issuesJava 210 | 211 | 212 | OtherGroovy 213 | 214 | 215 | Packaging issuesJava 216 | 217 | 218 | Performance issuesJava 219 | 220 | 221 | Portability issuesJava 222 | 223 | 224 | Potentially confusing code constructsGroovy 225 | 226 | 227 | Probable bugsGroovy 228 | 229 | 230 | Probable bugsJava 231 | 232 | 233 | Properties Files 234 | 235 | 236 | Properties FilesJava 237 | 238 | 239 | RELAX NG 240 | 241 | 242 | Resource management issuesJava 243 | 244 | 245 | Security issuesJava 246 | 247 | 248 | Serialization issuesJava 249 | 250 | 251 | Spelling 252 | 253 | 254 | TestNGJava 255 | 256 | 257 | Threading issuesGroovy 258 | 259 | 260 | Threading issuesJava 261 | 262 | 263 | Type checksC/C++ 264 | 265 | 266 | Unused codeC/C++ 267 | 268 | 269 | Validity issuesGroovy 270 | 271 | 272 | Visibility issuesJava 273 | 274 | 275 | XML 276 | 277 | 278 | toString() issuesJava 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 300 | 301 | C:\Users\wulei\AppData\Roaming\Subversion 302 | 303 | 304 | 305 | 306 | 307 | 1.8 308 | 309 | 314 | 315 | 316 | 317 | 318 | 319 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](http://upload-images.jianshu.io/upload_images/1931006-fa6fbaa08b91e647.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2 | #前言 3 | 听到一些童鞋抱怨MVP,所有搞了个辅助实现MVP的小东西,叫MvpFrame。还不了解MVP的先看[《Google原味mvp实践》](http://www.jianshu.com/p/dc9733bc3a54)。主要的功能如下 4 | * 省代码。不能偷懒的框架都是耍流氓,当然像Rx系列这样可以简化逻辑的也是正经人。 5 | * 不依赖其他库。不跟Retrofit,Rxjava等等耦合,只是纯粹的辅助MVP的实现。 6 | * 小,只有8k。可以在任意最小业务单元使用,即使之前业务没使用,或者之后不想使用都没关系。 7 | * M,V,P中各个层级的实例托管。 8 | * 维护M,V,P中对其他层的引用,并保证实例可回收。 9 | * 在工程任意位置获取MVP中的实例。 10 | 11 | 开源地址是 12 | >https://github.com/wolearn/MvpFrame 13 | 14 | #怎么用 15 | 可以把上面工程中的mvpframelib作为Android Lib引入,或者直接复制java文件也可以。我简单解释下还是我常用那个登陆的例子。先看目录结构。 16 | ![](http://upload-images.jianshu.io/upload_images/1931006-13632165bf609f39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 17 | ##初始化 18 | 在Application中调用 19 | >Mvp.getInstance().init(this); 20 | 21 | 规划好view和presenter的接口。 22 | ``` 23 | public class LoginContract { 24 | public interface View extends BaseView { 25 | String getAccount(); 26 | String getPassword(); 27 | void loginSuccess(); 28 | void loginError(String errorMsg); 29 | } 30 | 31 | public interface Presenter extends BasePresenter { 32 | void login(); 33 | } 34 | } 35 | ``` 36 | 用一个契约类来定义需要的方法。之前有童鞋问我,这个接口写好烦,能不能不写。肯定不能。我能想到的理由有三点 37 | * 依赖倒置原则。高层模块和底层模块之间不能直接依赖,而是应该依赖其接口 38 | * 保证其可测性 39 | * 面向接口编程的前期设计感 40 | 41 | ##View层 42 | 可以支持Activity和Fragment,Activity继承MvpActivity,Fragment继承MvpFragment。 43 | ``` 44 | public class LoginActivity extends MvpActivity implements LoginContract.View, View.OnClickListener { 45 | private EditText edtAccount, edtPassword; 46 | private Button btnLogin; 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | setContentView(R.layout.activity_login); 52 | 53 | initViews(); 54 | } 55 | 56 | @Override 57 | public BaseView getBaseView() { 58 | return this; 59 | } 60 | 61 | @Override 62 | public void onClick(View v) { 63 | mPresenter.login(); 64 | } 65 | 66 | private void initViews() { 67 | edtAccount = (EditText) findViewById(R.id.edt_account); 68 | edtPassword = (EditText) findViewById(R.id.edt_password); 69 | btnLogin = (Button) findViewById(R.id.btn_login); 70 | 71 | btnLogin.setOnClickListener(this); 72 | } 73 | 74 | @Override 75 | public void loginError(String msg) { 76 | Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show(); 77 | } 78 | 79 | @Override 80 | public void loginSuccess() { 81 | Toast.makeText(LoginActivity.this, getResources().getString(R.string.login_success), Toast.LENGTH_SHORT).show(); 82 | } 83 | 84 | @Override 85 | public String getAccount() { 86 | return edtAccount.getText().toString(); 87 | } 88 | 89 | @Override 90 | public String getPassword() { 91 | return edtPassword.getText().toString(); 92 | } 93 | } 94 | ``` 95 | * 注意MvpActivity,在继承的时候要通过泛型确定Presenter层的具体类型,一定要写。 96 | * getBaseView方法返回的是IView类型,如果是当前Activity实现的话,直接返回this即可。 97 | * mPresenter可以直接使用,不用声明和实例化 98 | 99 | ##Presenter层 100 | Presenter继承MvpPresenter实现即可。 101 | ``` 102 | public class LoginPresenter extends MvpPresenter implements LoginContract.Presenter { 103 | private static final String TAG = "LoginPresenter"; 104 | 105 | @Override 106 | public void login() { 107 | if (!checkParameter()) return; 108 | 109 | String account = getIView().getAccount(); 110 | String password = getIView().getPassword(); 111 | 112 | mModel.login(account, password); 113 | 114 | //模拟登陆成功 115 | getIView().loginSuccess(); 116 | } 117 | 118 | /** 119 | * 登录参数校验 120 | * 121 | * @return 122 | */ 123 | private boolean checkParameter() { 124 | try { 125 | if (TextUtils.isEmpty(getIView().getAccount())) { 126 | getIView().loginError(mContext.getString(R.string.toast_account_empty)); 127 | return false; 128 | } 129 | 130 | if (TextUtils.isEmpty(getIView().getPassword())) { 131 | getIView().loginError(mContext.getString(R.string.toast_password_empty)); 132 | return false; 133 | } 134 | } catch (Exception e) { 135 | e.printStackTrace(); 136 | } 137 | return true; 138 | } 139 | } 140 | ``` 141 | * 注意MvpPresenter的泛型,要确定Model的具体实现和IView。 142 | * IView的回调接口对象通过getIView()方法获取 143 | * mModel指向泛型中确认的LoginHttp对象,可以直接使用,不用声明和实例化 144 | * mContext是一个ApplicationContext的引用 145 | 146 | ##Model层 147 | 数据的来源一般有三个:DB,NET,Cache。看个图 148 | ![](http://upload-images.jianshu.io/upload_images/1931006-cedb0686a7d085bb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 149 | 之前有童鞋说,业务过程很烦,要搞个UseCase文件,然后又要搞个Repository文件,最后搞个HttpLogin,因为登录本来就只是要跟服务端确认,前面2个文件基本都是透传。是不是一定要这么死板呢?当然不是,结构可以根据业务的复杂度做调整的。比如我这里登录就是直接让HttpLogin继承MvpModel, 直接跟P层交互。 150 | ``` 151 | public class LoginHttp extends MvpModel { 152 | private static final String TAG = "LoginHttp"; 153 | 154 | /** 155 | * 密码登陆 156 | * 157 | * @param account 158 | * @param password 159 | */ 160 | public void login(String account, String password) { 161 | // execute(api.login(account, password), callback); 162 | } 163 | } 164 | ``` 165 | 如果你当前业务是只跟DB打交道,也可以让LoginDB继承MvpModel,然后在P层的泛型中确认类型即可。 166 | ##其他任意位置获取M,V,P实例 167 | 默认通过以下API获取的唯一实例,传入为实例的class类型 168 | >Mvp.getInstance().getPresenter(); 169 | Mvp.getInstance().getModel(); 170 | Mvp.getInstance().getView(); 171 | 172 | getPresenter 和 getModel 的实例默认会创建,getView 要确定Activity或者Fragment已经创建,否则可能为null。 173 | 174 | #后记 175 | 建议以文件的形式引入,方便依据工程业务做定制化。喜欢请帮忙戳喜欢,有问题欢迎评论。 176 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.0" 6 | 7 | defaultConfig { 8 | applicationId "com.wolearn.mvpframe" 9 | minSdkVersion 15 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:24.0.0' 26 | compile project(path: ':mvpframelib') 27 | } 28 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/wolearn/mvpframe/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolearn/mvpframe/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe; 2 | 3 | import android.app.Application; 4 | 5 | import com.wolearn.mvpframelib.frame.Mvp; 6 | 7 | /** 8 | * Created by wulei 9 | * Data: 2016/8/8. 10 | */ 11 | public class MyApplication extends Application{ 12 | @Override 13 | public void onCreate() { 14 | super.onCreate(); 15 | 16 | Mvp.getInstance().init(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolearn/mvpframe/login/contract/LoginContract.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe.login.contract; 2 | 3 | import com.wolearn.mvpframelib.base.BasePresenter; 4 | import com.wolearn.mvpframelib.base.BaseView; 5 | 6 | /** 7 | * Created by wulei 8 | * Data: 2016/8/4. 9 | */ 10 | public class LoginContract { 11 | public interface View extends BaseView { 12 | String getAccount(); 13 | String getPassword(); 14 | void loginSuccess(); 15 | void loginError(String errorMsg); 16 | } 17 | 18 | public interface Present extends BasePresenter { 19 | void login(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolearn/mvpframe/login/model/LoginHttp.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe.login.model; 2 | 3 | import com.wolearn.mvpframelib.frame.MvpModel; 4 | 5 | /** 6 | * Created by wulei 7 | * Data: 2016/3/30. 8 | */ 9 | public class LoginHttp extends MvpModel { 10 | private static final String TAG = "LoginHttp"; 11 | 12 | /** 13 | * 密码登陆 14 | * 15 | * @param account 16 | * @param password 17 | */ 18 | public void login(String account, String password) { 19 | // execute(api.login(account, password), callback); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolearn/mvpframe/login/presenter/LoginPresenter.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe.login.presenter; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.wolearn.mvpframe.R; 6 | import com.wolearn.mvpframe.login.contract.LoginContract; 7 | import com.wolearn.mvpframe.login.model.LoginHttp; 8 | import com.wolearn.mvpframelib.frame.MvpPresenter; 9 | 10 | /** 11 | * Created by wulei 12 | * Data: 2016/3/30. 13 | */ 14 | public class LoginPresenter extends MvpPresenter implements LoginContract.Present { 15 | private static final String TAG = "LoginPresenter"; 16 | 17 | @Override 18 | public void login() { 19 | if (!checkParameter()) return; 20 | 21 | String account = getIView().getAccount(); 22 | String password = getIView().getPassword(); 23 | 24 | mModel.login(account, password); 25 | 26 | //模拟登陆成功 27 | getIView().loginSuccess(); 28 | } 29 | 30 | /** 31 | * 登录参数校验 32 | * 33 | * @return 34 | */ 35 | private boolean checkParameter() { 36 | try { 37 | if (TextUtils.isEmpty(getIView().getAccount())) { 38 | getIView().loginError(mContext.getString(R.string.toast_account_empty)); 39 | return false; 40 | } 41 | 42 | if (TextUtils.isEmpty(getIView().getPassword())) { 43 | getIView().loginError(mContext.getString(R.string.toast_password_empty)); 44 | return false; 45 | } 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolearn/mvpframe/login/ui/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.wolearn.mvpframe.login.ui; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.widget.Button; 6 | import android.widget.EditText; 7 | import android.widget.Toast; 8 | 9 | import com.wolearn.mvpframe.R; 10 | import com.wolearn.mvpframe.login.contract.LoginContract; 11 | import com.wolearn.mvpframe.login.presenter.LoginPresenter; 12 | import com.wolearn.mvpframelib.base.BaseView; 13 | import com.wolearn.mvpframelib.frame.MvpActivity; 14 | 15 | 16 | public class LoginActivity extends MvpActivity implements LoginContract.View, View.OnClickListener { 17 | private EditText edtAccount, edtPassword; 18 | private Button btnLogin; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_login); 24 | 25 | initViews(); 26 | } 27 | 28 | @Override 29 | public BaseView getBaseView() { 30 | return this; 31 | } 32 | 33 | @Override 34 | public void onClick(View v) { 35 | mPresenter.login(); 36 | } 37 | 38 | private void initViews() { 39 | edtAccount = (EditText) findViewById(R.id.edt_account); 40 | edtPassword = (EditText) findViewById(R.id.edt_password); 41 | btnLogin = (Button) findViewById(R.id.btn_login); 42 | 43 | btnLogin.setOnClickListener(this); 44 | } 45 | 46 | @Override 47 | public void loginError(String msg) { 48 | Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show(); 49 | } 50 | 51 | @Override 52 | public void loginSuccess() { 53 | Toast.makeText(LoginActivity.this, getResources().getString(R.string.login_success), Toast.LENGTH_SHORT).show(); 54 | } 55 | 56 | @Override 57 | public String getAccount() { 58 | return edtAccount.getText().toString(); 59 | } 60 | 61 | @Override 62 | public String getPassword() { 63 | return edtPassword.getText().toString(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_btn_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_edt_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 19 | 20 | 30 | 31 |