Android :实现登录功能的思路
android的登录功能和前端一样,需要保存登录的用户信息。
- 创建一个工具类
// 用户工具类,用于管理用户登录状态和用户信息
object AppUserUtil {
// 常量定义
private const val LOGGED_FLAG = "logged_flag" // 登录状态的键名
private const val USER_INFO = "user_info" // 用户信息的键名
private const val TAG = "AppUserUtil" // 日志标签
// 登录状态属性
var isLogged: Boolean
// 获取登录状态,默认值为 false
get() = DataStoreUtils.readBooleanData(LOGGED_FLAG, false)
// 设置登录状态,并同步保存到 DataStore
set(value) = DataStoreUtils.saveSyncBooleanData(LOGGED_FLAG, value = value)
// 用户信息属性
var userInfo: UserInfo?
// 获取用户信息,从 DataStore 中读取并反序列化为 UserInfo 对象
get() = DataStoreUtils.readStringData(USER_INFO).fromJson()
// 设置用户信息,并同步保存到 DataStore
set(value) = DataStoreUtils.saveSyncStringData(USER_INFO, value = value?.toJson() ?: "")
// 登录方法
fun onLogin(userInfo: UserInfo) {
isLogged = true // 设置登录状态为 true
this.userInfo = userInfo // 保存用户信息
Log.d(TAG, "onLogin: $userInfo") // 打印登录日志
}
// 登出方法
fun onLogOut() {
isLogged = false // 设置登录状态为 false
this.userInfo = null // 清空用户信息
}
}
- 发起登录请求,登录成功,则调用工具类的onLgoin方法
private fun login() {
viewModelScope.launch {
flow {
emit(service.login(viewStates.account.trim(), viewStates.password.trim()))
}.map {
if (it.errorCode == 0) {
if (it.data != null) {
HttpResult.Success(it.data!!)
} else {
throw Exception("the result of remote's request is null")
}
} else {
throw Exception(it.errorMsg)
}
}.onEach {
AppUserUtil.onLogin(it.result)
_viewEvents.send(LoginViewEvent.PopBack)
}.catch {
_viewEvents.send(LoginViewEvent.ErrorMessage(it.message ?: ""))
}.collect()
}
}
- 一些页面,如果未登录,是不能使用的,这个时候我们可以取出isLogged 属性进行判断。
@ExperimentalFoundationApi
@Composable
fun CollectPage(
navCtrl: NavHostController,
scaffoldState: ScaffoldState,
viewModel: CollectViewModel = hiltViewModel()
) {
val viewStates = viewModel.viewStates
val collectPaging = viewStates.pagingData?.collectAsLazyPagingItems()
val webUrls = viewStates.urlList
val titles = viewStates.titles
val isRefreshing = viewStates.isRefreshing
val listState =
if ((collectPaging?.itemCount ?: 0) > 0) viewStates.listState else LazyListState()
DisposableEffect(Unit) {
Log.i("debug", "onStart")
viewModel.dispatch(CollectViewAction.OnStart)
onDispose {
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = BottomNavBarHeight)
) {
AppToolsBar(title = "我的收藏")
if (!AppUserUtil.isLogged) {
EmptyView(
tips = "点击登录",
imageVector = Icons.Default.Face
) {
RouteUtils.navTo(navCtrl, RouteName.LOGIN)
}
} else {
collectPaging?.let {
RefreshList(it, listState = listState, isRefreshing = isRefreshing, onRefresh = {
viewModel.dispatch(CollectViewAction.Refresh)
}) {
if (!webUrls.isNullOrEmpty()) {
stickyHeader {
ListTitle(title = titles[1].text)
}
item {
FlowRow(
modifier = Modifier.padding(10.dp)
) {
webUrls?.forEachIndexed { index, website ->
LabelTextButton(
text = website.name ?: "标签",
modifier = Modifier.padding(end = 10.dp, bottom = 10.dp),
onClick = {
RouteUtils.navTo(
navCtrl,
RouteName.WEB_VIEW,
WebData(website.name, website.link!!)
)
}
)
}
}
}
}
stickyHeader {
ListTitle(title = titles[0].text)
}
if (collectPaging.itemCount > 0) {
items(collectPaging) { collectItem ->
CollectListItemView(
collectItem!!,
onClick = {
RouteUtils.navTo(
navCtrl,
RouteName.WEB_VIEW,
WebData(collectItem.title, collectItem.link)
)
})
}
}
}
}
}
}
}
参考资料:
- https://github.com/RicardoJiang/wanandroid-compose