1.登录/注销功能实现

2.注册页面UI
This commit is contained in:
BA7LZD 2020-05-27 02:14:24 +08:00
parent 4ac14b54d9
commit 7ba043fba3
26 changed files with 697 additions and 263 deletions

View File

@ -60,6 +60,8 @@ dependencies {
implementation 'com.tencent.qcloud:cosxml:5.4.31'
//
implementation 'com.sackcentury:shinebutton:1.0.0'
//
implementation 'com.blankj:utilcodex:1.28.4'
//
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'

View File

@ -54,6 +54,7 @@
android:name=".gsv.SimpleDetailActivityMode2"
android:theme="@style/DetailTheme" />
<activity android:name=".comm.BaseActivity" />
<activity android:name=".ui.reg.login.RegActivity" />
</application>
</manifest>

View File

@ -0,0 +1,6 @@
package com.yuxihan.sdu.comm;
public class Const {
public static final String LOGIN_STATE = "LoginState";
public static final String LOGIN_TOKEN = "LoginToken";
}

View File

@ -44,7 +44,9 @@ public class SDUApp extends Application {
NineGridView.setImageLoader(new GlideImageLoader());
}
/** Glide 加载 */
/**
* Glide 加载
*/
private static class GlideImageLoader implements NineGridView.ImageLoader {
@Override
public void onDisplayImage(Context context, ImageView imageView, String url) {
@ -80,10 +82,7 @@ public class SDUApp extends Application {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request mRequest = chain.request().newBuilder()
.header("User-Agent", "android/" /* +
App.VERSIONNAME + "(" +
DeviceUtils.getSDKVersion() + ";" +
DeviceUtils.getModel() + ")"*/)
.header("User-Agent", "android/")
.build();
return chain.proceed(mRequest);
}

View File

@ -0,0 +1,19 @@
package com.yuxihan.sdu.comm.util;
import java.util.List;
public class DataUtil {
/**
* 字符串判空
*/
public static boolean isEmpty(String src) {
return null != src && src.length() > 0;
}
/**
* List判空
*/
public static boolean isEmpty(List src) {
return null != src && src.size() > 0;
}
}

View File

@ -0,0 +1,34 @@
package com.yuxihan.sdu.comm.util;
import android.text.TextUtils;
public class FormatUtils {
/**
* 验证手机格式
*/
public static boolean isMobileNO(String mobiles) {
/*
移动134135136137138139150151157(TD)158159187188
联通130131132152155156185186
电信1331531801891349卫通
总结起来就是第一位必定为1第二位必定为3或5或8其他位置的可以为0-9
------------------------------------------------
13()号段130131132133134135136137138139
14()号段145147
15()号段150151152153154155156157158159
17()号段170171173175176177178
18(3G)号段180181182183184185186187188189
*/
String telRegex = "[1][34578]\\d{9}";//"[1]"代表第1位为数字1"[358]"代表第二位可以为34578中的一个"\\d{9
// }"代表后面是可以是09的数字有9位。
if (TextUtils.isEmpty(mobiles)) return false;
else return mobiles.matches(telRegex);
}
public static boolean isPassword(String password) {
if (TextUtils.isEmpty(password)) return false;
else return password.length() >= 6;
}
}

View File

@ -1,61 +0,0 @@
package com.yuxihan.sdu.data;
import android.util.Log;
import com.yuxihan.sdu.comm.Constant;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoggedInUser;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Class that handles authentication w/ login credentials and retrieves user information.
*/
public class LoginDataSource {
public Result<LoggedInUser> login(final String username, String password) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.login(username, password);
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
String result = response.body().toString();
Log.e("TAG", "Url ===== " + result);
}
@Override
public void onFailure(Call<DataBean> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败");
}
});
return new Result.Success<>(new LoggedInUser(username, username));
/*try {
// TODO: handle loggedInUser authentication
LoggedInUser fakeUser =
new LoggedInUser(
java.util.UUID.randomUUID().toString(),
"Jane Doe");
return new Result.Success<>(fakeUser);
} catch (Exception e) {
return new Result.Error(new IOException("Error logging in", e));
}*/
}
public void logout() {
// TODO: revoke authentication
}
}

View File

@ -1,54 +0,0 @@
package com.yuxihan.sdu.data;
import com.yuxihan.sdu.data.model.LoggedInUser;
/**
* Class that requests authentication and user information from the remote data source and
* maintains an in-memory cache of login status and user credentials information.
*/
public class LoginRepository {
private static volatile LoginRepository instance;
private LoginDataSource dataSource;
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
private LoggedInUser user = null;
// private constructor : singleton access
private LoginRepository(LoginDataSource dataSource) {
this.dataSource = dataSource;
}
public static LoginRepository getInstance(LoginDataSource dataSource) {
if (instance == null) {
instance = new LoginRepository(dataSource);
}
return instance;
}
public boolean isLoggedIn() {
return user != null;
}
public void logout() {
user = null;
dataSource.logout();
}
private void setLoggedInUser(LoggedInUser user) {
this.user = user;
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
}
public Result<LoggedInUser> login(String username, String password) {
// handle login
Result<LoggedInUser> result = dataSource.login(username, password);
if (result instanceof Result.Success) {
setLoggedInUser(((Result.Success<LoggedInUser>) result).getData());
}
return result;
}
}

View File

@ -3,14 +3,18 @@ package com.yuxihan.sdu.data.model;
public class DataBean {
/**
* errCode : 1
* errMsg :
* result :
* {
* "errCode": "0",
* "errMsg": "",
* "result": {
* "token": "af8bffa1-e0f7-4956-a514-48fee10719e7"
* }
* }
*/
private String errCode;
private String errMsg;
private String result;
private LoginRetVo result;
public String getErrCode() {
return errCode;
@ -28,11 +32,11 @@ public class DataBean {
this.errMsg = errMsg;
}
public String getResult() {
public LoginRetVo getResult() {
return result;
}
public void setResult(String result) {
public void setResult(LoginRetVo result) {
this.result = result;
}
@ -41,7 +45,7 @@ public class DataBean {
return "DataBean{" +
"errCode='" + errCode + '\'' +
", errMsg='" + errMsg + '\'' +
", result='" + result + '\'' +
", result=" + result +
'}';
}
}

View File

@ -7,12 +7,19 @@ public class LoggedInUser {
private String userId;
private String displayName;
boolean loginSuccess = true;
public LoggedInUser(String userId, String displayName) {
this.userId = userId;
this.displayName = displayName;
}
public LoggedInUser(String userId, String displayName, boolean loginSuccess) {
this.userId = userId;
this.displayName = displayName;
this.loginSuccess = loginSuccess;
}
public String getUserId() {
return userId;
}
@ -20,4 +27,16 @@ public class LoggedInUser {
public String getDisplayName() {
return displayName;
}
public void setUserId(String userId) {
this.userId = userId;
}
public boolean isLoginSuccess() {
return loginSuccess;
}
public void setLoginSuccess(boolean loginSuccess) {
this.loginSuccess = loginSuccess;
}
}

View File

@ -0,0 +1,36 @@
package com.yuxihan.sdu.data.model;
import java.util.Objects;
public class LoginRetVo {
private String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "LoginRetVo{" +
"token='" + token + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LoginRetVo that = (LoginRetVo) o;
return Objects.equals(token, that.token);
}
@Override
public int hashCode() {
return Objects.hash(token);
}
}

View File

@ -1,5 +1,7 @@
package com.yuxihan.sdu.ui.account;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -11,8 +13,11 @@ import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.blankj.utilcode.util.SPUtils;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseFragment;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.ui.login.LoginActivity;
public class AccountFragment extends BaseFragment {
@ -30,6 +35,20 @@ public class AccountFragment extends BaseFragment {
textView.setText(s);
}
});
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SPUtils.getInstance().put(Const.LOGIN_STATE, false);
SPUtils.getInstance().put(Const.LOGIN_TOKEN, "");
startActivity(new Intent(getContext(), LoginActivity.class));
Activity activity = getActivity();
if (null != activity) {
activity.finish();
}
}
});
return root;
}
}

View File

@ -10,7 +10,7 @@ public class AccountViewModel extends ViewModel {
public AccountViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
mText.setValue("注销");
}
public LiveData<String> getText() {

View File

@ -1,17 +0,0 @@
package com.yuxihan.sdu.ui.login;
/**
* Class exposing authenticated user details to the UI.
*/
class LoggedInUserView {
private String displayName;
//... other data fields that may be accessible to the UI
LoggedInUserView(String displayName) {
this.displayName = displayName;
}
String getDisplayName() {
return displayName;
}
}

View File

@ -23,6 +23,8 @@ import com.gyf.immersionbar.ImmersionBar;
import com.yuxihan.sdu.MainActivity;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.data.model.LoggedInUser;
import com.yuxihan.sdu.ui.reg.login.RegActivity;
public class LoginActivity extends BaseActivity {
@ -39,8 +41,27 @@ public class LoginActivity extends BaseActivity {
final EditText usernameEditText = findViewById(R.id.username);
final EditText passwordEditText = findViewById(R.id.password);
final Button loginButton = findViewById(R.id.login);
final TextView regButton = findViewById(R.id.tv_reg);
final ProgressBar loadingProgressBar = findViewById(R.id.loading);
loginViewModel.getLoggedInUser().observe(this, new Observer<LoggedInUser>() {
@Override
public void onChanged(LoggedInUser loginResult) {
if (loginResult == null) {
return;
}
loadingProgressBar.setVisibility(View.GONE);
if (loginResult.isLoginSuccess()) {
startActivity(new Intent(getApplicationContext(), MainActivity.class));
setResult(Activity.RESULT_OK);
finish();
} else {
Toast.makeText(LoginActivity.this, loginResult.getDisplayName(),
Toast.LENGTH_LONG).show();
}
}
});
loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
@Override
public void onChanged(@Nullable LoginFormState loginFormState) {
@ -57,26 +78,6 @@ public class LoginActivity extends BaseActivity {
}
});
loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
@Override
public void onChanged(@Nullable LoginResult loginResult) {
if (loginResult == null) {
return;
}
loadingProgressBar.setVisibility(View.GONE);
if (loginResult.getError() != null) {
showLoginFailed(loginResult.getError());
}
if (loginResult.getSuccess() != null) {
updateUiWithUser(loginResult.getSuccess());
}
setResult(Activity.RESULT_OK);
//Complete and destroy login activity once successful
finish();
}
});
TextWatcher afterTextChangedListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -116,15 +117,14 @@ public class LoginActivity extends BaseActivity {
passwordEditText.getText().toString());
}
});
}
private void updateUiWithUser(LoggedInUserView model) {
/*
String welcome = getString(R.string.welcome) + model.getDisplayName();
// TODO : initiate successful logged in experience
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
*/
startActivity(new Intent(getApplicationContext(), MainActivity.class));
regButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), RegActivity.class));
}
});
}
private void showLoginFailed(@StringRes Integer errorString) {

View File

@ -1,31 +0,0 @@
package com.yuxihan.sdu.ui.login;
import androidx.annotation.Nullable;
/**
* Authentication result : success (user details) or error message.
*/
class LoginResult {
@Nullable
private LoggedInUserView success;
@Nullable
private Integer error;
LoginResult(@Nullable Integer error) {
this.error = error;
}
LoginResult(@Nullable LoggedInUserView success) {
this.success = success;
}
@Nullable
LoggedInUserView getSuccess() {
return success;
}
@Nullable
Integer getError() {
return error;
}
}

View File

@ -1,73 +1,68 @@
package com.yuxihan.sdu.ui.login;
import android.util.Patterns;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.data.LoginRepository;
import com.yuxihan.sdu.data.Result;
import com.blankj.utilcode.util.SPUtils;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.FormatUtils;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoggedInUser;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginViewModel extends ViewModel {
private MutableLiveData<LoggedInUser> loggedInUser = new MutableLiveData<>();
private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>();
private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();
private LoginRepository loginRepository;
LoginViewModel(LoginRepository loginRepository) {
this.loginRepository = loginRepository;
public MutableLiveData<LoggedInUser> getLoggedInUser() {
return loggedInUser;
}
LiveData<LoginFormState> getLoginFormState() {
return loginFormState;
}
LiveData<LoginResult> getLoginResult() {
return loginResult;
}
public void login(String username, String password) {
// can be launched in a separate asynchronous job
Result<LoggedInUser> result = loginRepository.login(username, password);
if (result instanceof Result.Success) {
LoggedInUser data = ((Result.Success<LoggedInUser>) result).getData();
loginResult.setValue(new LoginResult(new LoggedInUserView(data.getDisplayName())));
} else {
loginResult.setValue(new LoginResult(R.string.login_failed));
}
}
public void loginDataChanged(String username, String password) {
loginFormState.setValue(new LoginFormState(true));
/*
if (!isUserNameValid(username)) {
loginFormState.setValue(new LoginFormState(R.string.invalid_username, null));
} else if (!isPasswordValid(password)) {
loginFormState.setValue(new LoginFormState(null, R.string.invalid_password));
} else {
if (FormatUtils.isMobileNO(username) && FormatUtils.isPassword(password)) {
loginFormState.setValue(new LoginFormState(true));
}
*/
}
// A placeholder username validation check
private boolean isUserNameValid(String username) {
if (username == null) {
return false;
}
if (username.contains("@")) {
return Patterns.EMAIL_ADDRESS.matcher(username).matches();
} else {
return !username.trim().isEmpty();
loginFormState.setValue(new LoginFormState(false));
}
}
// A placeholder password validation check
private boolean isPasswordValid(String password) {
return password != null && password.trim().length() > 5;
public void login(final String username, String password) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.login(username, password);
call.enqueue(new Callback<DataBean>() {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if ("0" .equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
loggedInUser.setValue(new LoggedInUser(username, username));
SPUtils.getInstance().put("LoginState", true);
SPUtils.getInstance().put("LoginToken", response.body().getResult().getToken());
} else {
loggedInUser.setValue(new LoggedInUser(username, "用户名/密码 错误!", false));
}
}
@Override
public void onFailure(Call<DataBean> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败:" + t.getMessage());
loggedInUser.setValue(new LoggedInUser(username, "\"服务器开小差了!\"", false));
}
});
}
}

View File

@ -1,11 +1,8 @@
package com.yuxihan.sdu.ui.login;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.annotation.NonNull;
import com.yuxihan.sdu.data.LoginDataSource;
import com.yuxihan.sdu.data.LoginRepository;
/**
* ViewModel provider factory to instantiate LoginViewModel.
@ -18,7 +15,7 @@ public class LoginViewModelFactory implements ViewModelProvider.Factory {
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(LoginViewModel.class)) {
return (T) new LoginViewModel(LoginRepository.getInstance(new LoginDataSource()));
return (T) new LoginViewModel();
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}

View File

@ -0,0 +1,136 @@
package com.yuxihan.sdu.ui.reg.login;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.gyf.immersionbar.ImmersionBar;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.ui.login.LoginActivity;
public class RegActivity extends BaseActivity {
private RegViewModel regViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg);
ImmersionBar.with(this).titleBar(R.id.toolbar).keyboardEnable(true).init();
regViewModel = new ViewModelProvider(this, new RegViewModelFactory())
.get(RegViewModel.class);
final EditText usernameEditText = findViewById(R.id.username);
final EditText passwordEditText = findViewById(R.id.password);
passwordEditText.setInputType(128);
final TextView btGetVerification = findViewById(R.id.bt_get_verification);
btGetVerification.setEnabled(false);
btGetVerification.setTextColor(getResources().getColor(R.color.gray));
final Button loginButton = findViewById(R.id.login);
final ProgressBar loadingProgressBar = findViewById(R.id.loading);
btGetVerification.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO:请求发送验证码
btGetVerification.setText("验证码已发送");
}
});
regViewModel.getRegFormState().observe(this, new Observer<RegFormState>() {
@Override
public void onChanged(@Nullable RegFormState regFormState) {
if (regFormState == null) {
return;
}
btGetVerification.setEnabled(regFormState.isPhoneNumberValid());
if (regFormState.isPhoneNumberValid()) {
btGetVerification.setTextColor(getResources().getColor(R.color.colorPrimary));
} else {
btGetVerification.setTextColor(getResources().getColor(R.color.gray));
}
loginButton.setEnabled(regFormState.isDataValid());
if (regFormState.getUsernameError() != null) {
usernameEditText.setError(getString(regFormState.getUsernameError()));
}
if (regFormState.getPasswordError() != null) {
passwordEditText.setError(getString(regFormState.getPasswordError()));
}
}
});
// loadingProgressBar.setVisibility(View.GONE);
TextWatcher afterTextChangedListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ignore
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// ignore
}
@Override
public void afterTextChanged(Editable s) {
regViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
};
usernameEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
regViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
return false;
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadingProgressBar.setVisibility(View.VISIBLE);
regViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
});
}
private void updateUiWithUser() {
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
}
private void showLoginFailed(@StringRes Integer errorString) {
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
}
}

View File

@ -0,0 +1,49 @@
package com.yuxihan.sdu.ui.reg.login;
import androidx.annotation.Nullable;
/**
* Data validation state of the login form.
*/
class RegFormState {
@Nullable
private Integer usernameError;
@Nullable
private Integer passwordError;
private boolean isDataValid;
private boolean isPhoneNumberValid;
RegFormState(@Nullable Integer usernameError, @Nullable Integer passwordError) {
this.usernameError = usernameError;
this.passwordError = passwordError;
this.isDataValid = false;
}
RegFormState(boolean isDataValid) {
this.usernameError = null;
this.passwordError = null;
this.isDataValid = isDataValid;
}
@Nullable
Integer getUsernameError() {
return usernameError;
}
@Nullable
Integer getPasswordError() {
return passwordError;
}
boolean isDataValid() {
return isDataValid;
}
public boolean isPhoneNumberValid() {
return isPhoneNumberValid;
}
public void setPhoneNumberValid(boolean phoneNumberValid) {
isPhoneNumberValid = phoneNumberValid;
}
}

View File

@ -0,0 +1,29 @@
package com.yuxihan.sdu.ui.reg.login;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.comm.util.FormatUtils;
public class RegViewModel extends ViewModel {
private MutableLiveData<RegFormState> regFormState = new MutableLiveData<>();
LiveData<RegFormState> getRegFormState() {
return regFormState;
}
public void login(String username, String password) {
}
public void loginDataChanged(String username, String password) {
RegFormState regFormState = new RegFormState(true);
regFormState.setPhoneNumberValid(FormatUtils.isMobileNO(username));
this.regFormState.setValue(regFormState);
}
}

View File

@ -0,0 +1,23 @@
package com.yuxihan.sdu.ui.reg.login;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
public class RegViewModelFactory implements ViewModelProvider.Factory {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(RegViewModel.class)) {
return (T) new RegViewModel();
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
}

View File

@ -3,8 +3,11 @@ package com.yuxihan.sdu.ui.splash;
import android.content.Intent;
import android.os.Bundle;
import com.blankj.utilcode.util.SPUtils;
import com.yuxihan.sdu.MainActivity;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.ui.login.LoginActivity;
public class InitializeActivity extends BaseActivity {
@ -13,7 +16,11 @@ public class InitializeActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_initialize);
startActivity(new Intent(this, LoginActivity.class));
if (SPUtils.getInstance().getBoolean(Const.LOGIN_STATE)) {
startActivity(new Intent(this, MainActivity.class));
} else {
startActivity(new Intent(this, LoginActivity.class));
}
finish();
}
}

View File

@ -78,6 +78,7 @@
android:background="@null"
android:hint="请输入手机号"
android:inputType="number"
android:text="13812345678"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</LinearLayout>
@ -118,6 +119,7 @@
android:background="@null"
android:hint="请输入密码"
android:inputType="textPassword"
android:text="123456"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</LinearLayout>
@ -154,15 +156,14 @@
</androidx.cardview.widget.CardView>
<TextView
android:visibility="invisible"
android:id="@+id/tv_forget_password"
android:id="@+id/tv_reg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="30dp"
android:text="忘记密码?"
android:textColor="#333333"
android:textSize="14sp" />
android:text="注册"
android:textColor="#3333FF"
android:textSize="20sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="@drawable/shape"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="注册"
app:titleTextColor="@android:color/white" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f9f9f9"
android:fillViewport="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f9f9f9"
android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:gravity="center_horizontal"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="30dp"
android:background="@android:color/white"
app:cardCornerRadius="22dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:gravity="center_vertical">
<TextView
android:layout_width="66dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:alpha="0.4"
android:text="手机号"
android:textColor="@color/black"
android:textSize="14sp" />
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="14dp"
android:background="@null"
android:hint="请输入手机号"
android:inputType="number"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="30dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="30dp"
app:cardCornerRadius="22dp">
<Button
android:id="@+id/bt_get_verification"
android:layout_width="100dp"
android:layout_height="35dp"
android:background="@null"
android:gravity="center"
android:text="获取验证码"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="30dp"
android:background="@android:color/white"
app:cardCornerRadius="22dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:gravity="center_vertical">
<TextView
android:layout_width="66dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:alpha="0.4"
android:text="验证码"
android:textColor="@color/black"
android:textSize="14sp" />
<EditText
android:id="@+id/et_verification"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="14dp"
android:background="@null"
android:hint="请输入验证码"
android:inputType="number"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="30dp"
android:layout_marginBottom="30dp"
android:background="@android:color/white"
app:cardCornerRadius="22dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:gravity="center_vertical">
<TextView
android:layout_width="66dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:alpha="0.4"
android:text="密码"
android:textColor="@color/black"
android:textSize="14sp" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="14dp"
android:background="@null"
android:hint="请输入密码"
android:inputType="textPassword"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="32dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="164dp"
android:visibility="gone" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
app:cardCornerRadius="2dp">
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@drawable/shape"
android:gravity="center"
android:text="注册"
android:textColor="@android:color/white"
android:textSize="14sp" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tv_reg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="30dp"
android:text="注册"
android:textColor="#3333FF"
android:textSize="20sp"
android:visibility="invisible" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -6,7 +6,7 @@
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
<color name="text_black">#101010</color>
<color name="gray">#AAFFFFFF</color>
<color name="gray">#888888</color>
<color name="white_bg">#fafafa</color>
<color name="divider_gray">#eeeeee</color>