Search code examples
c#xamarin.formsmultiple-columnsgrid-layoutcollectionview

Changing the span of CollectionView while rotating phone isn't working


I'm trying to change the span of CollectionView while rotating my iPhone. To make it easy, just show 2 columns in portrait, and 4 columns in landscape. It works when rotating from portrait to landscape mode, but when rotating back to portrait mode, it always shows 1 column. My code likes,

    VideoCollectionView = new CollectionView()
        {
            ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical),
        };
    ...

    private static double screen_width = 1280.0;
    private static double screen_height = 720.0;

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);

        if ((Math.Abs(screen_width - width) > minimum_double) || (Math.Abs(screen_height - height) > minimum_double))
        {
            screen_width = width;
            screen_height = height;

            int split;
            if (screen_width > screen_height)
            {   // landscape mode
                split = 4;
            }
            else
            {   // portrait mode
                split = 2;
            }

            VideoCollectionView.ItemsLayout = new GridItemsLayout(split, ItemsLayoutOrientation.Vertical);
        }
    }

Is this a bug? Or I should use other ways? Thanks for help.


Solution

  • You could use a Singleton for storing the current orientation.Because it is unwise to set the screen size as s static value . It maybe will cause issue on different size of device .

    public class CurrentDevice
    {
        protected static CurrentDevice Instance;
        double width;
        double height;
    
        static CurrentDevice()
        {
            Instance = new CurrentDevice();
        }
        protected CurrentDevice()
        {
        }
    
        public static bool IsOrientationPortrait()
        {
            return Instance.height > Instance.width;
        }
    
        public static void SetSize(double width, double height)
        {
            Instance.width = width;
            Instance.height = height;
        }
    }
    

    And in the method

    protected override void OnSizeAllocated(double width, double height)
    {
       base.OnSizeAllocated(width, height);
    
    
       if (CurrentDevice.IsOrientationPortrait() && width > height || !CurrentDevice.IsOrientationPortrait() && width < height)
       {
          int split;
          CurrentDevice.SetSize(width, height);
    
          // Orientation got changed! Do your changes here
          if (CurrentDevice.IsOrientationPortrait())
          {
             // portrait mode
             split = 2;
          }
    
          else
          {
             // landscape mode
             split = 4;
          }
    
          VideoCollectionView.ItemsLayout = new GridItemsLayout(split, ItemsLayoutOrientation.Vertical);
       }
    
    
    }