Xamarin.Forms ScrollView-在扩展时动画化其增长

时间:2019-03-29 10:33:45

标签: animation xamarin.forms

我们有一个ScrollView,我将它的VerticalOptions设置为“ End”,因此当我们在运行时向其添加内容时,它会从底部开始“生长”。

添加带有动画的内容时,我们将滚动到最后。当ScrollView已满并且实际上正在滚动时,这看起来不错。

但是,将内容添加到ScrollView时,新内容将立即显示而没有动画。

关于添加新内容时如何动画化ScrollView的任何想法?理想情况下,我希望它向上滑动,就像它充满时的动画滚动一样。

如果相关,我们正在使用RepeaterView作为ScrollView的内容。

下面相关的现有代码(我们将窗体与MvvmCross一起使用-因此是MVVM模式):

ViewModel

    private async Task NextClick()
    {

        var claimFlowQuestion = await GetClaimFlowQuestion(_currentIndexQuestion);

        Questions.Add(ClaimFlowExtendFromClaimFlow(claimFlowQuestion));

        // Trigger PropertyChanged so the Repeater updates
        await RaisePropertyChanged(nameof(Questions));

        // Trigger the QuestionAdded event so the ScrollView can scroll to the bottom (initiated in the xaml.cs code behind)
        QuestionAdded?.Invoke(this, new EventArgs());

    }

XAML

        <ScrollView  Grid.Row="1" x:Name="QuestionScrollView">
            <StackLayout VerticalOptions="End"
                Padding  ="10,0,10,0"
                IsVisible="{Binding Busy, Converter={StaticResource InvertedBooleanConvertor}}}">
                <controls:RepeaterView
                    x:Name="QuestionRepeater"
                    Margin      ="10"
                    AutomationId="IdQuestions"
                    Direction   ="Column"
                    ItemsSource ="{Binding Questions}"
                    ClearChild  ="false">
                    <controls:RepeaterView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <controlsClaimFlowControls:QuestionBlock
                                    Margin             ="0,20,0,20"
                                    QuestionNumber     ="{Binding Index}"
                                    QuestionText       ="{Binding QuestionText}"
                                    QuestionDescription="{Binding QuestionDescription}"
                                    ItemsSource        ="{Binding Source}"
                                    DisplayMemberPath  ="{Binding DisplayPaths}"
                                    QuestionType       ="{Binding QuestionType}"
                                    SelectedItem       ="{Binding Value}"
                                    IsEnabledBlock     ="{Binding IsEnabled}" />
                            </ViewCell>
                        </DataTemplate>
                    </controls:RepeaterView.ItemTemplate>
                </controls:RepeaterView>
            </StackLayout>
        </ScrollView>

XAML.cs

    protected override void OnAppearing()
    {
        if (BindingContext != null)
        {
            MedicalClaimConditionPageModel model = (MedicalClaimConditionPageModel)this.BindingContext.DataContext;

            model.QuestionAdded += Model_QuestionAdded;
        }

        base.OnAppearing();
    }

    protected override void OnDisappearing()
    {
        MedicalClaimConditionPageModel model = (MedicalClaimConditionPageModel)this.BindingContext.DataContext;

        model.QuestionAdded -= Model_QuestionAdded;
        base.OnDisappearing();
    }

    void Model_QuestionAdded(object sender, EventArgs e)
    {
        Device.BeginInvokeOnMainThread(async () =>
        {
            if (Device.RuntimePlatform == Device.iOS)
            {
                // We need a Task.Delay to allow the contained controls to repaint and have their new sizes
                // Ultimately we should come up with a better resolution  - the delay value can vary depending on device and OS version.

                await Task.Delay(50);
            }

            await QuestionScrollView.ScrollToAsync(QuestionRepeater, ScrollToPosition.End, true);
        });

    }

1 个答案:

答案 0 :(得分:0)

用户yelinzh在Xamarin论坛上发布了一个合理的答案:

  

如何尝试使用自定义渲染器(例如淡入淡出效果)。

[assembly: ExportRenderer(typeof(ScrollView_), typeof(ScrollViewR))]
namespace App3.Droid
{
    public class ScrollViewR : ScrollViewRenderer
    {
        public ScrollViewR(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            this.SetFadingEdgeLength(300);
            this.VerticalFadingEdgeEnabled = true;
        }
    }
}
     

这可能会起作用。实际上,我们需要另一种方法 (根据客户的反馈),我们将当前问题保留在屏幕顶部并向上滚动,因此内容不再扩展。