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 full-size slide

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


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


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


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

    View full-size slide

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


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


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


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

    View full-size slide

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


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


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

    View full-size slide

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

    View full-size slide

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


    • Flutter.dev Accessibility


    • iOS


    • Human Interface Guideline Accessibility


    • Android


    • Material Design Accessibility
    6

    View full-size slide

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


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


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


    • Suf
    fi
    cient Contrast


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


    • Screen Reader


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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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


    • IconSizeɿ32px


    • Paddingɿ4px
    4px
    • IconButton


    • padding: 4


    • Icon: Icon()
    12

    View full-size slide

  13. ࣮૷ ྫ
    4px
    13

    View full-size slide

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

    View full-size slide

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


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

    View full-size slide

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


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


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

    View full-size slide

  17. System Font Scale
    17

    View full-size slide

  18. System Font Scale
    18

    View full-size slide

  19. System Font Scale
    19

    View full-size slide

  20. System Font Scale
    • MediaQueryData


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


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


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


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


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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  24. TextButton
    • test/material/text_butt


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

    View full-size slide

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


    • ͺͬͱΈ໰୊ͳ͠🙆
    25

    View full-size slide

  26. Widget Test Passed
    26

    View full-size slide

  27. Widget Test Failed
    27

    View full-size slide

  28. Error Message
    28

    View full-size slide

  29. Error Message
    29

    View full-size slide

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

    View full-size slide

  31. Fix
    SizedBoxΛ࡟আ
    31

    View full-size slide

  32. Widget Test Failed
    32

    View full-size slide

  33. Widget Test Failed
    33

    View full-size slide

  34. Error Message
    34

    View full-size slide

  35. Widget Test Failed
    36

    View full-size slide

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


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


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


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


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


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

    View full-size slide

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


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


    • Display Sizeখ͘͞ → WindowSize େ͖͘


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

    View full-size slide

  38. Ϩεϙϯγϒͳ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 full-size slide

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


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader
    40

    View full-size slide

  40. 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 full-size slide

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


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


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

    View full-size slide

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


    • AsyncMatcher meetsGuideline(AccessibilityGuideline guideline)


    • AccessibilityGuideline


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


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


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


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

    View full-size slide

  43. textContrastGuideline
    44

    View full-size slide

  44. textContrastGuideline
    45

    View full-size slide

  45. 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 full-size slide

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


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


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

    View full-size slide

  47. Screen Reader
    48

    View full-size slide

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


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


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

    View full-size slide

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


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


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

    View full-size slide

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


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


    - Label: `Flutter`


    - Button: true


    - Enable: true
    51

    View full-size slide

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


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

    View full-size slide

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


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

    View full-size slide

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

    View full-size slide

  54. Sample Code 2


    55

    View full-size slide

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


    Button: true
    ɾɾɾলུ
    Text
    56

    View full-size slide

  56. 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 full-size slide

  57. 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 full-size slide

  58. 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 full-size slide

  59. 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 full-size slide

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


    • ExcludeSemantics: childͷsemanticsΛআ֎


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


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

    View full-size slide

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


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


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


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


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


    • ྫᶄɿ૷০໨తͷը૾


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

    View full-size slide

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


    • ը૾


    • Exclude or Labelͷ෇༩


    • CustomWidget


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


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

    View full-size slide

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


    • Scale Factor


    • Suf
    fi
    cient Contrast


    • Screen Reader


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

    View full-size slide

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


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

    View full-size slide

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


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


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


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


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

    View full-size slide

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


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

    View full-size slide