import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:new_learn/core/providers/user_provider.dart'; /// ============================================================ /// Align 对齐布局演示页 + Riverpod 全局用户信息展示 /// /// 一、Align 两种使用方式: /// 1. 直接运行本页面:把 main() 改为 /// runApp(const ProviderScope(child: MaterialApp(home: AlignDemoPage()))); /// 2. 复制 body 核心代码到任意 Scaffold 的 body 中: /// /// body: Container( /// width: 300, /// height: 300, /// color: Colors.grey[200], /// child: Align( /// alignment: Alignment.bottomLeft, // 子组件放到父盒子左下角 /// child: Container(...), // 用户信息卡片 /// ), /// ), /// /// 二、Flutter 核心布局规则(务必理解): /// 1. 父组件给子组件传递【约束】(Constraints),子组件在约束范围内决定自身【大小】; /// 2. Align 会把自身区域扩大到父组件允许的最大范围(宽高撑满), /// 然后通过 alignment 把子组件放到指定位置; /// 3. 子组件的 size(宽高)如果不写,Align 会取子组件的固有尺寸; /// 一旦写了固定 width/height,就由子组件自己决定,Align 不再干预。 /// /// 三、Riverpod 全局状态用法(本次新增重点): /// - AlignDemoPage 改成 ConsumerWidget(build 多一个 WidgetRef ref 参数); /// - `ref.watch(currentUserProvider)` 订阅全局用户,登录后任何页面都拿到; /// - `.value` 是 CurrentUserExtension?:登录了有值,未登录是 null; /// - 登录页登录成功时会 set 这个 provider,本卡片自动刷新(无需手动 setState)。 /// /// 四、高频坑: /// 1. 用了 ref 的组件必须继承 ConsumerWidget / ConsumerStatefulWidget, /// 普通 StatelessWidget 拿不到 ref(编译报错); /// 2. ref.watch 要在 build 里调用(声明式依赖),ref.read 才能放回调里; /// 3. 加了 .w/.h/.sp 的 widget 不能再用 const(尺寸是运行期算的)。 /// ============================================================ class AlignDemoPage extends ConsumerWidget { const AlignDemoPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // Riverpod 全局用户:登录后全 App 共享,未登录为 null final user = ref.watch(currentUserProvider).value; return Scaffold( appBar: AppBar(title: const Text('Align 对齐布局 Demo11')), // ---------- 下方即为核心代码,可直接复制到 Scaffold body ---------- body: Container( width: 300.w, height: 300.h, color: Colors.grey[300], child: Align( alignment: Alignment.bottomLeft, // 子组件放到父盒子左下角 child: Container( width: 240.w, padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.h), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(8.w), ), child: Column( mainAxisSize: MainAxisSize.min, // 卡片高度跟随内容 crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '用户:${user?.userName ?? '未登录'}', style: TextStyle( color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.bold, ), ), SizedBox(height: 6.h), Text( '班级:${user?.className ?? '-'}', style: TextStyle(color: Colors.white, fontSize: 14.sp), ), SizedBox(height: 4.h), Text( '积分:${user?.userPoints ?? 0}', style: TextStyle(color: Colors.white, fontSize: 14.sp), ), ], ), ), ), ), ); } }