Adding Animation to Accordion ListView

So, I just started learning about animation in Xamarin. I read the documentation and want to try implementing it. Because I’m new at this stuff, I wanna start with something simple. I modified one of my old post about accordion list view by adding little animation to it. If you’ve read that post, you will know that when I expand the list view, I changed the down arrow icon to up arrow icon. And when I collapse the list view, I do the otherwise. The icon changing process just happen as it is, without any effect or animation on it. I want to change that. I want to add a rotate animation when the icon changing happen. So, let’s do that.

Image Gesture Recognizer

First thing we need to is switching the trigger of expanding list view event. Back then I used List View Item Tapped event, but now, because I want to rotate the arrow icon, I need to put the trigger in Image view where the arrow icon is. So, I add Image Gesture Recognizer to the Image view. It’s look like this.

animated accordion

With this gesture recognizer, I can get the current Image view being tapped by user so I can handle it properly in code behind. In code behind, all I need to is just rotate the image and call function in view model to expand or collapse the list view. I rotate the image 180 degree and for 0,5 second.

public partial class AccordionCountriesPage : ContentPage
{
    AccordionCountriesViewModel viewModel;
    public AccordionCountriesPage()
    {
        InitializeComponent();
        BindingContext = viewModel = new AccordionCountriesViewModel();
    }

    void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        //Country mCountry = (Country)e.Item;
        //viewModel.ShowCities(mCountry);
        ListView listView = sender as ListView;
        listView.SelectedItem = null;
    }

    async void Handle_Tapped(object sender, EventArgs e)
    {
        Image image = sender as Image;
        await image.RotateTo(180, 500);
        Grid grid = image.Parent as Grid;
        Label label = grid.Children[0] as Label;
        viewModel.ShowCities(label.Text);
    }
}

A little bit downside from this method is I don’t get the whole Country class like I did when I was using List View Item Tapped. But I’m still able to know which country user tapped by accessing the label which contain the country’s name. By doing this, it means I also need little modification to the view model as well. This is how the view model look like now. I only updated the ShowCities method.

public class AccordionCountriesViewModel : BaseViewModel
{
    private CustomObservableCollection countries;
    public CustomObservableCollection Countries
    {
        get => countries;
        set => SetProperty(ref countries, value);
    }

    public AccordionCountriesViewModel()
    {
        ObservableCollection USACities = new ObservableCollection()
        {
            new City(){ CityName = "Washington DC" },
            new City(){ CityName = "New York" },
            new City(){ CityName = "Los Angeles" }
        };

        ObservableCollection ChinaCities = new ObservableCollection()
        {
            new City(){ CityName = "Beijing" },
            new City(){ CityName = "Shanghai" },
            new City(){ CityName = "Shenzhen" }
        };

        ObservableCollection RussiaCities = new ObservableCollection()
        {
            new City(){ CityName = "Moscow" },
            new City(){ CityName = "St. Peterburg" },
            new City(){ CityName = "Kazan" }
        };

        countries = new CustomObservableCollection()
        {
            new Country(){ CountryName = "USA", IsChildrenVisible = false, Cities = USACities },
            new Country(){ CountryName = "China", IsChildrenVisible = false, Cities = ChinaCities },
            new Country(){ CountryName = "Russia", IsChildrenVisible = false, Cities = RussiaCities },
        };
    }

    public void ShowCities(string countryName)
    {
        Country country = Countries.SingleOrDefault(c => c.CountryName == countryName);
        country.IsChildrenVisible = !country.IsChildrenVisible;
        Countries.ReportItemChange(country);
    }
}

Let’s rotate it!

Nah, now we can run the project again and see how our arrow rotating.

 

Credit :

  • Arrow Icons from FlatIcon, Down Arrow icon by Freepik, Right Arrow icon by GraphicsBay, Up Arrow icon by Hadrien

3 thoughts on “Adding Animation to Accordion ListView

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s