オープンソースライブラリのタッチフィードバックを有効にしたいと思います。
RecyclerView
とCardView
を作成しました。 CardView
には、異なるonClick
アクションを持つ異なる領域が含まれています。ユーザーがカードの任意の場所をクリックすると、リップル効果がトリガーされますが、この動作を実現することはできません。
これは私のリストアイテムです。GitHubでも見つけることができます。 https://github.com/mikepenz/AboutLibraries/blob/master/library/src/main/res/layout/listitem_opensource.xml
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:clickable="true"
Android:background="@drawable/button_rect_normal"/>
<LinearLayout
Android:padding="6dp"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical">
<LinearLayout
Android:gravity="center_vertical"
Android:paddingLeft="8dp"
Android:paddingRight="8dp"
Android:orientation="horizontal"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/libraryName"
Android:textColor="@color/title_openSource"
Android:textSize="@dimen/textSizeLarge_openSource"
Android:textStyle="normal"
Android:layout_width="0dp"
Android:layout_weight="5"
Android:layout_height="wrap_content"
Android:ellipsize="end"
Android:maxLines="1"/>
<TextView
Android:id="@+id/libraryCreator"
Android:textColor="@color/text_openSource"
Android:textStyle="normal"
Android:layout_width="0dp"
Android:layout_weight="2"
Android:layout_height="wrap_content"
Android:layout_marginTop="2dp"
Android:gravity="right"
Android:maxLines="2"
Android:textSize="@dimen/textSizeSmall_openSource"/>
</LinearLayout>
<View
Android:layout_width="match_parent"
Android:layout_height="1px"
Android:layout_marginTop="4dp"
Android:background="@color/dividerLight_openSource"/>
<TextView
Android:id="@+id/libraryDescription"
Android:textSize="@dimen/textSizeSmall_openSource"
Android:textStyle="normal"
Android:textColor="@color/text_openSource"
Android:padding="8dp"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:maxLines="20">
</TextView>
<View
Android:id="@+id/libraryBottomDivider"
Android:layout_width="match_parent"
Android:layout_height="1px"
Android:layout_marginTop="4dp"
Android:background="@color/dividerLight_openSource"/>
<LinearLayout
Android:id="@+id/libraryBottomContainer"
Android:gravity="center_vertical"
Android:paddingLeft="8dp"
Android:paddingTop="4dp"
Android:paddingRight="8dp"
Android:orientation="horizontal"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/libraryVersion"
Android:textColor="@color/text_openSource"
Android:textStyle="normal"
Android:layout_width="0dp"
Android:layout_weight="1"
Android:layout_height="wrap_content"
Android:gravity="left"
Android:maxLines="1"
Android:textSize="@dimen/textSizeSmall_openSource"/>
<TextView
Android:id="@+id/libraryLicense"
Android:textColor="@color/text_openSource"
Android:textStyle="normal"
Android:layout_width="0dp"
Android:layout_weight="1"
Android:layout_height="wrap_content"
Android:gravity="right"
Android:maxLines="1"
Android:textSize="@dimen/textSizeSmall_openSource"/>
</LinearLayout>
</LinearLayout>
また、onClick
は、このレイアウトの3つの部分に設定されています。 libraryCreator
、libraryDescription
、およびlibraryBottomContainer
。
ここで何が間違っているのか、誰かがアイデアを得たと思います。
ご協力いただきありがとうございます。
これで問題を解決できました。
問題は、TextViewsでonClickListenerを使用し、このクリックリスナーがRippleForegroundがタッチイベントについて通知されないようにすることです。そのため、解決策は、これらのTextViewにTouchListenerを実装し、タッチイベントを渡すことです。
クラスは本当にシンプルで、どこでも使用できます。
package com.mikepenz.aboutlibraries.util;
import Android.support.v7.widget.CardView;
import Android.view.MotionEvent;
import Android.view.View;
/**
* Created by mikepenz on 16.04.15.
*/
public class RippleForegroundListener implements View.OnTouchListener {
CardView cardView;
public RippleForegroundListener setCardView(CardView cardView) {
this.cardView = cardView;
return this;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// Convert to card view coordinates. Assumes the Host view is
// a direct child and the card view is not scrollable.
float x = event.getX() + v.getLeft();
float y = event.getY() + v.getTop();
if (Android.os.Build.VERSION.SDK_INT >= 21) {
// Simulate motion on the card view.
cardView.drawableHotspotChanged(x, y);
}
// Simulate pressed state on the card view.
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
cardView.setPressed(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
cardView.setPressed(false);
break;
}
// Pass all events through to the Host view.
return false;
}
}
これをTouchListenerとして追加することで使用できます。
RippleForegroundListener rippleForegroundListener = new RippleForegroundListener();
older.libraryCreator.setOnTouchListener(rippleForegroundListener);
このリスナーは、タッチイベントをCardViewに渡すだけで、正しいリップル効果をトリガーします。 (任意のビューを取得するようにこれを変更することもできます。CardViewに限定されるべきではありません)
Material/AppcompatテーマとLollipopを使用していると仮定すると、CardViewに次の属性を持たせることでこれが機能するようになりました。
Android:focusable="true"
Android:clickable="true"
Android:foreground="?android:attr/selectableItemBackground"
CardLayoutはViewGroupのサブクラスなので、設定は次のとおりです。
Android:background="?android:attr/selectableItemBackground"
トリックを行う必要があります。
UPDATE:
(カスタムリップル色を使用しようとしているように見えます。)
背景としてカスタムカラーのリップルドローアブルを使用してみてください(これを使用していません。したがって、この動作を確認できません。)参照: documentation またはthis question あなたが始めました。
私のために:
Android:background="?android:attr/selectableItemBackground"
ようやく機能しました。 recyclerViewの背景/アイテムの背後にあるコンテンツを参照し、recyclerViewで使用される波及効果も参照してください。
上記の答えはどれも私にとってはうまくいかず、あまりにも複雑でした。
その後、RECYCLERVIEW ADAPTERレイアウトで次のプロパティを設定する必要があることに気付きました。
Android:background="?android:attr/selectableItemBackground"
Android:focusable="true"
Android:clickable="true"
それから私はそれを動作させました。
Android:foreground="?android:attr/selectableItemBackground"
バックグラウンドの代わりにフォアグラウンドを使用する場合、クリック可能またはフォーカス可能を使用する必要はありません
私の場合、カスタムの背景と波及効果も表示する必要がありました。したがって、これを実現する方法は、リサイクラービューアイテムのルートレイアウトに次の2つの属性を適用することです。
Android:background="@drawable/custom_bg"
Android:foreground="?android:attr/selectableItemBackground"
江と同じ問題がありました:
RecycleViewを膨らませるレイアウトファイルに属性を設定する必要があります。
私のメインレイアウト:(Do n'tここにプロパティを追加してください!)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:scrollbars="vertical"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
</RelativeLayout>
私のRecycleViewAdapter:
View v = inflater.inflate(R.layout.list_center_item, parent, false);
私のlist_center_item.xml(ここにプロパティを追加してください!)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@Android:id/text1"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:background="?android:attr/selectableItemBackground"
Android:clickable="true"
Android:focusable="true"
/>
CardView
の下で使用しているレイアウトに次の行を追加する必要があります
Android:clickable="true"
Android:focusable="true"
Android:background="@drawable/my_ripple"
例
<Android.support.v7.widget.CardView Android:layout_height="wrap_content"
Android:layout_width="match_parent"
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:clickable="true"
Android:focusable="true"
Android:background="@drawable/my_ripple">
私の場合、実際の馬鹿げた問題は次のとおりです...
技術的には、私の場合、誰もがここで提案しているようなことではありません。本当の問題は、LayoutView
、RelativeView
、またはTextView
のどこでもAndroid:clickable = "true"を使用してはならないことです。
CardViewにのみ存在する必要があります。その後、チャームのように動作します
Android:focusable="true"
は本当に必要ではありません。
CardViewに以下を追加するだけです
Android:clickable="true" Android:foreground="?android:attr/selectableItemBackground"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<Android.support.v7.widget.CardView
Android:id="@+id/card_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="center"
Android:layout_margin="@dimen/card_margin"
Android:foreground="?android:attr/selectableItemBackground"
Android:clickable="true"
Android:elevation="3dp"
card_view:cardCornerRadius="@dimen/card_corner_radius">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<ImageView
Android:id="@+id/card_template_item_image"
Android:layout_width="match_parent"
Android:layout_height="@dimen/card_size_height"
Android:scaleType="fitXY" />
<TextView
Android:id="@+id/card_template_item_title"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@id/card_template_item_image"
Android:paddingLeft="@dimen/card_title_padding"
Android:paddingRight="@dimen/card_title_padding"
Android:paddingTop="@dimen/card_title_padding"
Android:textSize="@dimen/card_title_size"
Android:text="@string/place_holder_item_name"/>
<TextView
Android:id="@+id/card_template_item_sub_title"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@id/card_template_item_title"
Android:paddingBottom="@dimen/card_sub_title_padding"
Android:paddingLeft="@dimen/card_sub_title_padding"
Android:paddingRight="@dimen/card_sub_title_padding"
Android:textSize="@dimen/card_sub_title_size"
Android:text="@string/place_holder_item_category"/>
</RelativeLayout>
</Android.support.v7.widget.CardView>
</LinearLayout>