c# - 在 Android 和 iOS 上点击自定义按钮时实现“突出显示效果”而不是“涟漪效果”
问题描述
我的Xamarin.Forms
应用程序中有一个通过继承ContentView
类创建的自定义按钮,并且希望在点击此自定义视图时实现类似于 iOS 平台的“突出显示效果”(如图所示)。
我知道,在 Android 平台上,可以通过创建特定于自定义视图的自定义渲染器并将RippleDrawable
对象添加到本机控件,在自定义视图中实现特定于 Android 的波纹效果,如下所示:
class CustomButtonRenderer
: ViewRenderer
<CustomButton,
Android.Views.View>
{
public DescriptiveButtonRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<CustomButton> e)
{
LayoutInflater viewInflater;
Android.Views.View view;
GradientDrawable drawnBackground;
StateListDrawable drawableStateList;
RippleDrawable drawableRippleEffect;
base.OnElementChanged(e);
if (this.Control == null)
{
// Implement the Android specific resource pertaining to
// the Android specific XML layout of the custom button
viewInflater = (LayoutInflater)this.Context
.GetSystemService(
Context
.LayoutInflaterService);
view = viewInflater.Inflate
(Resource.Layout.CustomButton,
null,
false);
// For ripple effect
drawnBackground = new GradientDrawable
(GradientDrawable.Orientation.LeftRight,
new int[] {
this.Element.BackgroundColor.ToAndroid(),
this.Element.BackgroundColor.ToAndroid()
});
drawableStateList = new StateListDrawable();
drawableRippleEffect = new RippleDrawable
(ColorStateList.ValueOf
(Android.Graphics.Color.White),
drawnBackground,
null);
drawableStateList.AddState
(new int[] {
Android.Resource
.Attribute.StateEnabled },
drawableRippleEffect);
view.Background = drawableStateList;
this.SetNativeControl(view);
}
}
}
不幸的是,不能使用与上述解决方案类似的方法,因为在 API 库中没有促进“突出显示效果”的类。
我还知道,在 Android 平台中,可以通过实现类似于下面的自定义渲染来从 Button 中移除涟漪效果,该渲染将null
值设置StateListAnimator
为原生控件的属性,如下所示:
class ButtonCustomRenderer
: ButtonRenderer
{
public ButtonCustomRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
// Remove the ripple effect
if (this.Control != null && e.NewElement != null)
{
if (Build.VERSION.SdkInt > BuildVersionCodes.Lollipop)
this.Control.StateListAnimator = null;
else
this.Control.Elevation = 0;
}
}
}
为了使用上述方法,我查看了与类型相关的内置动画师,Android.Animation.StateListAnimator
但找不到任何满足要求的动画师。
关于这个问题的解决方案,我最初的也是唯一的直觉是在按下或点击视图时手动将视图的背景颜色更改为“突出显示的颜色”,但是,我相信这不是一个优雅的解决方案,因为它从自定义按钮的背景颜色模拟原生的“突出显示颜色”非常费劲。
提前致谢。
解决方案
在 Android 中,您只需使用选择器动画设置按钮背景。
在你的创建一个highlightbutton.xmlResources/drawable
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--press-->
<item android:state_pressed="true" android:state_enabled="true">
<shape >
<solid android:color="#c00"/>
</shape>
</item>
<!--normal-->
<item android:state_pressed="false" android:state_enabled="false">
<shape >
<solid android:color="#f00"/>
</shape>
</item>
</selector>
然后在您的 customrenderer 中:
class ButtonCustomRenderer
: ButtonRenderer
{
public ButtonCustomRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (this.Control != null && e.NewElement != null)
{
Control.SetBackgroundResource(Resource.Drawable.highlightbutton);
}
}
}
推荐阅读
- microsoft-graph-api - 使用 MsGraph 搜索特定 contentType 的 sharePoint
- python - ValueError:检查目标时出错:预期 c_acti 的形状为 (10,) 但得到的数组的形状为 (1,)
- objective-c - 如何使用 NSTask 检查是否安装了特定的包
- dart - 在 Flutter 中,iconButton 是在 appBar 中单击,但错误即将到来
- python - pyqt5 应用程序中的嵌入式 qtconsole 无法按预期工作
- azure-devops - 使用“SQL Server 数据库部署”任务部署 DACPAC 时未找到 TMP 文件异常
- java - java.sql.SQLException:未找到列“等级”
- c++ - 有没有办法将“内联”关键字的两个含义分开(ODR 放松与功能代码内联)
- c - 在 GLib N-ary 树中查找节点
- c++ - Qt:在析构函数中删除 QMainWindow 的中央小部件时程序崩溃