Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make Elevated&Outlined&TextButton support onHover&onFocus callback #90688

Merged
merged 5 commits into from Sep 28, 2021
Merged

make Elevated&Outlined&TextButton support onHover&onFocus callback #90688

merged 5 commits into from Sep 28, 2021

Conversation

@yk3372
Copy link
Contributor

@yk3372 yk3372 commented Sep 24, 2021

Signed-off-by: yukai yk3372@gmail.com

My Feature issue is #90686

What's the PR do?
My PR aim to make the ElevatedButton/OutlinedButton/TextButton to support onFocus and onHover callback.

Why need it?
Recently, I make an application for macOS and Web. I'm writing a NavMenu view like this: Element-Menu.
The Menu need onPress/onFocus/onHover functions.
I have known the TextButton is Powerful,and it's support the normal/pressed/hover/focus/disable states in MaterialState.

But when I try to use the onHover function, it's has no related param.
Then I read the flutter framework source, and found it use the InkWell widget. It support the onHover and onFocus callback.
And the MaterialStateMixin's updateMaterialState function also support the onChanged param.The TextButton to support onFocus and onHover callback is very easy.

What‘s the meaning of it?
The flutter is support all the platforms, such as macOS/Windows/TV. These platforms has keyboard and mouse, all need focus/hover state and callback.

Compare before and after:
Before:
image
After
image

The Demo Code:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> buttonText = ['Button', 'Button', 'Button', 'Button', 'Button', 'Button'];

  static ButtonStyle getButtonStyle(
      {Color? hoverColor, Color? pressedColor, Color? focusColor, Color? disableColor, Color? normalColor}) {
    return ButtonStyle(
      backgroundColor: MaterialStateProperty.resolveWith((states) {
        if (pressedColor != null && states.contains(MaterialState.pressed)) {
          return pressedColor;
        }
        if (hoverColor != null && states.contains(MaterialState.hovered)) {
          return hoverColor;
        }
        if (focusColor != null && states.contains(MaterialState.focused)) {
          return focusColor;
        }
        if (disableColor != null && states.contains(MaterialState.disabled)) {
          return disableColor;
        }
        //默认不使用背景颜色
        return normalColor;
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            for (int i = 0; i < buttonText.length; i++)
              Padding(
                padding: const EdgeInsets.only(bottom: 5, top: 5),
                child: TextButton(
                  onHover: (bool isHover) {
                    if (isHover) {
                      buttonText[i] = 'hover';
                      setState(() {});
                    } else {
                      buttonText[i] = 'Button';
                    }
                  },
                  onFocusChange: (bool isFocus) {
                    if (isFocus) {
                      buttonText[i] = 'focus';
                      setState(() {});
                    } else {
                      buttonText[i] = 'Button';
                    }
                  },
                  onPressed: () {},
                  style: getButtonStyle(
                      normalColor: Colors.blue,
                      pressedColor: Colors.red,
                      hoverColor: Colors.green,
                      focusColor: Colors.orange),
                  child: SizedBox(
                    width: 200,
                    height: 60,
                    child: Center(
                      child: Text(
                        '${buttonText[i]}:$i',
                        style: const TextStyle(color: Colors.black, fontSize: 14),
                      ),
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt.
  • All existing and new tests are passing.
Signed-off-by: yukai <yk3372@gmail.com>
@flutter-dashboard
Copy link

@flutter-dashboard flutter-dashboard bot commented Sep 24, 2021

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@google-cla
Copy link

@google-cla google-cla bot commented Sep 24, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no label Sep 24, 2021
@yk3372
Copy link
Contributor Author

@yk3372 yk3372 commented Sep 24, 2021

@googlebot I signed it!

@google-cla google-cla bot added cla: yes and removed cla: no labels Sep 24, 2021
@yk3372 yk3372 changed the title Feature: make Elevated&Outlined&TextButton support hover&focus callback make Elevated&Outlined&TextButton support onHover&onFocus callback Sep 25, 2021
@yk3372
Copy link
Contributor Author

@yk3372 yk3372 commented Sep 25, 2021

@HansMuller @a14n could you review my PR, thanks.

@HansMuller HansMuller self-requested a review Sep 25, 2021
yk3372 added 2 commits Sep 26, 2021
Signed-off-by: yukai <yk3372@gmail.com>
Signed-off-by: yukai <yk3372@gmail.com>
Copy link
Contributor

@HansMuller HansMuller left a comment

This looks good however I don't see any tests that verify that the onChange or onHover callbacks are called when expected. You could probably generalize the existing tests a little (including their titles) to cover that.

@yk3372
Copy link
Contributor Author

@yk3372 yk3372 commented Sep 28, 2021

This looks good however I don't see any tests that verify that the onChange or onHover callbacks are called when expected. You could probably generalize the existing tests a little (including their titles) to cover that.

I have added the tests for onHover and onFocus. Refer to the test in ink_well_test.dart. Thanks

Copy link
Contributor

@HansMuller HansMuller left a comment

LGTM

@HansMuller HansMuller merged commit d2c8b62 into flutter:master Sep 28, 2021
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants