Android应用同一登录页针对不同用户类型的功能区分代码结构设计
嘿,这个需求在多用户类型的Android应用里太常见了,我来给你拆解一下怎么设计代码结构,既能满足当前需求,又能方便以后扩展~
核心思路:先识别用户类型,再按需分发功能
本质上就是登录后拿到用户身份标识,再根据身份匹配对应的功能入口和权限,下面从代码结构的各个层面给你具体方案:
1. 先定义清晰的用户模型
首先要把用户类型标准化,用枚举类来约束,避免硬编码字符串,这样后续扩展新类型也方便:
// Kotlin示例,Java可以用enum类 enum class UserType { ADMIN, // 管理员 NORMAL_USER, // 普通用户 MERCHANT // 以后可能加的商家用户 } // 用户数据类,包含类型字段 data class User( val userId: String, val username: String, val userType: UserType, // 其他必要字段:头像、token等 )
2. 登录流程:拿到用户类型后持久化
登录接口返回用户信息时,一定要包含userType字段。登录成功后,把用户信息持久化到本地(比如SharedPreferences、Room或者DataStore),方便后续页面快速获取用户类型:
// 全局用户管理类,统一处理用户信息的读写 object UserManager { private const val KEY_USER = "current_user" private val gson = Gson() // 保存登录用户 fun saveCurrentUser(user: User) { val userJson = gson.toJson(user) PreferenceManager.getDefaultSharedPreferences(AppContext) .edit() .putString(KEY_USER, userJson) .apply() } // 获取当前登录用户 fun getCurrentUser(): User? { val userJson = PreferenceManager.getDefaultSharedPreferences(AppContext) .getString(KEY_USER, null) return userJson?.let { gson.fromJson(it, User::class.java) } } // 退出登录时清除用户信息 fun logout() { PreferenceManager.getDefaultSharedPreferences(AppContext) .edit() .remove(KEY_USER) .apply() } }
登录成功后的处理逻辑:
// LoginActivity中登录接口的回调 private fun handleLoginResponse(user: User) { UserManager.saveCurrentUser(user) // 根据用户类型跳转到对应主页 navigateToHome(user.userType) finish() // 关闭登录页 }
3. 页面路由:根据用户类型分发入口
用一个统一的导航类来处理页面跳转,避免在Activity里写一堆if-else,代码更整洁:
object UserNavigation { fun navigateToHome(context: Context, userType: UserType) { val intent = when(userType) { UserType.ADMIN -> Intent(context, AdminHomeActivity::class.java) UserType.NORMAL_USER -> Intent(context, NormalHomeActivity::class.java) UserType.MERCHANT -> Intent(context, MerchantHomeActivity::class.java) } context.startActivity(intent) } }
如果想做更灵活的(比如同一主页展示不同功能模块),可以用策略模式来加载不同的功能:
策略模式实现功能动态加载
先定义功能策略接口:
interface HomeFeatureStrategy { // 返回当前用户可访问的功能列表 fun getAvailableFeatures(): List<FeatureItem> } // 管理员功能策略 class AdminFeatureStrategy : HomeFeatureStrategy { override fun getAvailableFeatures(): List<FeatureItem> { return listOf( FeatureItem("用户管理", R.drawable.ic_user_manage), FeatureItem("数据统计", R.drawable.ic_data_stat), FeatureItem("系统设置", R.drawable.ic_settings) ) } } // 普通用户功能策略 class NormalUserFeatureStrategy : HomeFeatureStrategy { override fun getAvailableFeatures(): List<FeatureItem> { return listOf( FeatureItem("我的订单", R.drawable.ic_order), FeatureItem("个人中心", R.drawable.ic_profile) ) } } // 策略工厂,根据用户类型返回对应策略 object FeatureStrategyFactory { fun createStrategy(userType: UserType): HomeFeatureStrategy { return when(userType) { UserType.ADMIN -> AdminFeatureStrategy() UserType.NORMAL_USER -> NormalUserFeatureStrategy() UserType.MERCHANT -> MerchantFeatureStrategy() // 扩展时新增 } } }
然后在主页里使用:
// HomeActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) val currentUser = UserManager.getCurrentUser() ?: run { // 未登录,跳回登录页 startActivity(Intent(this, LoginActivity::class.java)) finish() return } // 获取对应策略,加载功能 val strategy = FeatureStrategyFactory.createStrategy(currentUser.userType) val features = strategy.getAvailableFeatures() // 把features渲染到RecyclerView featureRecyclerView.adapter = FeatureAdapter(features) }
4. 权限控制:防止非法访问
每个功能页面都要做用户类型校验,避免用户通过跳转直接进入不属于自己的页面:
// AdminHomeActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val currentUser = UserManager.getCurrentUser() if (currentUser?.userType != UserType.ADMIN) { // 无权限,跳回对应主页或提示 UserNavigation.navigateToHome(this, currentUser?.userType ?: UserType.NORMAL_USER) Toast.makeText(this, "无权限访问此页面", Toast.LENGTH_SHORT).show() finish() return } // 正常加载管理员页面内容 }
5. 代码分层建议(推荐MVVM)
为了让代码更易维护,建议采用分层架构:
- 数据层:负责网络请求(登录接口)、本地存储(UserManager),比如
LoginRepository处理登录逻辑 - 视图模型层:
LoginViewModel负责登录状态管理,调用Repository获取数据,通知View层更新UI - 视图层:
LoginActivity/Fragment处理用户输入、展示登录状态,收到ViewModel的登录成功通知后调用导航类跳转
这样分层后,业务逻辑和UI解耦,后续修改用户类型逻辑时,只需要调整数据层或视图模型层,不用动UI代码。
总结
这套方案的核心是标准化用户类型 + 统一路由/策略分发 + 权限校验,既满足当前两类用户的需求,以后新增用户类型时,只需要:
- 在
UserType枚举里加新类型 - 新增对应的导航页面或功能策略类
- 调整策略工厂的判断逻辑
几乎不用修改现有代码,符合开闭原则,扩展性拉满~
内容的提问来源于stack exchange,提问作者user1526671
相关产品推荐
相关产品推荐

