第二十七章:自定义渲染器(六)-阿里云开发者社区

开发者社区> 云计算> 正文

第二十七章:自定义渲染器(六)

简介: 有趣的是,Android SeekBar小部件具有与Steps属性等效的功能,但不等同于Minimum和Maximum属性! 这怎么可能? SeekBar实际上定义了一个名为Max的整数属性,SeekBar的Progress属性始终是一个从0到Max的整数。

有趣的是,Android SeekBar小部件具有与Steps属性等效的功能,但不等同于Minimum和Maximum属性! 这怎么可能? SeekBar实际上定义了一个名为Max的整数属性,SeekBar的Progress属性始终是一个从0到Max的整数。 因此,Max属性确实指示了SeekBar可以执行的步骤数,并且SeekBar的Progress属性和StepSlider的Value属性之间需要进行转换。
此转换发生在两个地方:SetValue方法从StepSlider的Value属性转换为SeekBar的Progress属性,OnProgressChanged方法从SeekBar的Progress属性转换为StepSlider的Value属性。
另外,事件处理程序有点不同。 SetOnSeekBarChangeListener方法接受类型为IOnSeekBarChangeListener的参数,该参数定义了三个报告Seekbar更改的方法,包括方法OnProgressChanged。 渲染器本身实现了该接口。
这是Xamarin.FormsBook.Platform.Android库中的完整StepSliderRenderer类:

using System.ComponentModel;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Xamarin.FormsBook.Platform.StepSlider),
                          typeof(Xamarin.FormsBook.Platform.Android.StepSliderRenderer))]
namespace Xamarin.FormsBook.Platform.Android
{
    public class StepSliderRenderer : ViewRenderer<StepSlider, SeekBar>,
                                      SeekBar.IOnSeekBarChangeListener
    {
        double minimum, maximum;
        protected override void OnElementChanged(ElementChangedEventArgs<StepSlider> args)
        {
            base.OnElementChanged(args);
            if (Control == null)
            {
                SetNativeControl(new SeekBar(Context));
            }
            if (args.NewElement != null)
            {
                SetMinimum();
                SetMaximum();
                SetSteps();
                SetValue();
                Control.SetOnSeekBarChangeListener(this);
            }
            else
            {
                Control.SetOnSeekBarChangeListener(null);
            }
        }
        protected override void OnElementPropertyChanged(object sender,
                                                         PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(sender, args);
            if (args.PropertyName == StepSlider.MinimumProperty.PropertyName)
            {
                SetMinimum();
            }
            else if (args.PropertyName == StepSlider.MaximumProperty.PropertyName)
            {
                SetMaximum();
            }
            else if (args.PropertyName == StepSlider.StepsProperty.PropertyName)
            {
                SetSteps();
            }
            else if (args.PropertyName == StepSlider.ValueProperty.PropertyName)
            {
                SetValue();
            }
        }
        void SetMinimum()
        {
            minimum = Element.Minimum;
        }
        void SetMaximum()
        {
            maximum = Element.Maximum;
        }
        void SetSteps()
        {
            Control.Max = Element.Steps;
        }
        void SetValue()
        {
            double value = Element.Value;
            Control.Progress = (int)((value - minimum) / (maximum - minimum) * Element.Steps);
        }
        // Implementation of SeekBar.IOnSeekBarChangeListener
        public void OnProgressChanged(SeekBar seekBar, int progress, bool fromUser)
        {
            double value = minimum + (maximum - minimum) * Control.Progress / Control.Max;
            ((IElementController)Element).SetValueFromRenderer(StepSlider.ValueProperty, value);
        }
        public void OnStartTrackingTouch(SeekBar seekBar)
        {
        }
        public void OnStopTrackingTouch(SeekBar seekBar)
        {
        }
    }
}

StepSliderDemo解决方案包含指向Xamarin.FormsBook.Platform库的链接以及对这些库的相应引用。 StepSliderDemo.xaml文件实例化五个StepSlider元素,其中三个是数据绑定,另外两个是显式事件处理程序:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:platform=
                 "clr-namespace:Xamarin.FormsBook.Platform;assembly=Xamarin.FormsBook.Platform"
             x:Class="StepSliderDemo.StepSliderDemoPage">
    <StackLayout Padding="10, 0">
        <StackLayout.Resources>
            <ResourceDictionary>
                <Style TargetType="ContentView">
                    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                </Style>
                <Style TargetType="Label">
                    <Setter Property="FontSize" Value="Large" />
                    <Setter Property="HorizontalOptions" Value="Center" />
                </Style>
            </ResourceDictionary>
        </StackLayout.Resources>
        <ContentView>
            <StackLayout>
                <platform:StepSlider x:Name="stepSlider1" />
                <Label Text="{Binding Source={x:Reference stepSlider1},
                                      Path=Value}" />
            </StackLayout>
        </ContentView>
        <ContentView>
            <StackLayout>
                <platform:StepSlider x:Name="stepSlider2"
                                     Minimum="10"
                                     Maximum="15"
                                     Steps="20"
                                     ValueChanged="OnSliderValueChanged" />
                <Label x:Name="label2" />
            </StackLayout>
        </ContentView>
        <ContentView>
            <StackLayout>
                <platform:StepSlider x:Name="stepSlider3"
                                     Steps="10" />
                <Label Text="{Binding Source={x:Reference stepSlider3},
                                      Path=Value}" />
            </StackLayout>
        </ContentView>
        <ContentView>
            <StackLayout>
                <platform:StepSlider x:Name="stepSlider4"
                                     Minimum="0"
                                     Maximum="1"
                                     Steps="100"
                                     ValueChanged="OnSliderValueChanged" />
                <Label x:Name="label4" />
            </StackLayout>
        </ContentView>
        <ContentView>
            <StackLayout>
                <platform:StepSlider x:Name="stepSlider5"
                                     Minimum="10"
                                     Maximum="20"
                                     Steps="2" />
                <Label Text="{Binding Source={x:Reference stepSlider5},
                                      Path=Value}" />
            </StackLayout>
        </ContentView>
    </StackLayout>
</ContentPage>

代码隐藏文件具有ValueChanged事件处理程序:

public partial class StepSliderDemoPage : ContentPage
{
    public StepSliderDemoPage()
    {
        InitializeComponent();
    }
    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        StepSlider stepSlider = (StepSlider)sender;
        if (stepSlider == stepSlider2)
        {
            label2.Text = stepSlider2.Value.ToString();
        }
        else if (stepSlider == stepSlider4)
        {
            label4.Text = stepSlider4.Value.ToString();
        }
    }
}

您会发现StepSlider的功能类似于普通的Xamarin.Forms Slider,只是StepSlider中的可能值现在处于程序控制之下:
2019_06_21_094010
第一个StepSlider的增量值为1,第二个增量为0.25,第三个增量为10,第四个增量为0.01,第五个增量为5,只有三个可能的设置。
现在你可以看到Xamarin.Forms如何提供工具,让你超越它最初的样子。 您可以在三个平台中定义的任何内容都可以在一个通用平台中成为可用的东西。 使用C#编程语言,以及Xamarin.Forms和渲染器的强大功能,您不仅可以进入iOS编程,Android编程或Windows编程,而且只需一步即可完成三个步骤,并继续迈向未来 移动开发。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
云计算
使用钉钉扫一扫加入圈子
+ 订阅

时时分享云计算技术内容,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

其他文章