个人作业Android学习系统开发日志二
实现Android前端搭建:
entity:
package com.example.learningmanagement.entity
data class User(
val userId: String,
val username: String,
val phoneNumber: String,
val userClass: String,
val password: String
) {
// 校验所有字段非空
private fun validateNotEmpty(): Boolean {
return userId.isNotEmpty() &&
username.isNotEmpty() &&
phoneNumber.isNotEmpty() &&
userClass.isNotEmpty() &&
password.isNotEmpty()
}
// 校验手机号格式(简单版)
private fun validatePhoneFormat(): Boolean {
return phoneNumber.matches(Regex("^1[3-9]\\d{9}$"))
}
// 综合校验
fun validateAll(): String? {
return when {
!validateNotEmpty() -> "所有字段不能为空"
!validatePhoneFormat() -> "手机号格式不正确"
password.length < 6 -> "密码至少需要6位"
else -> null // 返回null表示校验通过
}
}
}
package com.example.learningmanagement.entity
data class ApiResponse<T>(
val code: String,
val msg: String,
val data: T?
)
network:
package com.example.learningmanagement.network
import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object ServiceCreater {
val gson = GsonBuilder().setLenient().create()
// 换网修改IP地址
private const val BASE_URL="http://192.168.78.220:9090/"
private val retrofit=Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
fun <T> create(serviceClass: Class<T>): T= retrofit.create(serviceClass)
inline fun<reified T> create(): T= create(T::class.java)
}
service:
package com.example.learningmanagement.service
import com.example.learningmanagement.entity.ApiResponse
import com.example.learningmanagement.entity.User
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
interface UserApiService {
@POST("user/register")
suspend fun register(@Body user: User): ApiResponse<String>
@POST("user/login")
suspend fun login(@Body user: User): ApiResponse<User>
}
utils:
实现记住用户名:
package com.example.learningmanagement.utils
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
class PrefsHelper(context: Context) {
private val sharedPref: SharedPreferences =
context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
// 存储用户Name
fun saveLastUserName(username: String) {
sharedPref.edit() { putString("LAST_USER_NAME", username) }
}
// 获取最后登录的用户Name
fun getLastUserName(): String? {
return sharedPref.getString("LAST_USER_NAME", null)
}
// 清除存储的Name(可选)
fun clearLastUserName() {
sharedPref.edit() { remove("LAST_USER_NAME") }
}
}
activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="姓名"
android:inputType="text"/>
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"
android:layout_marginTop="8dp"/>
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:layout_marginTop="16dp"/>
<TextView
android:id="@+id/tvToRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="没有账号?立即注册"
android:textColor="@color/purple_500"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etUserId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="学号"
android:inputType="text"/>
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="姓名"
android:inputType="textPersonName"/>
<EditText
android:id="@+id/etPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="手机号"
android:inputType="phone"/>
<EditText
android:id="@+id/etClass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="班级"
android:inputType="text"/>
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"/>
<Button
android:id="@+id/btnRegister"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="注册"
android:layout_marginTop="16dp"/>
</LinearLayout>
ui:
package com.example.learningmanagement.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.example.learningmanagement.R
import com.example.learningmanagement.entity.User
import com.example.learningmanagement.network.ServiceCreater
import com.example.learningmanagement.service.UserApiService
import com.example.learningmanagement.utils.PrefsHelper
import kotlinx.coroutines.launch
class LoginActivity : AppCompatActivity() {
private val prefs by lazy { PrefsHelper(this) }
private lateinit var etUsername: EditText
private lateinit var etPassword: EditText
private lateinit var btnLogin: Button
private lateinit var tvToRegister: TextView
private val userService = ServiceCreater.create<UserApiService>()
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
// 初始化视图
etUsername = findViewById(R.id.etUsername)
etPassword = findViewById(R.id.etPassword)
btnLogin = findViewById(R.id.btnLogin)
tvToRegister = findViewById(R.id.tvToRegister)
//记住用户名
prefs.getLastUserName()?.let { savedName ->
findViewById<EditText>(R.id.etUsername).setText(savedName)
}
// 登录按钮点击事件
btnLogin.setOnClickListener {
handleLogin()
}
// 跳转到注册页面
tvToRegister.setOnClickListener {
startActivity(Intent(this, RegisterActivity::class.java))
}
}
private fun handleLogin() {
val user = User(
userId = null.toString(),
username = etUsername.text.toString().trim(),
phoneNumber = null.toString(),
userClass = null.toString(),
password = etPassword.text.toString().trim()
)
if (user.username.isEmpty() || user.password.isEmpty()) {
Toast.makeText(this, "姓名和密码不能为空", Toast.LENGTH_SHORT).show()
return
}
lifecycleScope.launch {
try {
val response = userService.login(user)
if (response.code == "200") {
Toast.makeText(
this@LoginActivity,
"登录成功",
Toast.LENGTH_SHORT
).show()
// 这里可以跳转到主页面(例如HomeActivity)
} else {
Toast.makeText(
this@LoginActivity,
"登录失败: ${response.msg}",
Toast.LENGTH_SHORT
).show()
}
} catch (e: Exception) {
Toast.makeText(
this@LoginActivity,
"网络错误: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
package com.example.learningmanagement.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.example.learningmanagement.R
import com.example.learningmanagement.entity.User
import com.example.learningmanagement.network.ServiceCreater
import com.example.learningmanagement.service.UserApiService
import com.example.learningmanagement.utils.PrefsHelper
import kotlinx.coroutines.launch
class RegisterActivity : AppCompatActivity() {
private val prefs by lazy { PrefsHelper(this) }
private lateinit var etUserId: EditText
private lateinit var etUsername: EditText
private lateinit var etPhone: EditText
private lateinit var etClass: EditText
private lateinit var etPassword: EditText
private lateinit var btnRegister: Button
private val userService = ServiceCreater.create<UserApiService>()
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
// 初始化视图
etUserId = findViewById(R.id.etUserId)
etUsername = findViewById(R.id.etUsername)
etPhone = findViewById(R.id.etPhone)
etClass = findViewById(R.id.etClass)
etPassword = findViewById(R.id.etPassword)
btnRegister = findViewById(R.id.btnRegister)
btnRegister.setOnClickListener {
handleRegister()
}
}
private fun handleRegister() {
val user = User(
userId = etUserId.text.toString().trim(),
username = etUsername.text.toString().trim(),
phoneNumber = etPhone.text.toString().trim(),
userClass = etClass.text.toString().trim(),
password = etPassword.text.toString().trim()
)
// 使用实体类的校验方法
user.validateAll()?.let { errorMsg ->
Toast.makeText(this, errorMsg, Toast.LENGTH_SHORT).show()
return
}
lifecycleScope.launch {
try {
val response = userService.register(user)
if (response.code == "200") {
prefs.saveLastUserName(user.username)
Toast.makeText(
this@RegisterActivity,
response.msg,
Toast.LENGTH_SHORT
).show()
finish()
} else {
Toast.makeText(
this@RegisterActivity,
"注册失败: ${response.msg}",
Toast.LENGTH_SHORT
).show()
}
} catch (e: Exception) {
Toast.makeText(
this@RegisterActivity,
"网络错误: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}

浙公网安备 33010602011771号