-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TouchEffect and scrolling (Android) #52
Comments
I got the Command working. private void _viewOverlay_Click(object sender, EventArgs e) {
foreach(var recognizer in ((Xamarin.Forms.View)Element).GestureRecognizers) {
if(recognizer is TapGestureRecognizer gesture) {
if(gesture.Command != null) {
gesture.Command.Execute(gesture.CommandParameter);
}
}
}
} My question is now: Can you remove the TouchCollector from the effect and implement the click event like i do? Then it should work in ScrollViews. |
Hello. I thinking about new version with fixes all bugs. But haven't time for that... |
@AlleSchonWeg Could you please share your whole solution? |
@isness : Here are the effect for android: using System;
using System.ComponentModel;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Android.Graphics.Color;
using ListView = Android.Widget.ListView;
using ScrollView = Android.Widget.ScrollView;
using View = Android.Views.View;
using VisualTouchFeedbackRoutingEffect = xxxx.Droid.Effects.VisualTouchFeedbackRoutingEffect;
[assembly: ExportEffect(typeof(VisualTouchFeedbackRoutingEffect), nameof(xxxx.Effects.VisualTouchFeedbackRoutingEffect))]
namespace xxx.Droid.Effects {
class VisualTouchFeedbackRoutingEffect : PlatformEffect {
public bool IsDisposed => (Container as IVisualElementRenderer)?.Element == null;
public View View => Control ?? Container;
//Color _color;
//RippleDrawable _ripple;
FrameLayout _viewOverlay;
protected override void OnAttached() {
if(Control is ListView || Control is ScrollView) {
return;
}
View.Clickable = true;
View.LongClickable = true;
_viewOverlay = new FrameLayout(Container.Context) {
LayoutParameters = new ViewGroup.LayoutParams(-1, -1),
Clickable = false,
Focusable = false,
};
Container.LayoutChange += ViewOnLayoutChange;
_viewOverlay.Touch += _viewOverlay_Touch;
_viewOverlay.Click += _viewOverlay_Click;
_viewOverlay.Foreground = CreateRipple(Android.Resource.Attribute.SelectableItemBackground);
Container.AddView(_viewOverlay);
_viewOverlay.BringToFront();
}
private void _viewOverlay_Touch(object sender, View.TouchEventArgs e) {
e.Handled = false;
switch(e.Event.Action) {
case MotionEventActions.Down: {
if(IsDisposed || !(_viewOverlay.Foreground is RippleDrawable bc))
return;
bc.SetHotspot(e.Event.GetX(), e.Event.GetY());
break;
}
}
}
private void _viewOverlay_Click(object sender, EventArgs e) {
foreach(var recognizer in ((Xamarin.Forms.View)Element).GestureRecognizers) {
if(recognizer is TapGestureRecognizer gesture) {
if(gesture.Command != null) {
gesture.Command.Execute(gesture.CommandParameter);
}
}
}
}
RippleDrawable CreateRipple(int color) {
var attrs = new int[] { color };
var typedArray = Xamarin.Essentials.Platform.AppContext.ObtainStyledAttributes(attrs);
var drawableFromTheme = (RippleDrawable)typedArray.GetDrawable(0);
typedArray.Recycle();
return drawableFromTheme;
}
static ColorStateList GetPressedColorSelector(int pressedColor) {
return new ColorStateList(
new[] { new int[] { } },
new[] { pressedColor, });
}
protected override void OnDetached() {
if(IsDisposed)
return;
Container.RemoveView(_viewOverlay);
_viewOverlay.Click -= _viewOverlay_Click;
_viewOverlay.Touch -= _viewOverlay_Touch;
_viewOverlay.Pressed = false;
_viewOverlay.Foreground = null;
_viewOverlay.Dispose();
Container.LayoutChange -= ViewOnLayoutChange;
//_ripple?.Dispose();
}
private void ViewOnLayoutChange(object sender, View.LayoutChangeEventArgs layoutChangeEventArgs) {
var group = (ViewGroup)sender;
if(group == null || IsDisposed)
return;
_viewOverlay.Right = group.Width;
_viewOverlay.Bottom = group.Height;
}
}
} And the effect in the shared project: using System;
using Xamarin.Forms;
using XamEffects;
namespace xxx.Effects {
public class VisualTouchFeedbackRoutingEffect : RoutingEffect {
public VisualTouchFeedbackRoutingEffect() : base($"{nameof(xxx)}.{nameof(VisualTouchFeedbackRoutingEffect)}") {
}
}
public static class VisualTouchFeedbackEffect {
public static readonly BindableProperty ColorProperty =
BindableProperty.CreateAttached(
"Color",
typeof(Color),
typeof(VisualTouchFeedbackEffect),
Color.Default,
propertyChanged: PropertyChanged
);
public static void SetColor(BindableObject view, Color value) {
view.SetValue(ColorProperty, value);
}
public static Color GetColor(BindableObject view) {
return (Color)view.GetValue(ColorProperty);
}
private static void PropertyChanged(BindableObject bindable, object oldValue, object newValue) {
var color = GetColor(bindable);
//Für iOS das TouchEffect Nuget nutzen.
if(Device.RuntimePlatform == Device.iOS) {
TouchEffect.SetColor(bindable, color);
}
//Für Android abgewandelte Form des TouchEffect Nuget
else if(Device.RuntimePlatform == Device.Android) {
if(bindable is View view) {
SetColor(bindable, Color.Default);
EffectsConfig.SetChildrenInputTransparent(view, true);
view.Effects.Add(new VisualTouchFeedbackRoutingEffect());
}
}
else {
throw new NotSupportedException($"{Device.RuntimePlatform} is not supported!");
}
}
}
} |
@AlleSchonWeg Hmm, I can't get it to work. Have you tried it on CollectionView? My collection view starts like this:
|
@isness I use the Sharpnado HorizontalListView. Not sure, if XF CollectionView works. Do you attach the effect like this: |
Yes, I attached it the way you described. Can't get it to work on collectionview. Maybe it doesn't work on latest XF version, I have no idea. The same bug exists on XamarinCommunityToolkit, though. It would be great to have a workaround for it: xamarin/XamarinCommunityToolkit#1261 |
Hi,
i have the same problem as described in this post: #41
and i played a litte bit with your code. If i comment out the TouchCollector.Add and TouchCollector.Delete calls the ripple effect is not called while scrolling, like items in a ListView.
But my problem is now, that the Command is not executed. Do you still support your library and could you fix it?
The text was updated successfully, but these errors were encountered: