I've create a layout that lists a List of objects in a RecyclerView
. I would like to add the option for the user to save a certain object, but I have no idea how to achieve something like the layout bellow. I need a button that can be toggled, and that if the user clicks it, it will fill the heart button with red, otherwise, it will be empty. Thank you.
Layout
If you want that heart to fill from nothing to full using some kind of animation, I'd suggest looking into SkiaSharp (https://blog.xamarin.com/deep-dive-skiasharp-xamarin-forms/) and then using the Animation Class (https://xamarinhelp.com/custom-animations-in-xamarin-forms/) to animate the fill height.
In a nutshell, you have to create a custom view in which you add a SKCanvasView:
<skia:SKCanvasView x:Name="PrimaryCanvas" PaintSurface="OnPaintSurface" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
In your view.xaml.cs you add a new function
OnPaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { ... }
Inside of this function you'll need to write some code to draw your heart. I'd suggest you draw an outline first and then the inside, which is supposed to fill up. You probably want to add a bindable property which holds the value of the amount to fill up, maybe as a percentage. Use this property to calculate the height of your inner part within your OnPaintSurface code.
Finally when you want your icon to fill up, you create an Animation, which then alters the property created earlier:
new Animation((value) =>
{
FillHeightProperty = value;
PrimaryCanvas.InvalidateSurface();
}).Commit(this, "fillAnimation", length: 350, repeat: () => false);
Notice that you need to invalidate the PrimaryCanvas surface. This will result in calling OnPaintSurface again, which will use your changed property and therefore increase the height of your filling while redrawing the canvas.
You can define a heart background with vector
and path
:
<?xml version="1.0" encoding="utf-8" ?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="250dp"
android:width="250dp"
android:viewportHeight="32"
android:viewportWidth="32" >
<path
android:name="heart"
android:fillColor="#f9f7f7"
android:strokeColor="#090808"
android:strokeWidth="1"
android:pathData="M20.5,9.5
c-1.955,0,-3.83,1.268,-4.5,3
c-0.67,-1.732,-2.547,-3,-4.5,-3
C8.957,9.5,7,11.432,7,14
c0,3.53,3.793,6.257,9,11.5
c5.207,-5.242,9,-7.97,9,-11.5
C25,11.432,23.043,9.5,20.5,9.5z"/>
</vector>
Here, I have posted my demo on github, you can see a button with selector
background which allow you change the button's background with the button's state, and another button with the SVG background.
Update:
I have add animation on the button.
private void Mbt_Click(object sender, System.EventArgs e)
{
if (isClick)
{
mbt.SetBackgroundResource(Resource.Drawable.heart);
isClick = false;
}else {
mbt.SetBackgroundResource(Resource.Drawable.heart_press);
ObjectAnimator animator = ObjectAnimator.OfFloat(mbt, "scaleY", 1f, 1.2f, 1f);
animator.SetDuration(1000);
animator.Start();
ObjectAnimator animator1 = ObjectAnimator.OfFloat(mbt, "scaleX", 1f, 1.2f, 1f);
animator1.SetDuration(1000);
animator1.Start();
isClick = true;
}
}