如何在Flutter中使用Stack实现响应式几何图形联系卡片
解决Flutter响应式联系卡片圆形错位问题
你设计的响应式联系卡片在屏幕尺寸变化时,右侧的圆形元素会出现错位。问题根源在于Positioned组件使用了固定的left: 380值——当父容器(卡片)的宽度在300-400px区间动态调整时,固定的left值无法适配不同宽度,导致圆形位置脱离预期布局。
修复方案
放弃固定的left定位,改用相对于父容器右侧的定位方式,同时优化垂直方向的定位逻辑,确保圆形始终保持原有的视觉布局:
- 用
right: -79替代left: 380:圆形宽度为158px,设置right为负的一半宽度,能让圆形始终保持一半在卡片外侧、一半在内侧的效果,不受卡片宽度变化影响 - 调整
top: 21:卡片高度200px,圆形高度158px,通过(200-158)/2计算出垂直居中的top值,让圆形在垂直方向保持居中
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:qima_dev/constants/constants.dart'; import 'package:qima_dev/pages/functions.dart'; class ContactCard extends StatelessWidget { final String phoneNumber; final String emailAddress; final String officeAddress; const ContactCard({ required this.phoneNumber, required this.emailAddress, required this.officeAddress, Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return Container( constraints: const BoxConstraints( minWidth: 300, maxWidth: 400, ), height: 200, decoration: BoxDecoration( color: darkShadeOpaque, borderRadius: BorderRadius.circular(10), ), child: Stack(children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ ListTile( leading: const Icon( Icons.phone_in_talk, color: Colors.white, ), title: Text( phoneNumber, style: const TextStyle( fontWeight: FontWeight.w200, color: Colors.white, decoration: TextDecoration.underline, ), ), onTap: () { // 点击电话号码的操作 }, ), ListTile( leading: const Icon( Icons.email, color: Colors.white, ), title: Text( emailAddress, style: const TextStyle( fontWeight: FontWeight.w200, color: Colors.white, decoration: TextDecoration.underline, ), ), onTap: () { // 点击邮箱地址的操作 }, ), ListTile( leading: const Icon( Icons.location_on, color: Colors.white, ), title: Text( officeAddress, style: const TextStyle( fontWeight: FontWeight.w200, color: Colors.white, decoration: TextDecoration.underline, ), ), onTap: () { // 点击办公地址的操作 }, ), ], ), ), ), Positioned( top: 21, // 垂直居中计算值:(200-158)/2 = 21 right: -79, // 圆形一半宽度的负值,保持一半在卡片外 child: Container( width: 158, height: 158, decoration: const BoxDecoration( color: lightShade, borderRadius: BorderRadius.all( Radius.circular(200), ), ), ), ), ]), ); } }
内容的提问来源于stack exchange,提问作者John Adex
相关产品推荐
相关产品推荐

