当前位置: 首页 > article >正文

Android :实现登录功能的思路

android的登录功能和前端一样,需要保存登录的用户信息。

  1. 创建一个工具类
// 用户工具类,用于管理用户登录状态和用户信息
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          // 清空用户信息
    }
}
  1. 发起登录请求,登录成功,则调用工具类的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()
        }
    }
  1. 一些页面,如果未登录,是不能使用的,这个时候我们可以取出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)
                                    )
                                })
                        }
                    }
                }
            }
        }
    }
}

参考资料:

  1. https://github.com/RicardoJiang/wanandroid-compose

http://www.kler.cn/a/581714.html

相关文章:

  • selenium的鼠标操作
  • SpringBoot 统一异常处理
  • JavaScript(Web APIs)
  • springboot433-基于SpringBoot的流浪猫爱心救助系统(源码+数据库+纯前后端分离+部署讲解等)
  • 消防行业如何借助 TDengine 打造高效的数据监控与分析系统
  • Spring(七)AOP-代理模式
  • 【群晖 NAS】把微软bing的背景图自动更换为群晖DSM7.X登录界面和DSM欢迎信息的教程
  • 「 DelegateUI 」Ant-d 风格的 Qt Qml UI 套件
  • VMware虚拟机迁移失败的故障排查方法
  • 文献阅读 | Nature Methods | SCENIC: 单细胞调控网络推断和聚类
  • warning: remote HEAD refers to nonexistent ref, unable to checkout.
  • Oracle 数据库导出与导入操作指南
  • 后端面试高频笔试题(非常规LeetCode类型)
  • 2025最新群智能优化算法:基于RRT的优化器(RRT-based Optimizer,RRTO)求解23个经典函数测试集,MATLAB
  • LVDS系列3:Xilinx的IOBUFDS原语
  • 通过 ElasticSearch的Python API和`curl` 命令获取Elasticsearch 所有索引名称
  • OpenManus 的提示词
  • ubuntu挂载新硬盘
  • Java中LinkedBlockingQueue在异步处理Kafka数据中的应用
  • 前端项目Axios封装Vue3详细教程(附源码)