简体   繁体   中英

How to change button color based on callback in flutter

I'm trying to change a button colour based on firebase text. When a user presses on the container then a callback will check a condition if the button match with the firebase instance then the button colour will be green if not then red.

Like this one

class TestBtnWidget extends StatefulWidget {
  const TestBtnWidget({
    Key? key,
    this.btnText,
    this.customAction,
    this.colorChange,
  }) : super(key: key);

  final String? btnText;
  final Future<dynamic> Function()? customAction;
  final Color? colorChange;

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

class _TestBtnWidgetState extends State<TestBtnWidget> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
  }

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: AlignmentDirectional(0, 0),
      child: InkWell(
        onTap: () async {
          await widget.customAction?.call();
        },
        child: Container(
          width: 180,
          height: 50,
          decoration: BoxDecoration(
            color: widget.colorChange,
            borderRadius: BorderRadius.circular(6),
          ),
          alignment: AlignmentDirectional(0, 0),
          child: Text(
            widget.btnText!,
            style: Theme.of(context).bodyText1,
          ),
        ),
      ),
    );
  }
}

check your response and if your status request was 200, means you got that clearly and after that change the color with setState((){})

First thing first, I would totally avoid magic instructions like these:

    WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));

Just get rid of this and if you got problems please let us know what's going on in another question.

Second, this problem may be suited for Riverpod . First, create a provider that listen holds whatever state you get from firestore:

final firstRequestProvider = StateProvider<bool>((ref) => false);
final myColorRequestProvider = FutureProvider<Color>((ref) {
  final isFirstRequest = ref.watch(firstRequestProvider);
  if (isFirstRequest) return Colors.white;

  final response = await ... // RESTful or by using the Firestore SDK
  
  return Color.from(response.body);
});

Then in your Widget you'll have something like:

class YourWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final color = ref.watch(myColorRequestProvider).maybeWhen(
       data: (color) => color,
       orElse: Colors.white
    );
    
    return ElevatedButton(
      onTap: () {
        ref.read(firstRequestProvider.notifier).state = false;
        ref.refresh(myColorRequestProvider);
      },
      // Style in which you'll need to add the color
      child:  // ... some text or whatever
    );
  }
}

This is just some random ideas with Riverpod, take this with a grain of salt. The takeaway here is: when you need to implement something, try to follow some known patterns that let you write reliable code. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM