Xamarin 表单在按下时禁用图像按钮,背景不正确
我的 Android 图像按钮背景有问题。我根据按下/释放事件实现了长按图像按钮。第一个问题是当我禁用按钮时发布事件。我通过调用 PropagateUpReleased 解决了这个问题,在 iOS 上这就足够了,但在 Android 上我遇到了问题,当我将按钮设置为再次启用时,我有一个按钮背景,就像它被按下一样:
- ,按钮有深灰色
- 长按向上箭头 ImageButton (XamarinForms) 的最大设置按钮为禁用
- 传播释放按钮
- 释放称为
- 禁用按钮具有浅灰色
- 单击向下箭头,向上箭头设置为启用,背景颜色为深灰色 我的 ImageButtonRenderer 实现:
public CustomButtonRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(Button.IsEnabled) && !Element.IsEnabled && Element.IsPressed)
{
PropagateRelease();
}
}
public override bool OnTouchEvent(MotionEvent e)
{
if (e.Action == MotionEventActions.Cancel)
PropagateRelease();
return base.OnTouchEvent(e);
}
private void PropagateRelease()
{
Element.PropagateUpReleased();
((IButtonController)Element).SendReleased();
Invalidate();
PostInvalidate();
}
编辑:
这是我的行为实现:
public class LongPressBehavior : Behavior<ImageButton>
{
private readonly object syncObject = new object();
private const int DurationStartLongPress = 500;
private const int DurationNextLongPress = 150;
private ImageButton button;
private Timer startTimer;
private Timer nextTimer;
private volatile bool isReleased;
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command),
typeof(ICommand), typeof(LongPressBehavior), default(ICommand));
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
#region Cnt
public LongPressBehavior()
{
isReleased = true;
}
#endregion
#region LifeCycles
protected override void OnAttachedTo(ImageButton button)
{
this.button = button;
base.OnAttachedTo(button);
this.BindingContext = button.BindingContext;
button.Pressed += Button_Pressed;
button.Released += Button_Released;
}
protected override void OnDetachingFrom(ImageButton button)
{
base.OnDetachingFrom(button);
this.BindingContext = null;
button.Pressed -= Button_Pressed;
button.Released -= Button_Released;
}
#endregion
#region Events
private void Button_Pressed(object sender, EventArgs e)
{
Debug.WriteLine("Pressed...");
isReleased = false;
InitializeStartTimer();
}
private void Button_Released(object sender, EventArgs e)
{
Debug.WriteLine("Released...");
isReleased = true;
DeInitializeTimer(ref startTimer);
DeInitializeTimer(ref nextTimer);
}
protected virtual void OnLongPressed()
{
if (button.Command != null)
{
Debug.WriteLine("Longpress execute...");
button.Command.Execute(null);
}
if (nextTimer == null)
InitializeNextTimer();
}
private void Timer_Elapsed(object state)
{
if (isReleased)
{
return;
}
Device.BeginInvokeOnMainThread(OnLongPressed);
}
#endregion
#region Private methods
private void DeInitializeTimer(ref Timer timer)
{
Debug.WriteLine("Dispose timer...");
lock (syncObject)
{
if (timer == null)
{
return;
}
timer.Change(Timeout.Infinite, Timeout.Infinite);
timer.Dispose();
timer = null;
Debug.WriteLine("Timer disposed...");
}
}
private void InitializeStartTimer()
{
Debug.WriteLine("Initialize start timer...");
lock (syncObject)
{
startTimer = new Timer(Timer_Elapsed, null, DurationStartLongPress, Timeout.Infinite);
}
}
private void InitializeNextTimer()
{
Debug.WriteLine("Initialize next timer...");
lock (syncObject)
{
if (startTimer != null)
DeInitializeTimer(ref startTimer);
nextTimer = new Timer(Timer_Elapsed, null, DurationNextLongPress, DurationNextLongPress);
}
}
#endregion
}
问题场景: 我们有 2 个带有向上和向下箭头的按钮来增加和减少值。我们也有最小值和最大值的限制。按钮为白色。
- 用户触摸按钮
- 按下事件被调用,计时器被初始化
- 我在小于maksimum(执行的命令)时增加值。如果 value 有一个 maxsimum,我将 IsEnabled 设置为 false
- Release 事件不会被调用(即使用户释放按钮),而是我手动调用 PropagateUpReleased Android 上的渲染器
- 按钮是浅灰色
- 触摸向下按钮
- 现在值小于最大值,我将按钮 IsEnabled 设置为 true,按钮背景为深灰色(与我们触摸按钮相同)
I had problem with android image button background. I had implementation of long press on image button based on Pressed/Released events. First problem was with Released event when I disabled button. I resolve it by call PropagateUpReleased, on iOS it is enough, but on android I had problem that when I set button to enabled again I had a background of button like it was pressed:
- long press on up arrow, button have dark gray color
- get the maximum, set button to disabled
- propagate release button
- release of ImageButton (XamarinForms) is call
- disabled button have light gray color
- click on down arrow, up arrow set to enabled, background color is dark gray
My implementation of ImageButtonRenderer:
public CustomButtonRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(Button.IsEnabled) && !Element.IsEnabled && Element.IsPressed)
{
PropagateRelease();
}
}
public override bool OnTouchEvent(MotionEvent e)
{
if (e.Action == MotionEventActions.Cancel)
PropagateRelease();
return base.OnTouchEvent(e);
}
private void PropagateRelease()
{
Element.PropagateUpReleased();
((IButtonController)Element).SendReleased();
Invalidate();
PostInvalidate();
}
Edit:
This is my implementation of behavior:
public class LongPressBehavior : Behavior<ImageButton>
{
private readonly object syncObject = new object();
private const int DurationStartLongPress = 500;
private const int DurationNextLongPress = 150;
private ImageButton button;
private Timer startTimer;
private Timer nextTimer;
private volatile bool isReleased;
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command),
typeof(ICommand), typeof(LongPressBehavior), default(ICommand));
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
#region Cnt
public LongPressBehavior()
{
isReleased = true;
}
#endregion
#region LifeCycles
protected override void OnAttachedTo(ImageButton button)
{
this.button = button;
base.OnAttachedTo(button);
this.BindingContext = button.BindingContext;
button.Pressed += Button_Pressed;
button.Released += Button_Released;
}
protected override void OnDetachingFrom(ImageButton button)
{
base.OnDetachingFrom(button);
this.BindingContext = null;
button.Pressed -= Button_Pressed;
button.Released -= Button_Released;
}
#endregion
#region Events
private void Button_Pressed(object sender, EventArgs e)
{
Debug.WriteLine("Pressed...");
isReleased = false;
InitializeStartTimer();
}
private void Button_Released(object sender, EventArgs e)
{
Debug.WriteLine("Released...");
isReleased = true;
DeInitializeTimer(ref startTimer);
DeInitializeTimer(ref nextTimer);
}
protected virtual void OnLongPressed()
{
if (button.Command != null)
{
Debug.WriteLine("Longpress execute...");
button.Command.Execute(null);
}
if (nextTimer == null)
InitializeNextTimer();
}
private void Timer_Elapsed(object state)
{
if (isReleased)
{
return;
}
Device.BeginInvokeOnMainThread(OnLongPressed);
}
#endregion
#region Private methods
private void DeInitializeTimer(ref Timer timer)
{
Debug.WriteLine("Dispose timer...");
lock (syncObject)
{
if (timer == null)
{
return;
}
timer.Change(Timeout.Infinite, Timeout.Infinite);
timer.Dispose();
timer = null;
Debug.WriteLine("Timer disposed...");
}
}
private void InitializeStartTimer()
{
Debug.WriteLine("Initialize start timer...");
lock (syncObject)
{
startTimer = new Timer(Timer_Elapsed, null, DurationStartLongPress, Timeout.Infinite);
}
}
private void InitializeNextTimer()
{
Debug.WriteLine("Initialize next timer...");
lock (syncObject)
{
if (startTimer != null)
DeInitializeTimer(ref startTimer);
nextTimer = new Timer(Timer_Elapsed, null, DurationNextLongPress, DurationNextLongPress);
}
}
#endregion
}
Problem scenerio:
We have 2 buttons with arrow up and down to increase and decrease value. Also we have limits of value min and max. Buttons have a white color.
- user touch up button
- pressed event is call, timer is initialize
- I increase the value while is less than maksimum (executed command). If value have a maksimum I set IsEnabled to false
- Release event is not call (even if user release button) , instead I call manually PropagateUpReleased in renderer
- button on android is light gray
- touch to down button
- now value is less than max, I set up button IsEnabled to true, background of button is dark gray (the same like we touch button)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论