You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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代码。

总结

这套方案的核心是标准化用户类型 + 统一路由/策略分发 + 权限校验,既满足当前两类用户的需求,以后新增用户类型时,只需要:

  1. 在UserType枚举里加新类型
  2. 新增对应的导航页面或功能策略类
  3. 调整策略工厂的判断逻辑

几乎不用修改现有代码,符合开闭原则,扩展性拉满~

内容的提问来源于stack exchange,提问作者user1526671

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:22:19