如何让按钮回到初始状态

问题描述

我创建了一个自定义按钮,它在第一次点击时展开,在第二次点击时,它会转到另一个屏幕。现在,问题是,我创建了该按钮的三个实例。因此,我首先点击的按钮保持展开状态,不会变为其初始大小。我想让按钮在用户点击任何其他小部件时返回​​其初始状态。对不起我的代码。我还在练习。希望有人帮忙。

这是自定义按钮的代码

import 'package:Flutter/material.dart';

double prevHeight = 0;

class CustomretractableButton extends StatefulWidget {
  double height;
  double width;
  String imagePath;
  Color color;

  CustomretractableButton({
    required this.height,required this.width,required this.color,required this.imagePath,}) {
    prevHeight = height;
  }

  @override
  _CustomretractableButtonState createState() =>
      _CustomretractableButtonState();
}

class _CustomretractableButtonState extends State<CustomretractableButton>
    with TickerProviderStateMixin {
  String btnText = '';
  Alignment imageAlignment = Alignment.center;
  bool isSelected = false;

  @override
  Widget build(BuildContext context) {
    double size = MediaQuery.of(context).size.height;
    return AnimatedContainer(
      duration: Duration(milliseconds: 150),decoration: Boxdecoration(
        color: widget.color,borderRadius: BorderRadius.circular(20.0),image: decorationImage(
          image: Assetimage(widget.imagePath),alignment: imageAlignment,fit: BoxFit.fitWidth,),height: widget.height,child: TextButton(
        onpressed: () {
          if (!isSelected) {
            isSelected = !isSelected;
            setState(() {
              widget.height = size;
              btnText = 'Send Alert';
              imageAlignment = Alignment.topCenter;
            });
          } else {
            //navigates to another screen
          }
        },child: Align(
          alignment: Alignment.bottomCenter,child: RotatedBox(
            quarterTurns: -1,child: AnimatedSize(
              curve: Curves.easeInOut,duration: const Duration(milliseconds: 150),child: Padding(
                padding: const EdgeInsets.only(left: 100),child: Text(
                  btnText,style: const TextStyle(
                    color: Colors.white,fontSize: 25,fontWeight: FontWeight.w600,);
  }
}

这里是main.dart的代码

import 'package:custom_animated_button/custom_retractable_button.dart';
import 'package:Flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  double height = 250;
  String btnText = '';
  bool isSelected = true;
  Alignment imageAlignment = Alignment.center;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',theme: ThemeData(
        primarySwatch: Colors.blue,home: Scaffold(
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(20.0),child: Column(
              mainAxisAlignment: MainAxisAlignment.end,children: [
                Expanded(
                  flex: 1,child: Column(
                    children: [
                      Container(
                        width: double.infinity,child: const Text(
                          "Request Assistance",style: TextStyle(
                            fontWeight: FontWeight.w700,fontSize: 20,Container(
                        width: double.infinity,child: const Text(
                          "Please choose the type of responder",style: TextStyle(
                            fontWeight: FontWeight.w400,fontSize: 14,],Expanded(
                  flex: 10,child: Row(
                    crossAxisAlignment: CrossAxisAlignment.end,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
                      Expanded(
                        child: CustomretractableButton(
                          height: 250,width: double.infinity,imagePath: 'assets/police3.png',color: const Color(0xFF4F70A1),const SizedBox(
                        width: 15,Expanded(
                        child: CustomretractableButton(
                          height: 250,imagePath: 'assets/medic.png',color: const Color(0xFF81C6D6),color: const Color(0xFFE05A45),imagePath: 'assets/firefighter.png',);
  }
}

解决方法

用 GestureDetector 包裹整个 Scaffold 并在 on tap 方法上进行操作。 并将 behavior: HitTestBehavior.opaque, 添加到手势检测器。

,
你想要:

允许 CustomRetractableButton 在项目被按下时返回初始状态。

您需要:
  • 保存 CustomRetractableButton 的初始设置。
  • 公开更改并恢复状态

待办事项:

  • 使 height 的所有属性(widthimagePathCustomRetractableButton)成为最终属性。
  • _CustomRetractableButtonState 下创建一个 activeHeight 属性。
  • 删除您的全局变量 prevHeight,它不适用于多个实例。
  • 创建一个 _CustomRetractableButtonState 类型的静态变量,用于保存最后一个活动 CustomRetractableButton 的状态。

自定义按钮的完整代码


import 'package:flutter/material.dart';


class CustomRetractableButton extends StatefulWidget {
  final double initialHeight;
  final double width;
  final String imagePath;
  final Color color;

  CustomRetractableButton({
    required double height,required this.width,required this.color,required this.imagePath,}):initialHeight = height;

  @override
  _CustomRetractableButtonState createState() =>
      _CustomRetractableButtonState();
}

class _CustomRetractableButtonState extends State<CustomRetractableButton>
    with TickerProviderStateMixin {
  static _CustomRetractableButtonState? oldActive; 
  String btnText = '';
  Alignment imageAlignment = Alignment.center;
  bool isSelected = false;
  double activeHeight = 0;
  
  @override
  initState(){
  activeHeight = widget.initialHeight;
    super.initState();
  }
  revert(){
    if(mounted){
      setState((){
        activeHeight = widget.initialHeight;
        isSelected = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    double size = MediaQuery.of(context).size.height;
    return AnimatedContainer(
      duration: Duration(milliseconds: 150),decoration: BoxDecoration(
        color: widget.color,borderRadius: BorderRadius.circular(20.0),image: DecorationImage(
          image: AssetImage(widget.imagePath),alignment: imageAlignment,fit: BoxFit.fitWidth,),height: activeHeight,child: TextButton(
        onPressed: () {
          if (!isSelected) {
            if(oldActive != null){
              oldActive!.revert();
            }
            isSelected = true;
            oldActive = this;
            setState(() {
              activeHeight = size;
              btnText = 'Send Alert';
              imageAlignment = Alignment.topCenter;
            });
          } else {
            
            if(oldActive != null){
              oldActive!.revert();
              oldActive = null;
            }
            //navigates to another screen
          }
        },child: Align(
          alignment: Alignment.bottomCenter,child: RotatedBox(
            quarterTurns: -1,child: AnimatedSize(
              vsync: this,curve: Curves.easeInOut,duration: const Duration(milliseconds: 150),child: Padding(
                padding: const EdgeInsets.only(left: 100),child: Text(
                  btnText,style: const TextStyle(
                    color: Colors.white,fontSize: 25,fontWeight: FontWeight.w600,);
  }
}

然后您可以使用 providers 或其他 flutter state management approach

改进代码