布局由几部分组成:
- 一张没网络时显示的图片;
- 一个正在加载的Progress,这两个默认都是Gone的;
- 然后就是两个EditText,
- 还有就是两个按钮,一个登录,一个清除;
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".androidmvp.ui.activity.login.Login">
<!--没网络连接时显示的图片-->
<include layout="@layout/public_noconnect" />
<!--显示正在加载的Progress-->
<include layout="@layout/public_loading" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_login_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入账号" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_login_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="登录" />
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="清除"
android:layout_marginLeft="@dimen/margin_20"
/>
</LinearLayout>
</LinearLayout>
一般登录成功后都会返回下面类似的Json数据;
{
status: true,
info: "登录成功",
results: {
userid: "17",
}
}
利用GsonFormat根据Json快速生成实体类;
public class LoginBean {
/**
* status : true
* info : 登录成功
* results : {"userid":"17"}
*/
private boolean status;
private String info;
private ResultsBean results;
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public ResultsBean getResults() {
return results;
}
public void setResults(ResultsBean results) {
this.results = results;
}
public static class ResultsBean {
private String userid;
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
}
}
对于登录这个简单的操作有几种可能出现的结果:
- 登录成功;
- 登录失败;
- 没网络连接(因为可能出现网络请求超时的情况),所以写监听登录操作的接口;
public interface OnLoginListener {
void loginSuccess(LoginBean loginBean);
void loginFailed();
void noconnect();
}
**因为登录需要用到用户名、用户密码、以及网络请求需要用到Context,
所以将需要用到的参数添加到登录接口的方法中;**
public interface ILoginBiz {
void Login(Context context,String username,String pwd,OnLoginListener onLoginListener);
}
然后就是登陆的具体操作(网络请求):
public class LoginBiz implements ILoginBiz {
@Override
public void Login(final Context context, String username, String pwd, final OnLoginListener onLoginListener) {
RequestQueue queue = Volley.newRequestQueue(context);
String path = "换成自己的测试网址";
HashMap<String ,String> map = new HashMap<>();
map.put("user",username);
map.put("pwd",pwd);
JsonObjectPostRequest json = new JsonObjectPostRequest(path, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
boolean status = response.getBoolean("status");
String info = response.getString("info");
if (status) {
Gson gson = new Gson();
LoginBean loginBean = gson.fromJson(response.toString(), LoginBean.class);
//登录成功
onLoginListener.loginSuccess(loginBean);
}else {
//登录失败
onLoginListener.loginFailed();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//网络超时,显示无网络连接的图片
onLoginListener.noconnect();
}
},map);
queue.add(json);
}
}
View中需要的操作有以下几个:
1. 登录操作需要用到用户名以及用户密码,所以,需要得到两个EditText中的文本内容;
2. 有网络连接以及没网络连接时,需要显示或者隐藏网络连接图片;
3. 加载中以及加载完成需要显示或者隐藏Progress;
4. 点击清除按钮的时候,需要清除两个EditText中的文本内容;
5. 登陆成功之后需要跳到主界面;根据这些需求操作,写出下面的LoginView;
public interface LoginView {
String getUserName();
String getUserPwd();
void noConnect();
void isConnect();
void showLoading();
void hideLoading();
void clearETInfo();
void toMainActivity();
}
**然后就是Presenter,像登陆这个界面比较简单,只有一个登录和一个清除文本的操作,
所以一个Presenter就足够了,如果界面包含多个操作的时候,可以用多个Presenter;**
public class LoginPresenter {
private Context context;
private LoginView loginView;
private LoginBiz loginBiz;
public LoginPresenter(Context context, LoginView loginView) {
this.context = context;
this.loginView = loginView;
loginBiz = new LoginBiz();
}
public void Login() {
if (!NetUtils.isNetworkConnected(context)) {
loginView.noConnect();
ToastUtil.ShowError(context);
} else {
loginView.isConnect();
if (loginView.getUserName().isEmpty() || loginView.getUserPwd().isEmpty()) {
ToastUtil.showToast(context, "账号或者密码不能为空");
} else {
loginView.showLoading();
loginBiz.Login(context, loginView.getUserName(), loginView.getUserPwd(), new OnLoginListener() {
@Override
public void loginSuccess(LoginBean loginBean) {
loginView.hideLoading();
loginView.toMainActivity();
}
@Override
public void loginFailed() {
loginView.hideLoading();
}
@Override
public void noconnect() {
loginView.hideLoading();
loginView.noConnect();
}
});
}
}
}
public void clear() {
loginView.clearETInfo();
}
}
最后是View也就是我们的Activity或者Fragment:
public class Login extends AppCompatActivity implements LoginView {
@InjectView(R.id.ll_loading)
LinearLayout llLoading;
@InjectView(R.id.et_login_user)
EditText etLoginUser;
@InjectView(R.id.et_login_pwd)
EditText etLoginPwd;
@InjectView(R.id.btn_login)
Button btnLogin;
@InjectView(R.id.btn_clear)
Button btnClear;
@InjectView(R.id.ll_noconnect)
LinearLayout llNoconnect;
private Context context;
private LoginPresenter loginPresenter = new LoginPresenter(this, this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.inject(this);
context = this;
}
@OnClick({R.id.ll_noconnect, R.id.btn_login, R.id.btn_clear})
public void onClick(View view) {
switch (view.getId()) {
case R.id.ll_noconnect:
loginPresenter.Login();
break;
case R.id.btn_login:
loginPresenter.Login();
break;
case R.id.btn_clear:
loginPresenter.clear();
break;
}
}
@Override
public String getUserName() {
return etLoginUser.getText().toString();
}
@Override
public String getUserPwd() {
return etLoginPwd.getText().toString();
}
@Override
public void noConnect() { llNoconnect.setVisibility(View.VISIBLE);}
@Override
public void isConnect() {
llNoconnect.setVisibility(View.GONE);
}
@Override
public void showLoading() {
llLoading.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
llLoading.setVisibility(View.GONE);
}
@Override
public void clearETInfo() {
etLoginPwd.setText("");
etLoginUser.setText("");
}
@Override
public void toMainActivity() {
startActivity(new Intent(Login.this, MainActivity.class));
finish();
}
}
参考资料:
http://blog.csdn.net/lmj623565791/article/details/46596109