Xamarin.Forms ScrollView - оживляет его рост по мере расширения - PullRequest
0 голосов
/ 29 марта 2019

У нас есть 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 голосов
/ 03 апреля 2019

Пользователь yelinzh на форумах Xamarin опубликовал разумный ответ:

Как насчет попытки использовать Custom Renderer, например эффект затухания.

[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;
        }
    }
}

Это, вероятно, сработает. На самом деле у нас есть другой подход (после обратной связи с клиентом), где мы держим текущий вопрос в верхней части экрана и прокручиваем вверх, чтобы контент больше не расширялся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...