首页 > 解决方案 > 在 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但找不到任何满足要求的动画师。

关于这个问题的解决方案,我最初的也是唯一的直觉是在按下或点击视图时手动将视图的背景颜色更改为“突出显示的颜色”,但是,我相信这不是一个优雅的解决方案,因为它从自定义按钮的背景颜色模拟原生的“突出显示颜色”非常费劲。

提前致谢。

标签: c#androidiosxamarinxamarin.forms

解决方案


在 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);
        }
    }
}

推荐阅读