1

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

这是自定义按钮的代码。

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,
                          width: double.infinity,
                          imagePath: 'assets/medic.png',
                          color: const Color(0xFF81C6D6),
                        ),
                      ),
                      const SizedBox(
                        width: 15,
                      ),
                      Expanded(
                        child: CustomRetractableButton(
                          height: 250,
                          width: double.infinity,
                          color: const Color(0xFFE05A45),
                          imagePath: 'assets/firefighter.png',
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
4

2 回答 2

0

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

于 2021-06-09T20:08:13.897 回答
0
你要:

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

你需要:
  • 保存初始设置CustomRetractableButton
  • 暴露更改并恢复状态

去做:

  • 使final的所有属性 ( height, width, imagePath) 。CustomRetractableButton
  • 在 下创建一个 activeHeight 属性_CustomRetractableButtonState
  • 删除您的全局变量prevHeight,它不适用于多个实例。
  • 创建一个类型的静态变量_CustomRetractableButtonState,它将保存最后一个 active 的状态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,
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

然后您可以通过使用提供程序或其他颤振状态管理方法来改进代码

于 2021-06-09T21:22:09.247 回答