We 4 parts in our android app:
– Model
– View
– Presenter
– Activity
More explanation about this design pattern here.
you can see the complete code here.
In model is the same, nothing new:
public class SignInRequest implements Serializable { private String username,name, lastname,password,email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Our view is a interface, and it connects presenter with activity:
public interface LoginView { void showLoading(boolean state); void onRequestSuccess(Object object); void onRequestError(Object object); Context getContext(); }
In presenter We make call, you can use retrofit or any other way, in this case We choose volley:
public class LoginPresenter { private static final String TAG ="LoginPresenter" ; private LoginView loginView; private RequestQueue queue; private LoginResponse loginResponse; public LoginPresenter(LoginView loginView) { this.loginView = loginView; } public void login(String username, String password) { queue = Volley.newRequestQueue(loginView.getContext()); final String url = loginView.getContext().getString(R.string.url_login)+"?username="+username+"&password="+password; final String appID= loginView.getContext().getString(R.string.app_id); final String key= loginView.getContext().getString(R.string.rest_key); Log.i(TAG, "url " + url); JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() { @Override public void onResponse(JSONObject response) { Log.i(TAG, "response "+response.toString()); GsonBuilder gsonb = new GsonBuilder(); Gson gson = gsonb.create(); loginResponse=null; try { loginResponse= gson.fromJson(response.toString(),LoginResponse.class); if(loginResponse!=null) { Log.i(TAG, "loginResponse "+loginResponse.toString()); loginView.onRequestSuccess(response); } }catch (Exception e) { loginView.onRequestError(e); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i(TAG, "Error: " + error); loginView.onRequestError(error); } }) { @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> params = new HashMap<String, String>(); params.put("X-Parse-Application-Id", appID); params.put("X-Parse-REST-API-Key", key); return params; } }; queue.add(jsonObjReq); } public void login(Object object) { } }
Finally our activity is few lineas and clear code:
public class LoginActivity extends AppCompatActivity implements LoginView { private static final String TAG = "HomeActivity"; private EditText eteUsername,etePassword; private View btnLogin,vLoading,tviSignIn; private String username, password; private LoginPresenter loginPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); loginPresenter= new LoginPresenter(this); initiateUI(); } private void initiateUI() { eteUsername = (EditText)findViewById(R.id.eteUsername); etePassword = (EditText)findViewById(R.id.etePassword); btnLogin = findViewById(R.id.btnLogin); vLoading = findViewById(R.id.vLoading); tviSignIn = findViewById(R.id.tviSignIn); vLoading.setVisibility(View.GONE); events(); } private void events() { btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (validate()) { login(); } } }); tviSignIn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { gotoSignIn(); } }); } private boolean validate() { username = eteUsername.getText().toString().trim(); password = etePassword.getText().toString().trim(); eteUsername.setError(null); etePassword.setError(null); if(username.isEmpty()) { eteUsername.setError(getString(R.string.msg_ingresar)); return false; } if(password.isEmpty()) { etePassword.setError(getString(R.string.msg_ingresar)); return false; } return true; } private void gotoSignIn() { } private void login() { showLoading(true); loginPresenter.login(username,password); } @Override public void showLoading(boolean state) { int visibility= (state)?(View.VISIBLE):(View.GONE); vLoading.setVisibility(visibility); } @Override public void onRequestSuccess(Object object) { showLoading(false); gotoHome(); } @Override public void onRequestError(Object object) { showLoading(false); } private void gotoHome() { startActivity(new Intent(this,MainActivity.class)); finish(); } @Override public Context getContext() { return this; } @Override public boolean onCreateOptionsMenu(Menu menu) { return false; } @Override public boolean onOptionsItemSelected(MenuItem item) { return false; } }
You can see the complete code here.
Also more explanation about this design pattern here.