<?xml version="1.0" encoding="utf-8"?>
<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"
android:padding="16dp"
tools:context=".LoginActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:textSize="24sp"
android:textStyle="bold"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="24dp"/>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:inputType="text"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/tvForgotPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="忘记密码?"
android:layout_gravity="end"/>
<TextView
android:id="@+id/tvRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册新账号"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"/>
</LinearLayout>
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnLogin.setOnClickListener {
val username = binding.etUsername.text.toString()
val password = binding.etPassword.text.toString()
if (validateInput(username, password)) {
// 执行登录逻辑
performLogin(username, password)
}
}
binding.tvForgotPassword.setOnClickListener {
// 跳转到找回密码页面
startActivity(Intent(this, ForgotPasswordActivity::class.java))
}
binding.tvRegister.setOnClickListener {
// 跳转到注册页面
startActivity(Intent(this, RegisterActivity::class.java))
}
}
private fun validateInput(username: String, password: String): Boolean {
if (username.isEmpty()) {
binding.etUsername.error = "用户名不能为空"
return false
}
if (password.isEmpty()) {
binding.etPassword.error = "密码不能为空"
return false
}
if (password.length < 6) {
binding.etPassword.error = "密码长度至少6位"
return false
}
return true
}
private fun performLogin(username: String, password: String) {
// 显示加载进度条
val progressDialog = ProgressDialog(this).apply {
setMessage("正在登录...")
setCancelable(false)
}
progressDialog.show()
// 模拟网络请求
Handler(Looper.getMainLooper()).postDelayed({
progressDialog.dismiss()
if (username == "admin" && password == "123456") {
// 登录成功,跳转到主页面
startActivity(Intent(this, MainActivity::class.java))
finish()
} else {
// 登录失败,显示错误提示
Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_SHORT).show()
}
}, 2000)
}
}
public class LoginActivity extends AppCompatActivity {
private ActivityLoginBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.btnLogin.setOnClickListener(v -> {
String username = binding.etUsername.getText().toString();
String password = binding.etPassword.getText().toString();
if (validateInput(username, password)) {
performLogin(username, password);
}
});
binding.tvForgotPassword.setOnClickListener(v -> {
startActivity(new Intent(this, ForgotPasswordActivity.class));
});
binding.tvRegister.setOnClickListener(v -> {
startActivity(new Intent(this, RegisterActivity.class));
});
}
private boolean validateInput(String username, String password) {
if (username.isEmpty()) {
binding.etUsername.setError("用户名不能为空");
return false;
}
if (password.isEmpty()) {
binding.etPassword.setError("密码不能为空");
return false;
}
if (password.length() < 6) {
binding.etPassword.setError("密码长度至少6位");
return false;
}
return true;
}
private void performLogin(String username, String password) {
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("正在登录...");
progressDialog.setCancelable(false);
progressDialog.show();
new Handler(Looper.getMainLooper()).postDelayed(() -> {
progressDialog.dismiss();
if (username.equals("admin") && password.equals("123456")) {
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
}
}, 2000);
}
}
class LoginViewModel : ViewModel() {
private val _loginResult = MutableLiveData<LoginResult>()
val loginResult: LiveData<LoginResult> = _loginResult
fun login(username: String, password: String) {
viewModelScope.launch {
try {
// 模拟网络请求
delay(2000)
if (username == "admin" && password == "123456") {
_loginResult.value = LoginResult(success = true)
} else {
_loginResult.value = LoginResult(error = "用户名或密码错误")
}
} catch (e: Exception) {
_loginResult.value = LoginResult(error = "网络错误: ${e.message}")
}
}
}
}
data class LoginResult(
val success: Boolean = false,
val error: String? = null
)
在build.gradle中启用数据绑定:
android {
...
buildFeatures {
dataBinding true
}
}
更新布局文件:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.example.app.LoginViewModel" />
</data>
<!-- 原有布局内容 -->
</layout>
在布局中添加CheckBox:
<CheckBox
android:id="@+id/cbRemember"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"/>
在Activity中添加处理逻辑:
private val sharedPref by lazy {
getSharedPreferences("login_prefs", Context.MODE_PRIVATE)
}
// 在onCreate中
binding.cbRemember.isChecked = sharedPref.getBoolean("remember", false)
if (binding.cbRemember.isChecked) {
binding.etUsername.setText(sharedPref.getString("username", ""))
binding.etPassword.setText(sharedPref.getString("password", ""))
}
// 在登录成功后
if (binding.cbRemember.isChecked) {
sharedPref.edit().apply {
putString("username", username)
putString("password", password)
putBoolean("remember", true)
apply()
}
} else {
sharedPref.edit().clear().apply()
}
密码安全:
输入验证:
用户体验:
com.example.app
├── auth
│ ├── LoginActivity.kt
│ ├── RegisterActivity.kt
│ ├── ForgotPasswordActivity.kt
│ └── viewmodel
│ ├── LoginViewModel.kt
│ └── AuthRepository.kt
├── ui
│ └── MainActivity.kt
└── data
├── model
│ └── User.kt
└── ApiService.kt
希望这个指南对您开发Android登录界面有所帮助!根据您的具体需求,可以进一步扩展和定制这个基础实现。