Android
 Computer >> コンピューター >  >> システム >> Android

Kotlin Android アニメーションにアクセスできるようにする方法

史上初の Android コントリビューションの例を調査したとき、Kotlin で記述されたアニメーションの例はほとんどありませんでした。ネイティブ アニメーション内のアクセシビリティに関する考慮事項のコード例もほとんどありませんでした。

では、行きましょう! Kotlin でネイティブの「展開」アニメーションを作成する方法を見て、TalkBack や拡大テキストがオンになっている人を支援する方法について話しましょう。すべてのコードは、このサンプル リポジトリで利用でき、アニメーション ビューを含む単一のアクティビティを作成します。これが基づいているコードは、Calum Turner と共同で作成されました。

Kotlin Android アニメーションにアクセスできるようにする方法
アプリ終了結果の GIF

Android アクセシビリティ (a11y)

すべての Android デバイスには、TalkBack という名前のスクリーン リーダーが組み込まれています。これはデバイスの設定からオンにすることができ、初回使用ガイドも組み込まれています。ジェスチャーを使用してページ内を移動し、フォーカスされた要素の説明を読み上げます。これがないと、多くの視覚障害のあるユーザーにとってアプリが使えなくなります。

最も重要なのは、正しい要素がフォーカス可能であり、説明があり、ビューへの変更がアナウンスされることです。

同じ設定メニュー内で、デフォルトのベース フォント サイズを 1.0 からスケーリングして調整できます。ビューは、すべての要素が存在し、機能している状態で、このフォント サイズの変更に対応する必要があります。

レイアウト

レイアウトのスタイリングの詳細は、この例にかなり固有であるため、ここでは見ていきませんが、アクセシビリティのタッチは強調する価値があります。

2 つのプロパティが使用されます:android:contentDescriptionandroid:importantForAccessibility .

contentDescription 要素がフォーカスを得たときに読み取られるものです。フォーカスを取得する ImageView では、これが不可欠です。そうしないと、スクリーン リーダーは代わりに、役に立たない「ラベルなし」をユーザーに読み上げます。

これがボタンの場合、デフォルトで「 ボタン、ダブルタップしてアクティブ化」と表示されますが、ImageView アイコンについては、このデフォルトがないため、アクションを手動で指定します。

android:contentDescription="tap to toggle extra person information"

importantForAccessibility:no も使用します 「+」TextView のフォーカスをオフにします。これは、2 つのバッジの下にあるテキストが説明を提供するため、「+」は読み上げた場合に役立つというよりも混乱を招くためです。

これらの両方について、TalkBack がオンになっている実際のデバイスでの手動テストは、コンテキストがビジュアルなしで意味をなすかどうかの最良の指標です。

アニメーションを展開

アニメーションは「情報」アイコンのタップでアクティブになり、詳細セクションの展開を切り替えます。

アニメーション コードだけに集中できるように、これをすべて 1 つのアクティビティ内で行います。実際のアプリでは、これが適用されるビューは、独自のフラグメントまたはリサイクラー ビュー内にある可能性が高いため、より抽象化されたコード構造が使用されます。

リスナーの設定

サンプル アクティビティの onCreate 内 最初にアイコンにリスナーを設定し、切り替えるビューを渡す必要があります。

infoIcon.setOnClickListener { toggleCardBody(root.personEntryBody) }

また、ビューが切り替えられたかどうかを追跡する変数をクラス内に設定し、最初は閉じているように設定します。

private var isToggled = false

エキスパンド アニメーションの切り替え

レイアウト内で、高さを personEntryBody に設定しました 0dpまで .

これをオープンに切り替えるには、設定する新しい高さ、アニメーションの長さ、アニメーションの各瞬間の高さを知る必要があります。

isToggled を設定する必要があります その逆に、もう一度タップすると逆になることを確認してください。

private fun toggleCardBody(body: View) {
    body.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
    val maxHeight = body.measuredHeight + body.paddingTop + body.paddingBottom
    val startHeight = if (isToggled) maxHeight else 0
    val targetHeight = if (isToggled) 0 else maxHeight

    val expandAnimator = ValueAnimator
        .ofInt(startHeight, targetHeight)
        .setDuration(200)
    
    expandAnimator.addUpdateListener {
        val value = it.animatedValue as Int
        body.layoutParams.height = value
        body.requestLayout()
    }

    expandAnimator.doOnEnd {
        isToggled = !isToggled
    }

    expandAnimator.start()
}

ビューが最初に描画されたときの高さは 0 であるため、レイアウトを再測定して新しいサイズを計算する必要があります。

Android ビュー レイアウト ドキュメントで説明されているように、 measure() を使用できます。 情報アイコンがタップされるたびに再測定するために、ビューに割り当てたレイアウト パラメータと共に。

最大の高さを計算するには、測定された高さに含まれていないため、これに上下のパディングを手動で追加する必要があります。

isToggled による 次に、0 から開始するか、拡張された最大高さから開始するかがわかり、反対側のターゲットの高さもわかります。

Value Animator を使用して開始値から目標の終了値に移動し、期間をミリ秒単位で設定します。この期間は、UX フィールに関するその後の手動テストに完全に基づいています。

ValueAnimator
        .ofInt(startHeight, targetHeight)
        .setDuration(200)

更新リスナーで期間を高さに結び付け、各更新後に描画される新しいレイアウトを要求し、毎回高さを調整します。

    expandAnimator.addUpdateListener {
        val value = it.animatedValue as Int
        body.layoutParams.height = value
        body.requestLayout()
    }

    expandAnimator.doOnEnd {
        isToggled = !isToggled
    }

    expandAnimator.start()

Kotlin を使用しているため、androidx も追加します。 ライブラリを build.gradledoOnEnd の恩恵を受ける 拡大。これにより、isToggled を非常に簡単に逆にすることができます。

ついにアニメーションを開始します!アイコンタッチで伸び縮みするボディができました!

よりスムーズなアニメーション

私たちのアニメーションは技術的にはそのままで機能しますが、動きがより自然に感じられるようにインターポレーターを追加することは良い追加のステップです.

expandAnimator.interpolator = FastOutSlowInInterpolator()

アクセシビリティの向上

a11y ユーザーに役立つことを願って、最後に 2 つのことを追加します。

まず、AccessibilityEvent を使用してナビゲーションを支援できます .

expandAnimator.doOnEnd {
    if (!isToggled)       body.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
    isToggled = !isToggled
}

これは、アニメーションが閉じた状態から開いた状態に移動すると、フォーカスが本文の最初の項目 (この場合は説明) のフォーカスにすぐに移動することを意味します。レイアウトでは、情報アイコン アクションの説明を設定しますが、ユーザーが次の項目に移動するための視覚的なインジケーターに頼ることができない場合があるため、これを処理できます。

次に、さまざまなフォント サイズを許可します。 measure() から返される測定された高さ は、デバイスのアクセシビリティ設定で設定されたフォント スケーリングを考慮していません。そのため、大きな縮尺では、説明が大きすぎて収まらないため、説明の下部がトリミングされます。

プログラムでフォント スケールにアクセスし、これに基づいて高さを調整できます。フォント スケールがレイアウトの高さとして機能しない float になる可能性があるため、整数に変換します。

val a11yFontScale = body.context.resources.configuration.fontScale
val maxHeight = ((body.measuredHeight + body.paddingTop + body.paddingBottom) * a11yFontScale).toInt()

完成!

Kotlin Android アニメーションにアクセスできるようにする方法
アプリ終了結果の GIF

これで、最終的なアニメーションに到達しました。ほんの数行追加するだけで、a11y の対象範囲が大幅に拡大され、Kotlin と Android のバッジが表示されるセクションがスムーズに展開されますか?

読んでくれてありがとう?

最近書いた他のいくつかのことを次に示します。

  • CodeceptJS E2E テストのカスタマイズ
  • Jest および Enzyme II を使用した React のテスト

便利なエクストラ

  • Android 用 KTX の探索に関する Joe Birch の素晴らしい androidx 投稿
  • Android アクセシビリティ チュートリアル:はじめに

  1. Android で YouTube の曲を着信音として作成する方法

    Android デバイスのデフォルトの着信音に飽き飽きしていませんか?さて、多くのユーザーは、独自の曲の着信音を設定して、電話の着信音を試す必要があると感じています。 YouTube で聞いた曲を電話の着信音として設定することもできます。 YouTube はエンターテイメントの最大のプラットフォームの 1 つであり、何百万もの曲から電話の着信音を選択できます。ただし、YouTube では、ユーザーがビデオから曲のオーディオをダウンロードすることを許可していません。 YouTube から着信音を作成する方法について疑問に思われるかもしれませんが、YouTube から曲をダウンロードして電話の

  2. AndroidフォンでLaravel 8をセットアップする方法

    やあ、調子はどうですか?この記事では、携帯電話に Laravel 8 をインストールする方法を紹介します。 このガイドを最大限に活用するには、PHP についてある程度の知識があり、Laravel とは何かを知っている必要があります。しかし、そうでない場合でも、心配しないでください。開始できるように基本を説明します。 Laravel とは? Laravel は、表現力豊かで洗練された構文を備えた Web アプリケーション フレームワークです。これは PHP 上に構築されています。つまり、Laravel は PHP ですが、操作が簡単になります。 認証などのさまざまな機能のパッケージが多数