Обновить виджет существующего класса StatefulWidget в flutter

#flutter #flutter-layout

#трепетать #flutter-layout #flutter

Вопрос:

Я хочу обновить свой MaterialButton, когда пользователь нажимал на onTapDown() и onTapUP (внутри GestureDetector). Но я не в состоянии этого сделать. Я пытался, но безуспешно. Я распечатал некоторую информацию в консоли, чтобы проверить, работает мой код или нет, но успешно все работает без обновления моего виджета MaterialButton. Пожалуйста, помогите мне, мой Некоторый код приведен ниже:-

(Это код для кнопки с изменяемым фоновым изображением).

 Container(
color: Colors.amber,
alignment: Alignment.center,
padding: EdgeInsets.only(top: 15, bottom: 10),
child: Text(
   "CALL FUNTIONS",
    style: TextStyle(
       fontSize: 25,
       fontWeight: FontWeight.bold,
  ),
)),
Container(
padding: EdgeInsets.only(bottom: 10),
color: Colors.amber,
child: callFunctionsForLessThan600Pixel(),
),


Widget callFunctionsForLessThan600Pixel() {
return new Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: <Widget>[
    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
       lessThan600Pixel(Key("LockCallButton"),"button_default","locked"),
   lessThan600Pixel(Key("UnLockCallButton"),"button_default","unlocked"),
       lessThan600Pixel(Key("StatusCallButton"),"button_default","info"),
      ],
    ),
  ],
);
}

Widget lessThan600Pixel(Key key, String buttonName, String svgName) {
return MaterialButton(
  key: key,
  child: ConstrainedBox(
    constraints: BoxConstraints(
      maxHeight: 70,
      maxWidth: 70,
    ),
    child: GestureDetector(
      child: Stack(
        children: <Widget>[
          Image.asset("assets/images/$buttonName.png",),
          SvgPicture.asset(
            "assets/images/$svgName.svg",
            height: 30,
            width: 30,
            color: Colors.white,
          ),
        ],
        alignment: Alignment.center,
      ),
      onTapDown: (v) {
        buttonTappedDown(key, svgName);
      },
      onTapUp: (v) {
        buttonTappedDown(key, svgName);
      },
    ),
  ),
  onPressed: buttonPressed,
  elevation: 0,
  highlightElevation: 0,
  highlightColor: Colors.amber,
);
}



void buttonTappedDown(Key key, String svgName) {
setState(() {
  lessThan600Pixel(key, "button_pressed", svgName);
});
}

void buttonTappedUp(Key key, String svgName) {
setState(() {
  lessThan600Pixel(key, "button_default", svgName);
});
}
  

Ответ №1:

Чтобы иметь интерактивный пользовательский интерфейс, вам нужно сделать свой класс виджета с сохранением состояния, а в функции onPressed вы просто используете метод setState() для выполнения любых изменений. Таким образом, виджет знает, что его нужно обновить.

Если ваш виджет не имеет состояния, он никогда не обновится.

Вот вводный урок Goolge, который хорошо обучает вас логике Statefull:https://flutter.dev/docs/development/ui/interactive

Комментарии:

1. Это означает, что я буду использовать свой MaterialButton в качестве виджета с полным состоянием?

2. Мой виджет находится в состоянии, но пока не работает. Есть другой способ или что-то не так с моим кодом?

3. можете ли вы обновить свой вопрос с помощью класса Statful widget?

4. обновил ответ с помощью руководства Google, чтобы сделать ваш пользовательский интерфейс интерактивным

5. Я обновил свой код в соответствии с руководством, используя некоторые условия, которые теперь работают должным образом, но возникла одна проблема: я нажал одну кнопку, а затем воспроизвел анимацию в каждой неожиданной кнопке. Можете ли вы привести мне краткий пример?

Ответ №2:

 My all code are below:-


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

class FirstPage extends StatefulWidget {
@override
_FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
var screenWidth;
var isMobile;
var scaffoldKey = GlobalKey<ScaffoldState>();
bool isTap = false;


@override
Widget build(BuildContext context) {
isMobile = MediaQuery
    .of(context)
    .size
    .width < 600;
screenWidth = MediaQuery
    .of(context)
    .size
    .width;

return Scaffold(
  key: scaffoldKey,
  backgroundColor: Colors.amber[300],
  appBar: AppBar(
    title: Text("Home Page"),
  ),
  body: SingleChildScrollView(
    child: Container(
      child: Column(
        children: <Widget>[
          Container(
              color: Colors.amber,
              alignment: Alignment.center,
              padding: EdgeInsets.only(top: 15, bottom: 10),
              child: Text(
                "CALL FUNTIONS",
                style: TextStyle(
                  fontSize: 25,
                  fontWeight: FontWeight.bold,
                ),
              )),
          Container(
            padding: EdgeInsets.only(bottom: 10),
            color: Colors.amber,
            child: callFunctionsForLessThan600Pixel(),
          ),
          Container(
              color: Colors.amber,
              alignment: Alignment.center,
              margin: EdgeInsets.only(top: 8),
              padding: EdgeInsets.only(top: 15, bottom: 10),
              child: Text(
                "SMS FUNTIONS",
                style: TextStyle(
                  fontSize: 25,
                  fontWeight: FontWeight.bold,
                ),
              )),
        ],
      ),
    ),
  ),
  );
  }


 Widget callFunctionsForLessThan600Pixel() {
 return new Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: <Widget>[
    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        lessThan600Pixel(Key("LockCallButton"), "button_default", "locked"),
        lessThan600Pixel(
            Key("UnLockCallButton"), "button_default", "unlocked"),
        lessThan600Pixel(Key("StatusCallButton"), "button_default", "info"),
      ],
    ),
  ],
 );
 }

 void buttonTappedDown(Key key, String svgName) {
 setState(() {
  lessThan600Pixel(key, "button_pressed", svgName);
 });
 }

void buttonTappedUp(Key key, String svgName) {
setState(() {
  lessThan600Pixel(key, "button_default", svgName);
});
}

 Widget lessThan600Pixel(Key key, String buttonName, String svgName) {
return MaterialButton(
  key: key,
  child: ConstrainedBox(
    constraints: BoxConstraints(
      maxHeight: 70,
      maxWidth: 70,
    ),
    child: GestureDetector(
      child: Stack(
        children: <Widget>[
          Image.asset("assets/images/$buttonName.png",),
          SvgPicture.asset(
            "assets/images/$svgName.svg",
            height: 30,
            width: 30,
            color: Colors.white,
          ),
        ],
        alignment: Alignment.center,
      ),
      onTapDown: (v) {
        buttonTappedDown(key, svgName);
      },
      onTapUp: (v) {
        buttonTappedDown(key, svgName);
      },
    ),
  ),
  elevation: 0,
  highlightElevation: 0,
  highlightColor: Colors.amber,
);
}
}