Upgrade to Pro — share decks privately, control downloads, hide ads and more …

アクセシビリティが高いFlutterアプリケーションを開発する

100059
November 30, 2021

 アクセシビリティが高いFlutterアプリケーションを開発する

FlutterKaigi2021
2021/11/30 19:45〜 Live レギュラートーク(30分)
https://fortee.jp/flutterkaigi-2021/proposal/d80e1204-3fd5-4c55-b728-83ee1dbf1d01

100059

November 30, 2021
Tweet

More Decks by 100059

Other Decks in Technology

Transcript

  1. ΞΫηγϏϦςΟʔ͕ߴ͍
    FlutterΞϓϦέʔγϣϯΛ


    ։ൃ͢Δ
    Flutter Kaigi 2021 Day2
    1

    View Slide

  2. ࣗݾ঺հ
    • ઋੴ ߊٱ (Sengoku Akihisa)


    • גࣜձࣾαΠόʔΤʔδΣϯτ


    • 2018 - 2021 Ξϝʔόϒϩά iOSΤϯδχΞ


    • 2021- ݱࡏ WINTICKET FlutterΤϯδχΞ
    2

    View Slide

  3. WINTICKETͰͷΞΫηγϏϦςΟͷऔΓ૊Έ
    • WINTICKET͸ʮαʔϏεΛ௨ͯ͠୭Ͱ΋ެӦڝٕΛָ͠ΊΔΑ͏ɺ
    ΞΫηγϏϦςΟͷ޲্ʹ౒Ί͍ͯ·͢ɻʯ


    • WebͰ͸WCAGͷγϯάϧA΁ͷ४ڌΛ໨ඪͱ͍ͯ͠Δɻ


    • ݱࡏɺΞϓϦ͸Flutter੡ͷΞϓϦʹϦϓϨʔεΛߦͳ͓ͬͯΓɺͦΕ
    ʹ൐͍ΞϓϦͷΞΫηγϏϦςΟͷ޲্Λߦͳ͍ͬͯΔ


    • https://www.cyberagent.co.jp/way/csr/accessibility/
    3

    View Slide

  4. ΞδΣϯμ
    • Flutter ΞΫηγϏϦςΟ


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


    • ΞΫηγϏϦςΟରԠ
    4

    View Slide

  5. ࿩͞ͳ͍͜ͱ
    • Flutter for WebͷΞΫηγϏϦςΟ
    5

    View Slide

  6. Flutter ΞΫηγϏϦςΟ ࢀߟ
    • Flutter


    • Flutter.dev Accessibility


    • iOS


    • Human Interface Guideline Accessibility


    • Android


    • Material Design Accessibility
    6

    View Slide

  7. Flutter ΞΫηγϏϦςΟ
    • Large Fonts


    • ϑΥϯταΠζ͕େ͖͘ͳͬͯ΋σβΠϯ่͕Εͳ͍Α͏ʹ͢Δ


    • σόΠεͰઃఆ͞Ε͍ͯΔϑΥϯτͷεέʔϧ஋Λ࢖༻ͯ͠ɺΞϓϦ಺ͷϑΥϯ
    ταΠζ͕ܾఆ͢Δ


    • Suf
    fi
    cient Contrast


    • ΞϓϦ಺ͷίϯςϯπ͕े෼ͳίϯτϥετൺ͕อͨΕ͍ͯΔ


    • Screen Reader


    • εΫϦʔϯϦʔμʔΛ࢖༻ͯ͠ɺΞϓϦͷίϯςϯπΛಡΈ্͛Δ͜ͱ͕Ͱ͖Δ
    7

    View Slide

  8. Flutter Checklist
    • Active interactions:Ϣʔβͷಈ࡞ʹରͯ͠ͷϑΣʔυόοΫ΍ΞϓϦͷ࣮ߦ݁ՌͷϑΟʔυόοΫ͕͋Δ͔ʁ


    • Screen reader testing: εΫϦʔϯϦʔμʔΛ࢖༻ͯ͠ΞϓϦΛ࢖༻͢Δ͜ͱ͕Ͱ͖Δ͔ʁ


    • Contrast ratios: ίϯτϥετൺ͕े෼ʹอͨΕ͍ͯΔ͔ʁ


    • Context switching: Ϣʔβͷ֬ೝͳ͠ͰϢʔβͷίϯςϯπͷมߋ͍ͯ͠ͳ͍͔ʁ


    • Tappable targets: 48px *48px ͷλοϓྖҬ͕֬อ͞Ε͍ͯΔ͔ʁ


    • Errors: ΤϥʔͱҰॹʹमਖ਼ํ๏͕Θ͔Δ͔ʁ


    • Color vision de
    fi
    ciency testing: ৭֮ҟৗϞʔυͱάϨʔεέʔϧϞʔυͰ࢖༻ՄೳͰ͋Δ͔ʁ


    • Scale factors: ϑΥϯταΠζΛେ͖ͯ͘͠΋σβΠϯ่͕Εͳ͍͔ʁ
    8

    View Slide

  9. iOSͱAndroidͷΞΫηγϏϦςΟ
    iOS


    44px * 44px


    3:1


    Voice Over


    ̋


    ×
    Android


    48px * 48px


    3:1 or 4.5:1(14ptະຬ)


    Talk Back


    ̋


    ̋
    λοϓྖҬ


    Boldίϯτϥετൺ


    Screen Reader


    ϑΥϯταΠζͷมߋ


    දࣔαΠζͷมߋ
    9

    View Slide

  10. Flutter Framework Material
    • λοϓྖҬͷ࠷খ஋Ͱ͋Δ48px͕ఆٛ͞Ε͍ͯΔ



    fl
    utter / lib / src / material / constant.dart


    • const double kMinInteractiveDimension = 48.0;


    • MaterialͷIconButtonͰ࢖༻͞Ε͓ͯΓɺσϑΥϧτͰ48pxͷλοϓྖҬ͕
    ֬อ͞ΕΔ



    fl
    utter / lib / src / material / icon_button.dart


    • BoxConstraints(minWidth: _kMinButtonSize, minHeight: _kMinButtonSize)
    10

    View Slide

  11. Flutter Framework Cupertino
    • λοϓྖҬͷ࠷খ஋Ͱ͋Δ44px͕ఆٛ͞Ε͍ͯΔ



    fl
    utter / lib / src / cupertino / constraints.dart


    • const double kMinInteractiveDimensionCupertino = 44.0;


    • CupertinoButtonͰ࢖༻͞Ε͓ͯΓɺσϑΥϧτͰ44pxͷλοϓྖҬ
    ͕֬อ͞ΕΔ



    fl
    utter / lib / src / cupertino / button.dart
    11

    View Slide

  12. σβΠϯσʔλͷαϯϓϧ
    • λοϓྖҬɿ40px * 40px


    • IconSizeɿ32px


    • Paddingɿ4px
    4px
    • IconButton


    • padding: 4


    • Icon: Icon()
    12

    View Slide

  13. ࣮૷ ྫ
    4px
    13

    View Slide

  14. ࣮૷ ྫ
    IconButtonͷConstraint͸σϑΥϧτͰ48pxͷͨΊɺsizeͱ
    paddingͷࢦఆͷΈͰ͸࣮૷Ͱ͖ͣɺConstraintͷࢦఆ͕ඞཁ😢
    14

    View Slide

  15. ΞΫηγϏϦςΟΛཧղ͓ͯ͘͜͠ͱ
    Ͱ


    ΞΫηγϒϧͳΞϓϦ։ൃΛ!
    15

    View Slide

  16. ΞδΣϯμ
    • Flutter ΞΫηγϏϦςΟ


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


    • ΞΫηγϏϦςΟରԠ
    16

    View Slide

  17. System Font Scale
    17

    View Slide

  18. System Font Scale
    18

    View Slide

  19. System Font Scale
    19

    View Slide

  20. System Font Scale
    • MediaQueryData


    • ϝσΟΞʢγεςϜʣ৘ใʹ͍ͭͯ


    • MediaQueryData.textScaleFactor: ϑΥϯτͷεέʔϧൺ


    • MediaQueryData.size: ΞϓϦ͕දࣔ͞Ε͍ͯΔWindow Size


    • MediaQueryData.boldText: ϑΥϯτΛଠ͘͢Δࢦఆ


    • MediaQueryData.highContrast: ίϯτϥετΛ্͛Δࢦఆ
    20

    View Slide

  21. App Bar Title͕`1.3ͱ2.0ͰมԽ͍ͯ͠ͳ͍ʁ
    21

    View Slide

  22. App Bar
    • ࠷େαΠζʢkMaxTitleTextScaleFactor: 1.34ʣΛࢦఆͯ͠σβΠϯΛ
    ҡ͍࣋ͯ͠Δ
    22

    View Slide

  23. App Bar σβΠϯ่͕Εͳ͍Α͏ʹ
    23

    View Slide

  24. TextButton
    • test/material/text_butt


    • ϑΥϯτͷεέʔϧʹ
    ΑͬͯTextButtonͷScale
    ͕มΘΔͷ͔ͷςετ
    έʔε͕ଘࡏ
    24

    View Slide

  25. Example
    • RowͱColumnͰ࡞ΒΕ
    ͨΑ͋͘Γͦ͏ͳWidget


    • ͺͬͱΈ໰୊ͳ͠🙆
    25

    View Slide

  26. Widget Test Passed
    26

    View Slide

  27. Widget Test Failed
    27

    View Slide

  28. Error Message
    28

    View Slide

  29. Error Message
    29

    View Slide

  30. Error Message
    • SizedBoxͰߴ͕͞ࢦఆ͞
    Ε͓ͯΓɺColumnׂ͕
    Γ౰ͯΒΕͨεϖʔεΑ
    Γ΋޿͘ͳΔͨΊ
    30

    View Slide

  31. Fix
    SizedBoxΛ࡟আ
    31

    View Slide

  32. Widget Test Failed
    32

    View Slide

  33. Widget Test Failed
    33

    View Slide

  34. Error Message
    34

    View Slide

  35. Fixed
    35

    View Slide

  36. Widget Test Failed
    36

    View Slide

  37. ࣮૷࣌ͷ஫ҙ఺
    • ࣮ࡍʹtextScaleFactorΛมԽͤͯ֬͞ೝͯ͠ΈΔͷ͕Ұ൪ྑ͍😅


    • TextͷදࣔྖҬͷߴ͞ or ԣ෯Λݻఆ͍ͯ͠Δ ← ΄΅͜Ε


    • → PaddingΛ࢖͏ͳͲͯ͠ಈతͳϨΠΞ΢τʹमਖ਼


    • → MediaQueryͰWidgetΛWrapͯ͠maxͷtextScaleFactorΛࢦఆ


    • จݴ͕௕͍έʔε΍2ߦͷέʔε


    • ยଆͷPadding͕ਖ਼֬ʹઃఆ͞Ε͍ͯͳ͍
    37

    View Slide

  38. ิ଍ Display SizeͷରԠ
    • AndroidͰ͸දࣔαΠζΛมߋ͢Δ͜ͱ͕Ͱ
    ͖Δ


    • දࣔαΠζΛมߋ͢Δ͜ͱͰΞϓϦͷදࣔ
    ͞ΕΔWindowSize͕มΘΔ


    • Display Sizeখ͘͞ → WindowSize େ͖͘


    • Display Sizeେ͖͘ → WindowSize খ͘͞
    38

    View Slide

  39. ϨεϙϯγϒͳUI
    • DisplaySizeΛେ͖͘ʢදࣔྖҬ͕খ͘͞ͳΔʣͱ͖ʹσβΠϯΛҡ࣋


    • LayoutBuilder


    • ImageͷAspectൺͷҡ࣋


    • AspectRatio


    • Document


    • https://docs.
    fl
    utter.dev/development/ui/layout/adaptive-
    responsive#creating-a-responsive-
    fl
    utter-app
    39

    View Slide

  40. ΞδΣϯμ
    • Flutter ΞΫηγϏϦςΟ


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader
    40

    View Slide

  41. Su
    ffi
    cient Contrast
    • 4.5 : 1


    • 18ptະຬ Regular Text,14ptະຬ Bold Text


    • 3: 1


    • 18ptҎ্ Regular Text,14ptҎ্ ,Bold Text , จࣈը૾


    • W3Cͷਪ঑


    • https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-
    contrast.html
    41

    View Slide

  42. Contrast Check
    • Android Ϣʔβʔิॿݕূπʔϧ


    • https://play.google.com/store/
    apps/details?
    id=com.google.android.apps.ac
    cessibility.auditor


    • λοϓྖҬͱίϯτϥετൺͷ֬ೝ
    ͕Մೳ
    42

    View Slide

  43. meetsGuideline
    • widget͕ΞΫηγϏϦςΟΛຬ͍ͨͯ͠Δ͔Λ֬ೝ͢Δ͜ͱ͕Ͱ͖ΔMatcher


    • AsyncMatcher meetsGuideline(AccessibilityGuideline guideline)


    • AccessibilityGuideline


    • textContrastGuideline: ςΩετͷίϯτϥετ


    • androidTapTargetGuideline: AndroidͷλοϓྖҬ 48 * 48


    • iOSTapTargetGuideline: iOSͷλοϓྖҬ 44 * 44


    • labeledTapTargetGuideline: λοϓΤϦΞʹηϚϯςΟοΫϥϕϧͷ༗ແ
    43

    View Slide

  44. textContrastGuideline
    44

    View Slide

  45. textContrastGuideline
    45

    View Slide

  46. meetsGuideline
    • FlutterGalleryͷDemoͷΞΫηγϏ
    ϦςΟͷςετʹ࢖ΘΕ͍ͯΔ


    • https://github.com/
    fl
    utter/
    fl
    utter/
    blob/
    24207183899d546983873dd6d6e
    3b80a2825a982/dev/
    integration_tests/
    fl
    utter_gallery/
    test/accessibility_test.dart
    46

    View Slide

  47. ΞδΣϯμ
    • Flutter ΞΫηγϏϦςΟ


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


    • ΞΫηγϏϦςΟରԠ
    47

    View Slide

  48. Screen Reader
    48

    View Slide

  49. Semantics Widget
    • WidgetʹηϚϯςΟοΫʢҙຯʣ৘ใΛ෇༩͢Δ


    • VoiceOver΍TalkbackͳͲͷࢧԉπʔϧͰ༻͍ΒΕΔ


    • labelҎ֎ʹ΋༷ʑͳҙຯ৘ใΛ෇༩Մೳ
    49

    View Slide

  50. Semantics Tree
    • WidgetTreeΛ࡞੒͢ΔͱSemanticsTree͕ੜ੒͞ΕΔ


    • WidgetTreeͱSemanticsTree͸1ର̍ͰରԠ͸͍ͯ͠ͳ͍


    • Semantics৘ใΛอ͍࣋ͯ͠ͳ͍Widget΍ෳ਺ͷWidget͕Ϛʔδ͞ΕΔͨΊ
    WidgetTree SemanticsTree
    50

    View Slide

  51. Semantics Node
    • SemanticsWidgetΛ࢖͏͜ͱͰSemanticsNodeΛੜ੒͢Δ͜ͱ͕Ͱ͖Δ


    • SemanticsNodeʹ͸SemanticsWidgetͰ෇༩ͨ͠ҙຯ৘ใ͕ؔ࿈෇͚Β
    Ε͍ͯΔ
    SemanticsNode


    - Label: `Flutter`


    - Button: true


    - Enable: true
    51

    View Slide

  52. Flutter Skelton Template
    • ύοέʔδͷதͰ͸
    SemanticsͷWidget͸
    ࢖ΘΕ͍ͯͳ͍


    • ͏·͘εΫϦʔϯϦʔ
    μʔͰಡΈ্͛Մೳʁ
    52

    View Slide

  53. Material IconButton
    • Semantics͕࢖ΘΕ͓ͯΓɺ
    Semantic৘ใ͕෇༩͞Ε͍ͯΔ


    • ଞͷWidget΋IconButtonಉ༷ʹ
    ద੾ͳSemantic৘ใΛอ࣋ & ઃ
    ఆͰ͖ΔΑ͏ʹͳ͍ͬͯΔ
    53

    View Slide

  54. Sample Code
    • Semantics͸Ͳ͏ͳΔ͔ʁ
    54

    View Slide

  55. Sample Code 2


    55

    View Slide

  56. Widget Tree and Semantics Tree
    Card
    Text Text
    Button
    label: 'FlutterKaigi'
    Label: 'Start'


    Button: true
    ɾɾɾলུ
    Text
    56

    View Slide

  57. Semantics Widget Property
    • bool container (default false)


    • trueͷ৔߹ʹ৽͍͠SemanticsNodeΛੜ੒͢Δ


    • falseͷ৔߹͸਌ͷSemanticsNodeʹϚʔδ͞ΕΔʢ਌͕ڐՄ͍ͯ͠Δ৔߹ʣ


    • bool explicitChildNodes (default false)


    • trueͷ৔߹͸ࢠͷSemanticsNodeΛࣗ਎ͷSemanticsNodeʹϚʔδ͕ෆՄʹͳΔ


    • falseͷ৔߹͸Ϛʔδ͢Δ͜ͱ͕Մೳ


    • bool excludeSemantics (default false)


    • trueͷ৔߹ʹchildͷSemanticsNodeΛআ֎͢Δ
    57

    View Slide

  58. Widget Tree and Semantics Tree
    Card


    container: true
    Text


    label 'Flutter'
    label: 'FlutterKaigi'
    Button: true


    Label: 'Start'
    ɾɾɾলུ
    Text


    label 'Kaigi'
    Button


    container: true


    button: true
    Text


    label 'Start!'
    58

    View Slide

  59. Widget Tree and Semantics Tree
    Card


    container: true
    Text


    label 'Flutter'
    label: 'FlutterKaigi'
    ɾɾɾলུ
    Text


    label 'Kaigi'
    Button


    container: true


    button: true
    Text


    label 'Start!'
    merge
    merge
    Button: true


    Label: 'Start!'
    59

    View Slide

  60. ExplicitChildNodes
    Card


    container: true


    explicitChildNodes: true
    Text


    label 'Flutter'
    Button: true


    Label: 'Start'
    ɾɾɾলུ
    Text


    label 'Kaigi'
    Button


    container: true


    button: true
    Text


    label 'Start!'
    Label: 'Kaigi'
    Label: 'Flutter'
    60

    View Slide

  61. Semantics Class
    • MergeSemantics: childͷsemanticsΛϚʔδ


    • ExcludeSemantics: childͷsemanticsΛআ֎


    • BlockSemantics: Widgetͷഎޙʹ͋ΔSemanticsΛແޮʢStackͷ
    WidgetΛҰॹʹ࢖༻Մೳʣ


    • OrdinalSortKey: ಡΈ্͛ॱংΛorderʹԠͯ͡ιʔτʢSemantics
    ͷsortKeyʹࢦఆʣ
    61

    View Slide

  62. SemanticsͷLabelͷ෇͚ํ
    • WCAG΍WCAGͷୡ੒ํ๏ूΛࢀߟ


    • https://waic.jp/docs/WCAG21/


    • https://waic.jp/docs/WCAG21/Techniques/


    • ྫᶃ : ը૾಺ʹίϯςϯπΛཧղ͢ΔͨΊͷจࣈؚ͕·ΕΔ


    • ಉ͡จࣈΛSemanticsͷLabelʹ෇༩


    • ྫᶄɿ૷০໨తͷը૾


    • Semanticsͷ৘ใΛ෇༩͠ͳ͍
    62

    View Slide

  63. ࣮૷࣌ͷ஫ҙ఺
    • ࣮ࡍʹ֬ೝͯ͠ΈΔͷ͕Ұ൪ྑ͍😅


    • ը૾


    • Exclude or Labelͷ෇༩


    • CustomWidget


    • ଐੑͷ෇༩ʢButton, SelectedͳͲʣ


    • Mergeͯ͠1ͭͷSemanticsNodeͱͯ͠ಡΈ্͛Δ
    63

    View Slide

  64. ΞδΣϯμ
    • Flutter ΞΫηγϏϦςΟ


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


    • ΞΫηγϏϦςΟରԠ
    64

    View Slide

  65. ։ൃͰ͸ʁ
    ػೳ։ൃ
    ΞΫηγϏ
    ϦςΟͷ
    νΣοΫ
    ΞΫηγϏ
    ϦςΟͷ
    νΣοΫ
    ΞΫηγϏ
    ϦςΟͷ
    νΣοΫ
    ΞΫηγϏϦ
    ςΟରԠ
    ΞΫηγϏϦ
    ςΟରԠ
    ΞΫηγϏϦ
    ςΟରԠ
    • ݄ʹ1ճͷΞΫηγϏϦςΟΛߦͳ͍ͬͯΔ


    • ׬੒ͨ͠ػೳ΍ը໘ͷΞΫηγϏϦςΟΛνΣοΫͯ͠ɺͦͷޙ͙͢
    ʹमਖ਼ͷରԠΛߦ͏
    65

    View Slide

  66. ྑ͔ͬͨ͜ͱ
    • νʔϜͷΞΫηγϏϦςΟͷϨϕϧ্͕͕Δ


    • ௨ৗͷ։ൃ͔ΒΞΫηγϏϦςΟΛҙࣝͨ͠ίʔυΛॻ͘͜ͱ͕Ͱ
    ͖ɺޙ͔ΒͷରԠίετ͕Լ͕Δ


    • ϨϏϡʔͰͷΞΫηγϏϦςΟͷࢦఠ͕Ͱ͖Δ


    • UIͷઃܭ࣌ʹΞΫηγϏϦςΟΛߟྀ͢Δ͜ͱ͕Ͱ͖Δ


    • ڞ௨ͷCustomWidge͸ΞΫηγϏϦςΟରԠࡁΈ
    66

    View Slide

  67. ·ͱΊ
    • ։ൃதͷΞϓϦͷΞΫηγϏϦςΟΛνΣοΫͯ͠ΈΑ͏


    • ೔ࠒ͔ΒΞΫηγϏϦςΟΛߟྀͨ͠։ൃΛߦ͏͜ͱͰɺগͳ͍ίε
    τͰΞΫηγϏϦςΟ͕ߴ͍ΞϓϦͷ։ൃ͕Մೳ
    67

    View Slide