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

Flutter滑动面板依赖报错及面板关闭后底部导航切换问题

Flutter 两个问题的解决方案

问题1:点击Payments按钮抛出Expanded兼容异常

错误原因

错误日志显示Spacer(本质是Expanded的封装)被放置在ListView的子节点中,而Expanded/Spacer仅能作为Flex容器(如Row、Column)的直接子组件,ListView不属于Flex容器,因此出现父数据类型不兼容的错误。

修复方案

修改TabWidget代码,移除Spacer(ListView是滚动布局,Spacer无法起到填充剩余空间的作用),可替换为固定高度的SizedBox(根据需求调整):

import 'package:flutter/material.dart';
import 'package:sadapay_clone/widgets/personal_item.dart';

class TabWidget extends StatelessWidget {
  final ScrollController scrollController;
  const TabWidget({super.key, required this.scrollController});

  @override
  Widget build(BuildContext context) => ListView(
        padding: const EdgeInsets.all(16),
        controller: scrollController,
        children: const [
          Padding(
            padding: EdgeInsets.only(bottom: 20.0),
            child: Icon(
              Icons.horizontal_rule,
            ),
          ),
          // 替换Spacer为固定高度的SizedBox(可选,按需调整)
          SizedBox(height: 20),
          Padding(
            padding: EdgeInsets.only(
              top: 15,
              left: 10,
              bottom: 15,
            ),
            child: Text(
              'Payments',
              textAlign: TextAlign.left,
              style: TextStyle(
                fontSize: 35,
                fontWeight: FontWeight.w500,
                color: Colors.black,
              ),
            ),
          ),
          PersonalItem(
            icon: Icon(
              Icons.phone_android_rounded,
              size: 30,
              color: Color.fromARGB(255, 255, 129, 129),
            ),
            title: 'Mobile top up',
            subtext: 'Instantly top up your mobile.',
          ),
          Divider(thickness: 1.5),
          PersonalItem(
            icon: Icon(
              Icons.receipt_rounded,
              size: 30,
              color: Color.fromARGB(255, 255, 129, 129),
            ),
            title: 'Bills and utilities',
            subtext: 'Pay for your utilities.',
          ),
          Divider(
            thickness: 1.5,
          ),
          PersonalItem(
            icon: Icon(
              Icons.card_membership_rounded,
              size: 30,
              color: Color.fromARGB(255, 255, 129, 129),
            ),
            title: 'Money requests',
            subtext: 'Review pending money req.',
          ),
        ],
      );
}

问题2:关闭滑动面板后自动切换回Personal标签页

实现思路

给Payments组件添加回调函数,监听滑动面板的关闭状态,触发时通知父页面MyHomePage切换导航索引到0(Personal标签页)。

步骤1:修改Payments组件,添加状态监听与回调

import 'package:flutter/material.dart';
import 'package:sliding_up_panel/sliding_up_panel.dart';

import '../widgets/homepage_item.dart';
import '../widgets/tabwidget.dart';

class Payments extends StatefulWidget {
  // 定义面板关闭时的回调
  final VoidCallback? onPanelClosed;
  const Payments({super.key, this.onPanelClosed});

  @override
  State<Payments> createState() => _PaymentsState();
}

class _PaymentsState extends State<Payments> {
  late PanelController _panelController;

  @override
  void initState() {
    super.initState();
    _panelController = PanelController();
    // 监听面板状态变化
    _panelController.addListener(_handlePanelChange);
  }

  void _handlePanelChange() {
    if (_panelController.isClosed) {
      // 面板关闭时触发回调
      widget.onPanelClosed?.call();
    }
  }

  @override
  void dispose() {
    _panelController.removeListener(_handlePanelChange);
    _panelController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SlidingUpPanel(
      controller: _panelController, // 绑定面板控制器
      backdropEnabled: true,
      panelBuilder: (scrollController) =>
          buildSlidingPanel(scrollController: scrollController),
      body: const HomePageItem(),
      borderRadius: const BorderRadius.only(
          topLeft: Radius.circular(20), topRight: Radius.circular(20)),
      backdropTapClosesPanel: true,
      defaultPanelState: PanelState.OPEN,
      panelSnapping: false,
      maxHeight: 400,
      minHeight: 40,
    );
  }

  Widget buildSlidingPanel({
    required ScrollController scrollController,
  }) =>
      TabWidget(
        scrollController: scrollController,
      );
}

步骤2:修改MyHomePage,接收回调并切换索引

import 'package:flutter/material.dart';
import 'package:sadapay_clone/screens/more_screen.dart';
import 'package:sadapay_clone/screens/payments.dart';

import '../widgets/homepage_item.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currIndex = 0;

  // 动态生成当前页面,传递回调
  Widget getCurrentTab() {
    switch (_currIndex) {
      case 0:
        return const HomePageItem();
      case 1:
        return Payments(
          onPanelClosed: () {
            setState(() {
              _currIndex = 0; // 切换回Personal标签页
            });
          },
        );
      case 2:
        return const MoreScreen();
      default:
        return const HomePageItem();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 238, 237, 237),
      body: getCurrentTab(), // 使用动态生成的页面
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currIndex,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home_rounded),
            label: 'Personal',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.view_kanban),
            label: 'Payments',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.menu),
            label: 'More',
          ),
        ],
        fixedColor: const Color.fromARGB(255, 255, 129, 129),
        onTap: (index) {
          setState(() {
            _currIndex = index;
          });
        },
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:06:39