Я создал свою собственную кнопку с текстом и изображением. Для этого я использовал фрейм, в котором все инкапсулировал. В Android должна быть нажата кнопка. Для этого я использовал FrameRenderer, где у меня есть событие Touch в случае с Android, и оно прекрасно работает.
Проблема в том, что я также хочу использовать Frame.GestureRecognizers для отправки команды при ее нажатии, но это, по-видимому, отменяет вызов события, поскольку команда не выполняется. Следует отметить, что я сделал точно так же для UWP, и этой проблемы не возникает. Наверное, я ем что-то на Android. Я поделюсь с вами кодом, чтобы узнать, можете ли вы мне помочь. Спасибо.
Xaml:
<local:MyFrameButton
x:Name = "ButtonFrame"
Grid.Column = "0"
Grid.Row = "6"
Grid.ColumnSpan = "2"
Grid.RowSpan = "4"
CornerRadius = "5"
BackgroundColor = "{StaticResource ButtonColor}"
HorizontalOptions = "CenterAndExpand"
VerticalOptions = "CenterAndExpand"
HeightRequest = "172"
WidthRequest = "172"
Padding = "0" >
<Grid Padding = "8">
<Label
Text = "{Binding IconCustomer}"
FontFamily = "{DynamicResource MaterialFontFamilyID}"
FontSize = "{OnPlatform Android='45', iOS='45', UWP='55'}"
TextColor = "White"
HorizontalOptions = "CenterAndExpand"
VerticalOptions = "CenterAndExpand" >
</Label>
<Label
Grid.Row = "1"
Text = "Clientes"
FontSize = "17"
TextColor = "White"
HorizontalOptions = "Center"
VerticalOptions = "Center" />
</Grid>
<Frame.GestureRecognizers>
<TapGestureRecognizer
Command = "{Binding CustomerListCommand}"
/>
</Frame.GestureRecognizers>
</local:MyFrameButton>
ViewModel:
public ICommand CustomerListCommand => new RelayCommand(GoCustomerList);
private async void GoCustomerList()
{
isRunning = true;
MainViewModel.Instance.CustomersV = new CustomersViewModel(CustomerList);
await MainViewModel.Instance.CustomersV.LoadConditionInitialsAsync();
await navigationService.Navigate("CustomersView");
isRunning = false;
}
Фреймрендерер:
class MyFrameButtonRenderer : FrameRenderer
{
public MyFrameButtonRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var drawable = new GradientDrawable();
ViewGroup.SetBackground(drawable);
UpdateBackgroundColor(drawable);
UpdateCornerRadius(drawable);
UpdateOutlineColor(drawable);
UpdateShadow();
this.Touch += (v, me) =>
{
switch (me.Event.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
Element.Scale = 1.05;
break;
case MotionEventActions.Up:
Element.Scale = 1;
break;
case MotionEventActions.PointerDown:
break;
case MotionEventActions.PointerUp:
break;
case MotionEventActions.Move:
break;
}
};
}
}
}
@ G.hakim Привет, нет, у меня это было только в сетке. но я мог найти решение, изменив FrameRender на событие Toch с помощью публичного переопределения bool OnTouchEvent (MotionEvent e), это благодаря FaizalSaidali, который дал мне совет на форумах Xamarin. forums.xamarin.com/discussion/comment/376599#Comment_376599
Решение состояло в том, чтобы изменить событие Touch в FrameRender с помощью публичного переопределения bool OnTouchEvent (MotionEvent e), как показано ниже:
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
Element.Scale = 1.05;
break;
case MotionEventActions.Up:
Element.Scale = 1;
break;
case MotionEventActions.PointerDown:
break;
case MotionEventActions.PointerUp:
break;
case MotionEventActions.Move:
break;
}
return base.OnTouchEvent(e);
}
Идея была подана мне мистером Файзалом Сайдали на форуме Xamarin:
https://forums.xamarin.com/discussion/comment/376599#Comment_376599
Этот кадр в
ListView
или вообще в любойDataTemplate
?