Forum Xamarin.Android
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to display toast message below icon that is tapped in Android ?

I'm using Xamarin Forms, I tried to display Top, Center screen.

This my code for AndroidOS:
public void Show(string message, VisualElement visualElement) { Toast toast = Toast.MakeText(Forms.Context, message, ToastLength.Short); toast.SetGravity(Gravity.GetAbsoluteGravity(GravityFlags.Top, GravityFlags.Center), 0, 0); toast.Show(); }

But how to get position X/Y to display toast message at below icon that is tapped ?
Thank you!

Best Answer

  • PhamThanhTongPhamThanhTong USMember ✭✭
    Accepted Answer

    @AlvinKwek Yes. I'm using Xamarin.Forms.

    I investigated and solved my problem by using DependencyService.

    **On forms:
    namespace myapplication
    {
    public class Toast
    {
    public static void Show(string message)
    {
    DependencyService.Get().Show(message);
    }

        public static void Show(string message, VisualElement visualElement)
        {
            DependencyService.Get<IToast>().Show(message, visualElement);
        }
    
        public static void Show(string message, ToastPosition position)
        {
            DependencyService.Get<IToast>().Show(message, position);
        }
    }
    
    public interface IToast
    {
        void Show(string message);
        void Show(string message, ToastPosition position);
        void Show(string message, VisualElement visualElement);
    }
    
    public enum ToastPosition
    {
        Top,
        Center,
        Bottom
    }
    

    }

    **On Android:

    [assembly: Dependency(typeof(ToastDroid))]
    namespace myapplication.AndroidOS
    {
    public class ToastDroid : IToast
    {
    private Toast toast;
    public void Show(string message)
    {
    ShowToast(message, ToastPosition.Center);
    }

        public void Show(string message, VisualElement visualElement)
        {
            ShowToast(message, ToastPosition.Bottom, visualElement);
        }
    
        public void Show(string message, ToastPosition position)
        {
            ShowToast(message, position);
        }
    
        void ShowToast(string message, ToastPosition position, VisualElement visualElement = null)
        {
            if (toast != null)
            {
                toast.Cancel();
                toast = null;
            }
            if (visualElement != null && position != ToastPosition.Center)
            {
                const int MARGIN = 15;
                int x = 0;
                int y = 0;
                Rectangle element = GetElementFrame(visualElement);
                element.X += element.Width / 2;
    
                var rectangle = new Rect();
                var act = Forms.Context as Activity;
                Window window = act.Window;
                window.DecorView.GetWindowVisibleDisplayFrame(rectangle);
                int statusBarHeight = rectangle.Top;
    
                switch (position)
                {
                    case ToastPosition.Top:
                        break;
                    case ToastPosition.Bottom:
                        element.Y += (element.Height + UnitSizeUtil.ToPixel(MARGIN, Android.App.Application.Context.Resources.DisplayMetrics));
                        if (NavigationPage.GetHasNavigationBar(visualElement))
                        {
                            if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                            {
                                element.Y += statusBarHeight;
                            }
                        }
                        break;
                }
                x = UnitSizeUtil.ToPixel(Convert.ToInt32(element.X), Forms.Context.Resources.DisplayMetrics);
                y = UnitSizeUtil.ToPixel(Convert.ToInt32(element.Y), Forms.Context.Resources.DisplayMetrics);
    
                //This is a temporary solution to calculate the position of toast message.
                const float CHARACTER_TO_PIXEL = 2.9f;
                const int SPACE_ON_BOTH_SIDES_OF_TOAST = 34;
                int messageLength = UnitSizeUtil.ToPixel(Convert.ToInt32(message.Length * CHARACTER_TO_PIXEL) + SPACE_ON_BOTH_SIDES_OF_TOAST, Forms.Context.Resources.DisplayMetrics);
                x -= messageLength;
    
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                toast.SetGravity(GravityFlags.Top | GravityFlags.Left, x, y);
            }
            else
            {
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                if (position == ToastPosition.Center)
                {
                    toast.SetGravity(GravityFlags.Center | GravityFlags.CenterHorizontal, 0, 0);
                }
                else if (position == ToastPosition.Bottom)
                {
                    toast.SetGravity(GravityFlags.Bottom | GravityFlags.Center, 0, 0);
                }
            }
            toast.Show();
        }
    
        Rectangle GetElementFrame(VisualElement visualElement)
        {
            Rectangle element = new Rectangle(visualElement.X, visualElement.Y, visualElement.Width, visualElement.Height);
            if (visualElement.ParentView != null)
            {
                Rectangle parentElement = GetElementFrame(visualElement.ParentView);
                element.X += parentElement.X;
                element.Y += parentElement.Y;
                if (visualElement.ParentView is Xamarin.Forms.ScrollView)
                {
                    var scrollView = visualElement.ParentView as Xamarin.Forms.ScrollView;
                    element.X -= scrollView.ScrollX;
                    element.Y -= scrollView.ScrollY;
                }
            }
            return element;
        }
    }
    

    }

    Hope it helps someone!

Answers

  • AlvinKwekAlvinKwek USMember ✭✭

    How can I do it in C#?

  • PhamThanhTongPhamThanhTong USMember ✭✭

    @AlvinKwek Yes. I'm using Xamarin.Forms.

    I investigated and solved my problem by using DependencyService.

    **On forms:
    namespace myapplication
    {
    public class Toast
    {
    public static void Show(string message)
    {
    DependencyService.Get().Show(message);
    }

        public static void Show(string message, VisualElement visualElement)
        {
            DependencyService.Get<IToast>().Show(message, visualElement);
        }
    
        public static void Show(string message, ToastPosition position)
        {
            DependencyService.Get<IToast>().Show(message, position);
        }
    }
    
    public interface IToast
    {
        void Show(string message);
        void Show(string message, ToastPosition position);
        void Show(string message, VisualElement visualElement);
    }
    
    public enum ToastPosition
    {
        Top,
        Center,
        Bottom
    }
    

    }

    **On Android:

    [assembly: Dependency(typeof(ToastDroid))]
    namespace myapplication.AndroidOS
    {
    public class ToastDroid : IToast
    {
    private Toast toast;
    public void Show(string message)
    {
    ShowToast(message, ToastPosition.Center);
    }

        public void Show(string message, VisualElement visualElement)
        {
            ShowToast(message, ToastPosition.Bottom, visualElement);
        }
    
        public void Show(string message, ToastPosition position)
        {
            ShowToast(message, position);
        }
    
        void ShowToast(string message, ToastPosition position, VisualElement visualElement = null)
        {
            if (toast != null)
            {
                toast.Cancel();
                toast = null;
            }
            if (visualElement != null && position != ToastPosition.Center)
            {
                const int MARGIN = 15;
                int x = 0;
                int y = 0;
                Rectangle element = GetElementFrame(visualElement);
                element.X += element.Width / 2;
    
                var rectangle = new Rect();
                var act = Forms.Context as Activity;
                Window window = act.Window;
                window.DecorView.GetWindowVisibleDisplayFrame(rectangle);
                int statusBarHeight = rectangle.Top;
    
                switch (position)
                {
                    case ToastPosition.Top:
                        break;
                    case ToastPosition.Bottom:
                        element.Y += (element.Height + UnitSizeUtil.ToPixel(MARGIN, Android.App.Application.Context.Resources.DisplayMetrics));
                        if (NavigationPage.GetHasNavigationBar(visualElement))
                        {
                            if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                            {
                                element.Y += statusBarHeight;
                            }
                        }
                        break;
                }
                x = UnitSizeUtil.ToPixel(Convert.ToInt32(element.X), Forms.Context.Resources.DisplayMetrics);
                y = UnitSizeUtil.ToPixel(Convert.ToInt32(element.Y), Forms.Context.Resources.DisplayMetrics);
    
                //This is a temporary solution to calculate the position of toast message.
                const float CHARACTER_TO_PIXEL = 2.9f;
                const int SPACE_ON_BOTH_SIDES_OF_TOAST = 34;
                int messageLength = UnitSizeUtil.ToPixel(Convert.ToInt32(message.Length * CHARACTER_TO_PIXEL) + SPACE_ON_BOTH_SIDES_OF_TOAST, Forms.Context.Resources.DisplayMetrics);
                x -= messageLength;
    
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                toast.SetGravity(GravityFlags.Top | GravityFlags.Left, x, y);
            }
            else
            {
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                if (position == ToastPosition.Center)
                {
                    toast.SetGravity(GravityFlags.Center | GravityFlags.CenterHorizontal, 0, 0);
                }
                else if (position == ToastPosition.Bottom)
                {
                    toast.SetGravity(GravityFlags.Bottom | GravityFlags.Center, 0, 0);
                }
            }
            toast.Show();
        }
    
        Rectangle GetElementFrame(VisualElement visualElement)
        {
            Rectangle element = new Rectangle(visualElement.X, visualElement.Y, visualElement.Width, visualElement.Height);
            if (visualElement.ParentView != null)
            {
                Rectangle parentElement = GetElementFrame(visualElement.ParentView);
                element.X += parentElement.X;
                element.Y += parentElement.Y;
                if (visualElement.ParentView is Xamarin.Forms.ScrollView)
                {
                    var scrollView = visualElement.ParentView as Xamarin.Forms.ScrollView;
                    element.X -= scrollView.ScrollX;
                    element.Y -= scrollView.ScrollY;
                }
            }
            return element;
        }
    }
    

    }

    Hope it helps someone!

  • PhamThanhTongPhamThanhTong USMember ✭✭
    Accepted Answer

    @AlvinKwek Yes. I'm using Xamarin.Forms.

    I investigated and solved my problem by using DependencyService.

    **On forms:
    namespace myapplication
    {
    public class Toast
    {
    public static void Show(string message)
    {
    DependencyService.Get().Show(message);
    }

        public static void Show(string message, VisualElement visualElement)
        {
            DependencyService.Get<IToast>().Show(message, visualElement);
        }
    
        public static void Show(string message, ToastPosition position)
        {
            DependencyService.Get<IToast>().Show(message, position);
        }
    }
    
    public interface IToast
    {
        void Show(string message);
        void Show(string message, ToastPosition position);
        void Show(string message, VisualElement visualElement);
    }
    
    public enum ToastPosition
    {
        Top,
        Center,
        Bottom
    }
    

    }

    **On Android:

    [assembly: Dependency(typeof(ToastDroid))]
    namespace myapplication.AndroidOS
    {
    public class ToastDroid : IToast
    {
    private Toast toast;
    public void Show(string message)
    {
    ShowToast(message, ToastPosition.Center);
    }

        public void Show(string message, VisualElement visualElement)
        {
            ShowToast(message, ToastPosition.Bottom, visualElement);
        }
    
        public void Show(string message, ToastPosition position)
        {
            ShowToast(message, position);
        }
    
        void ShowToast(string message, ToastPosition position, VisualElement visualElement = null)
        {
            if (toast != null)
            {
                toast.Cancel();
                toast = null;
            }
            if (visualElement != null && position != ToastPosition.Center)
            {
                const int MARGIN = 15;
                int x = 0;
                int y = 0;
                Rectangle element = GetElementFrame(visualElement);
                element.X += element.Width / 2;
    
                var rectangle = new Rect();
                var act = Forms.Context as Activity;
                Window window = act.Window;
                window.DecorView.GetWindowVisibleDisplayFrame(rectangle);
                int statusBarHeight = rectangle.Top;
    
                switch (position)
                {
                    case ToastPosition.Top:
                        break;
                    case ToastPosition.Bottom:
                        element.Y += (element.Height + UnitSizeUtil.ToPixel(MARGIN, Android.App.Application.Context.Resources.DisplayMetrics));
                        if (NavigationPage.GetHasNavigationBar(visualElement))
                        {
                            if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                            {
                                element.Y += statusBarHeight;
                            }
                        }
                        break;
                }
                x = UnitSizeUtil.ToPixel(Convert.ToInt32(element.X), Forms.Context.Resources.DisplayMetrics);
                y = UnitSizeUtil.ToPixel(Convert.ToInt32(element.Y), Forms.Context.Resources.DisplayMetrics);
    
                //This is a temporary solution to calculate the position of toast message.
                const float CHARACTER_TO_PIXEL = 2.9f;
                const int SPACE_ON_BOTH_SIDES_OF_TOAST = 34;
                int messageLength = UnitSizeUtil.ToPixel(Convert.ToInt32(message.Length * CHARACTER_TO_PIXEL) + SPACE_ON_BOTH_SIDES_OF_TOAST, Forms.Context.Resources.DisplayMetrics);
                x -= messageLength;
    
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                toast.SetGravity(GravityFlags.Top | GravityFlags.Left, x, y);
            }
            else
            {
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                if (position == ToastPosition.Center)
                {
                    toast.SetGravity(GravityFlags.Center | GravityFlags.CenterHorizontal, 0, 0);
                }
                else if (position == ToastPosition.Bottom)
                {
                    toast.SetGravity(GravityFlags.Bottom | GravityFlags.Center, 0, 0);
                }
            }
            toast.Show();
        }
    
        Rectangle GetElementFrame(VisualElement visualElement)
        {
            Rectangle element = new Rectangle(visualElement.X, visualElement.Y, visualElement.Width, visualElement.Height);
            if (visualElement.ParentView != null)
            {
                Rectangle parentElement = GetElementFrame(visualElement.ParentView);
                element.X += parentElement.X;
                element.Y += parentElement.Y;
                if (visualElement.ParentView is Xamarin.Forms.ScrollView)
                {
                    var scrollView = visualElement.ParentView as Xamarin.Forms.ScrollView;
                    element.X -= scrollView.ScrollX;
                    element.Y -= scrollView.ScrollY;
                }
            }
            return element;
        }
    }
    

    }

    Hope it helps someone!

  • PhamThanhTongPhamThanhTong USMember ✭✭

    @AlvinKwek Yes. I'm using Xamarin.Forms.

    I investigated and solved my problem by using DependencyService.

    **On forms:
    namespace myapplication
    {
    public class Toast
    {
    public static void Show(string message)
    {
    DependencyService.Get().Show(message);
    }

        public static void Show(string message, VisualElement visualElement)
        {
            DependencyService.Get<IToast>().Show(message, visualElement);
        }
    
        public static void Show(string message, ToastPosition position)
        {
            DependencyService.Get<IToast>().Show(message, position);
        }
    }
    
    public interface IToast
    {
        void Show(string message);
        void Show(string message, ToastPosition position);
        void Show(string message, VisualElement visualElement);
    }
    
    public enum ToastPosition
    {
        Top,
        Center,
        Bottom
    }
    

    }

    **On Android:

    [assembly: Dependency(typeof(ToastDroid))]
    namespace myapplication.AndroidOS
    {
    public class ToastDroid : IToast
    {
    private Toast toast;
    public void Show(string message)
    {
    ShowToast(message, ToastPosition.Center);
    }

        public void Show(string message, VisualElement visualElement)
        {
            ShowToast(message, ToastPosition.Bottom, visualElement);
        }
    
        public void Show(string message, ToastPosition position)
        {
            ShowToast(message, position);
        }
    
        void ShowToast(string message, ToastPosition position, VisualElement visualElement = null)
        {
            if (toast != null)
            {
                toast.Cancel();
                toast = null;
            }
            if (visualElement != null && position != ToastPosition.Center)
            {
                const int MARGIN = 15;
                int x = 0;
                int y = 0;
                Rectangle element = GetElementFrame(visualElement);
                element.X += element.Width / 2;
    
                var rectangle = new Rect();
                var act = Forms.Context as Activity;
                Window window = act.Window;
                window.DecorView.GetWindowVisibleDisplayFrame(rectangle);
                int statusBarHeight = rectangle.Top;
    
                switch (position)
                {
                    case ToastPosition.Top:
                        break;
                    case ToastPosition.Bottom:
                        element.Y += (element.Height + UnitSizeUtil.ToPixel(MARGIN, Android.App.Application.Context.Resources.DisplayMetrics));
                        if (NavigationPage.GetHasNavigationBar(visualElement))
                        {
                            if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                            {
                                element.Y += statusBarHeight;
                            }
                        }
                        break;
                }
                x = UnitSizeUtil.ToPixel(Convert.ToInt32(element.X), Forms.Context.Resources.DisplayMetrics);
                y = UnitSizeUtil.ToPixel(Convert.ToInt32(element.Y), Forms.Context.Resources.DisplayMetrics);
    
                //This is a temporary solution to calculate the position of toast message.
                const float CHARACTER_TO_PIXEL = 2.9f;
                const int SPACE_ON_BOTH_SIDES_OF_TOAST = 34;
                int messageLength = UnitSizeUtil.ToPixel(Convert.ToInt32(message.Length * CHARACTER_TO_PIXEL) + SPACE_ON_BOTH_SIDES_OF_TOAST, Forms.Context.Resources.DisplayMetrics);
                x -= messageLength;
    
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                toast.SetGravity(GravityFlags.Top | GravityFlags.Left, x, y);
            }
            else
            {
                toast = Toast.MakeText(Forms.Context, message, ToastLength.Short);
                if (position == ToastPosition.Center)
                {
                    toast.SetGravity(GravityFlags.Center | GravityFlags.CenterHorizontal, 0, 0);
                }
                else if (position == ToastPosition.Bottom)
                {
                    toast.SetGravity(GravityFlags.Bottom | GravityFlags.Center, 0, 0);
                }
            }
            toast.Show();
        }
    
        Rectangle GetElementFrame(VisualElement visualElement)
        {
            Rectangle element = new Rectangle(visualElement.X, visualElement.Y, visualElement.Width, visualElement.Height);
            if (visualElement.ParentView != null)
            {
                Rectangle parentElement = GetElementFrame(visualElement.ParentView);
                element.X += parentElement.X;
                element.Y += parentElement.Y;
                if (visualElement.ParentView is Xamarin.Forms.ScrollView)
                {
                    var scrollView = visualElement.ParentView as Xamarin.Forms.ScrollView;
                    element.X -= scrollView.ScrollX;
                    element.Y -= scrollView.ScrollY;
                }
            }
            return element;
        }
    }
    

    }

    Hope it helps someone!

  • Jhelumi786Jhelumi786 Member ✭✭

    Hi, Can you share the code for UnitSizeUtil class please
    Thanks

Sign In or Register to comment.