Animate to a specific slide

4 posts, 1 answers
  1. Efthymios
    Efthymios avatar
    17 posts
    Member since:
    Apr 2012

    Posted 30 Apr 2014 Link to this post

    Hello.

    Currently RadSlideView has 2 methods. These are:

    MoveToPreviousItem and MoveToNextItem

    Also, it has the property SelectedItem.

    Unfortunately, if the SlideView is on the 1st slide and the application wants to slide on the 4th, you have to do something like the following:

    slideView.SelectedItem = my4thSlide;

    The problem with that approach is that the application does not slide to the 4th slide but it just displays it straight away (without any kind of animation). I have tried a lot of approaches to animate it, one of them was to use the SlideAnimationCompleted event to advance to the next and the next and the next page like the following:

    void mySlideAnimationCompleted(object sender, EventArgs e)
            {

                int iCur = GetSelectedSlideIndex();

                if (iGoingToSlide == iCur)
                {
                    mySlideView.SlideAnimationCompleted -= mySlideAnimationCompleted;
                    return;
                }

                if (iGoingToSlide < iCur)
                    mySlideView.MoveToPreviousItem(true);
                else
                    mySlideView.MoveToNextItem(true);
            }

    The problem with that approach is that the slide animation (eg. from the 1st to the 4th slide) is not very good (probably because of the acceleration/deceleration of the slide speed from the 1st to the 2nd, from the 2nd to the 3rd and go on.

    Is it any way that I can somehow override that animation behavior?
    Does Telerik have any thoughts of creating a function like MoveToSpecificItem?

    Thank you very much.

    Efthymios Kalyviotis
  2. Answer
    Ivaylo Gergov
    Admin
    Ivaylo Gergov avatar
    661 posts

    Posted 05 May 2014 Link to this post

    Hi,

    This scenario is not support by the RadSlideView control out of the box. However I've come up with a possible workaround but it is a bit tricky. Here is what I suggest:
    1. In the SelectionChanged event handler as in your example you can track if the selection is executed after a sliding has been made or when you trigger it explicitly.
    2. Then you can select an item that is on the previous/next position of the item that you want to select and invoke the MoveToPreviousItem() / MoveToNextItem() method which will trigger the desired slide animation. 
    For your convenience I have prepared a sample project that demonstrate this. Please see the attached file.

    Let me know if this helps you and should you need further assiatance.


    Regards,
    Ivaylo Gergov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. DevCraft banner
  4. Efthymios
    Efthymios avatar
    17 posts
    Member since:
    Apr 2012

    Posted 05 May 2014 in reply to Ivaylo Gergov Link to this post

    Hello Ivaylo.

    Thank you very much for your reply. This is actually slightly better solution than the one I have taken by using the SlideAnimationCompleted event handler.
    On the weekend I have downloaded the source code of the controls and played with it and I found that it should be quite straightforward for something like that to be implemented in them. Unfortunately I didn't go with the solution of changing the source code because in a later update of the controls I would have lost that functionality again. Just to let you know, I write down the changes that I have done if you are interested in implementing something like this in later versions of the controls.

    SlideViewManipulationBehavior.cs
    Created the bellow function:
    internal virtual void MoveBy(int iSlidesNum)
            {
            }

    RadSlideView.cs
    Created the bellow function:
    /// <summary>
            /// Moves an amount of slides in the sequence.
            /// </summary>
            /// <param name="amount">Amount of slides to move left or right (negative or positive number).</param>
            /// <param name="animate">True to perform a transition, false otherwise.</param>
            /// <returns>True if a next item exists, false otherwise.</returns>
            public bool MoveBy(int amount, bool animate = true)
            {
                IDataSourceItem item = this.selectedDataSourceItem;
                for (int i = 0; i < Math.Abs(amount); ++i)
                    item = Math.Sign(amount) < 0 ? this.GetNextDataSourceItem(item) : this.GetPreviousDataSourceItem(item);
     
                if (item == null)
                {
                    return false;
                }
     
                if (animate && this.manipulationBehavior != null && this.IsLoaded)
                {
                    this.manipulationBehavior.MoveBy(amount);
                }
                else
                {
                    this.selectedDataSourceItem = item;
                    this.ChangePropertySilently(SelectedItemProperty, this.selectedDataSourceItem.Value);
                    if (this.itemsPanel != null)
                    {
                        this.itemsPanel.InvalidateUI();
                    }
                }
     
                return true;
            }

    ​SlideManipulationBehavior.cs
    Created the following two functions:
    private void PerformFlickByAmount(int amount, bool changeSelection)
            {
                Debug.WriteLine("SlideBehaviour: PerformFlickByAmount");
     
                this.View.isPanInProgress = false;
     
                double to = 0;
                if (changeSelection)
                {
                    // we have made enough offset to move to the previous/next item
                    this.itemToSelect = this.View.SelectedDataSourceItem;
                    for (int i = 0; i < Math.Abs(amount); ++i)
                        this.itemToSelect = Math.Sign(amount) < 0 ? this.View.GetNextDataSourceItem(this.itemToSelect) : this.View.GetPreviousDataSourceItem(this.itemToSelect);
     
                    this.View.ChangeSelectedItem(this.itemToSelect, false);
                    to = this.Panel.ItemLength * amount;
                    //this.Panel.OnSelectionAnimationStarted(amount);
                }
     
                this.AnimateSlide(to);
            }
     
            internal override void MoveBy(int iSlidesNum)
            {
                if (this.AnimationState != SlideViewAnimationState.None)
                {
                    return;
                }
     
                this.PerformFlickByAmount(iSlidesNum, true);
            }

    In the PerformFlickByAmount function I commented out the line:
    //this.Panel.OnSelectionAnimationStarted(amount);

    Inside that function it has the command
    this.sign = sign;
    that messes with the animation if the sign is not 0.

    I hope that the above might help you in case you are interested in implementing something like this inside the controls.

    Best regards

    Efthymios Kalyviotis

  5. Ivaylo Gergov
    Admin
    Ivaylo Gergov avatar
    661 posts

    Posted 08 May 2014 Link to this post

    Hi,

    I have added this as a feature request in our backlog. Also, great job with the implementation of the feature. We will definitely take advantage of your feedback. Consequently I have added 1000 Telerik points to your account.

    Thanks for your time and feedback.

    Regards,
    Ivaylo Gergov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top