波紋カードビューのリップルホットスポットを設定する方法は?タッチポイントから
Googleは、彼らがそれらの波紋アニメーションをトリガしたタッチポイントから出ていないよう材料設計スタイルのUIにリップルアニメーションを使用した場合、アプリ開発者に指摘を開始しました。
Googleの検索エンジンを使用して、この作業を行う方法を説明した唯一のものは、Lucas RochaのTwoWayViewライブラリの問題に関するコメントでした。幸いなことに、そのコメントは私にとってはうまくいくようなものを作るのに十分なものでした。
彼のつぶやきでButcher氏がヒントしたように、キーはDrawableのsetHotspot()メソッドのようです。 APIレベル21で追加された、これはdrawableに "ホットスポット"を教え、RippleDrawableは明らかにこれを波紋効果の発散点として使用します。 setHotspot()は浮動小数点値のペアを取ります。おそらくOnTouchListener内でsetHotspot()を使用することに注意してください。これは、MotionEventがfloat値のタッチイベントのX/Y位置を報告するためです。
このサンプルアプリケーションでは、次の書籍の更新のために取り組んでいる50ページ以上の章の一環として、RecyclerViewのコンテキストでsetHotspot()を使用する方法を示します。このRecyclerViewは、従来のListViewの基本構造を複製するためにLinearLayoutManagerを使用しています。私の行はCardViewに基づいています:
`` `ユーザーが行に触れた場合は、XML
だから、私はそのホットスポットとしてバックグラウンドへのタッチポイントを伝播します。タッチイベントを消費していないことを示すためにfalseを返すので、必要に応じて残りのイベントハンドラに処理を継続します。
このsetHotspot()呼び出しがなければ、RippleDrawableはデフォルトでドロアブルの中心にあるようです。したがって、リストスタイルのRecyclerViewの行の場合、波紋効果は行の中央から出現します。タッチイベントに関連付けられたsetHotspot()は、エミッタポイントを変更します。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
cardview:cardCornerRadius="4dp">
<LinearLayout
android:id="@+id/row_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground">
<!-- other widgets in here -->
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
```
The LinearLayout that the CardView wraps has ?android:attr/selectableItemBackground as its background, pulling in a theme attribute. If this app runs on API Level 21, that background will be a RippleDrawable.
When I set up the row, I attach an OnTouchListener to set the hotspot, but only on API Level 21+ devices (as setHotspot() does not exist before then):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
row.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
v
.findViewById(R.id.row_content)
.getBackground()
.setHotspot(event.getX(), event.getY());
return(false);
}
});
}
これは動作するようです。私はそれが正式な正解であるかどうか分かりません。これは、Googleがどのようにこれを実装するのかわからない限りです(setHotspot()のSDKサンプルを検索すると何も表示されません)。特に、バックグラウンドでsetHotspot()を直接呼び出すと、私はmutate()を最初に呼び出すべきでしょうか?)。ですから、一面に約15cmの塩の粒を想像して、この実装で塩分を取ります。