3

First time asking a question here so lets see...

I'm having trouble with setting the ripple effect programmatically onto a CardView. (But i hope to find a way that works basically on any kind of view) The thing is, my cards are made programmatically like this :

...
        //make cardview
        CardView result = new CardView(Activity);
        //set layout
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, 100, 1f);
        layoutParams.SetMargins(10, 10, 10, 10);
        result.LayoutParameters = layoutParams;
        result.Tag = itemId.ToString();

        //FAILED ATTEMPT 1: 
        //result.Foreground = "?android:attr/selectableItemBackground";

        //FAILED ATTEMPT 2 : 
        //result.SetBackgroundDrawable(view.Resources.GetDrawable(Resource.Drawable.ripple));

...

Now as you can see i tried it with the foreground property based on the answer to a similar question that can be found here.

the second attempt makes me feel like its on the right path but it makes all my cards invisible-ish : link. (I added the ripple.xml to the drawable folder of my project)

I also found the RippleDrawable class but i really don't understand how to use it correctly. It asks for using a mask and a content drawable but i have no idea what to put there. My implementation of that so far :

result.Background = new RippleDrawable(view.Resources.GetColor(Resource.Color.green),????,?????);

The main reason i want the ripple effect is because i show a list of cards, and they all have a onLongClick event that opens a popupmenu. I want to indicate that the cards are clickable.

Anyways, I hope somebody can help me find a solution.

**UPDATE : ** cards turn invisible with code of pre-android 5.

 ...
 result.Tag = itemId.ToString();
 TypedValue outValue = new TypedValue();
        this.Activity.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, true);
        result.SetBackgroundResource(outValue.ResourceId);

1 Answers1

2

Well, the smart way of doing it would be something like this :

Note: The following code does not work in devices running below API-21 or Android Lollipop.

Add the following XML to your layout folder.

Ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/yourViewRippleColor"
tools:targetApi="lollipop">

<item>
<color android:color="@color/yourViewBackgroundColor" />
</item>

<item android:id="@android:id/mask">
  <shape android:shape="rectangle">
  <solid android:color="@color/yourViewRippleColor" />
  </shape>
</item>
</ripple>

And use it like this when needed:

_yourView.SetBackgroundResource(Resource.Layout.Ripple);

And if I am not wrong you can do it purely programmatically using something like this :

Note: Should work on any device above and on honeycomb.

TypedValue outValue = new TypedValue();
        this.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, true);//In an Activity
        this.Activity.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, true);//In an Fragment
        _YourView.SetBackgroundResource(outValue.ResourceId);

Goodluck!

In case you have queries revert.

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
  • I hope you have read that it does not work below android version 5 – FreakyAli May 07 '18 at 07:34
  • Yeah ive read it and just now tried the code, for some reason it doesn't seem to display anything (like my previously visible cards now became completely transparent . So i assume i have to turn the typedValue into the ripple xml or am i missing something it is placed in a fragment, for code see edit on post (also if you got any spam of me editing this comment, im sorry in advance ) – DramaticlyForgottenSemiColon May 08 '18 at 08:01
  • try removing the Android.Resource and use your project resources instead and check if that works! – FreakyAli May 08 '18 at 09:45
  • just tried this.Activity.Theme.ResolveAttribute(Resource.Attribute.selectableItemBackground, outValue, true); it still has the same endresult. Could it be that outValue is grabbing the wrong thing? When i used a watch to look at it it grabs a "{TypedValue{t=0x3/d=0x31f "res/drawable/item_background_material.xml" a=1 r=0x108045e}}". I thought it might have been my theme but there isn't really much going on in there either. I do wonder, i'm using appcompat for some elements; Could that cause the problem? – DramaticlyForgottenSemiColon May 08 '18 at 12:21
  • No thats not the problem but there can be other reasons that i am unaware of so i can't tell whats causing the problem until i debug and see the watch myself – FreakyAli May 16 '18 at 13:58