192 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Android.Content.Res;
 | 
						|
using Android.Graphics.Drawables;
 | 
						|
#if __ANDROID_29__
 | 
						|
using AndroidX.Core.Widget;
 | 
						|
using Google.Android.Material.BottomNavigation;
 | 
						|
#else
 | 
						|
using Android.Support.Design.Internal;
 | 
						|
using Android.Support.Design.Widget;
 | 
						|
#endif
 | 
						|
using System;
 | 
						|
using Xamarin.Forms;
 | 
						|
using Xamarin.Forms.Platform.Android;
 | 
						|
using AColor = Android.Graphics.Color;
 | 
						|
using R = Android.Resource;
 | 
						|
 | 
						|
namespace Pixiview.Droid.Renderers.AppShellSection
 | 
						|
{
 | 
						|
    public class AppShellBottomNavViewAppearanceTracker : IShellBottomNavViewAppearanceTracker
 | 
						|
    {
 | 
						|
        [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "<Pending>")]
 | 
						|
        IShellContext _shellContext;
 | 
						|
        ShellItem _shellItem;
 | 
						|
        ColorStateList _defaultList;
 | 
						|
        bool _disposed;
 | 
						|
        ColorStateList _colorStateList;
 | 
						|
 | 
						|
        public AppShellBottomNavViewAppearanceTracker(IShellContext shellContext, ShellItem shellItem)
 | 
						|
        {
 | 
						|
            _shellItem = shellItem;
 | 
						|
            _shellContext = shellContext;
 | 
						|
        }
 | 
						|
 | 
						|
        public virtual void ResetAppearance(BottomNavigationView bottomView)
 | 
						|
        {
 | 
						|
            if (_defaultList != null)
 | 
						|
            {
 | 
						|
                bottomView.ItemTextColor = _defaultList;
 | 
						|
                bottomView.ItemIconTintList = _defaultList;
 | 
						|
            }
 | 
						|
 | 
						|
            SetBackgroundColor(bottomView, Color.White);
 | 
						|
        }
 | 
						|
 | 
						|
        public virtual void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
 | 
						|
        {
 | 
						|
            IShellAppearanceElement controller = appearance;
 | 
						|
            var backgroundColor = controller.EffectiveTabBarBackgroundColor;
 | 
						|
            var foregroundColor = controller.EffectiveTabBarForegroundColor;
 | 
						|
            var disabledColor = controller.EffectiveTabBarDisabledColor;
 | 
						|
            var unselectedColor = controller.EffectiveTabBarUnselectedColor; // currently unused
 | 
						|
            var titleColor = controller.EffectiveTabBarTitleColor;
 | 
						|
 | 
						|
            if (_defaultList == null)
 | 
						|
            {
 | 
						|
#if __ANDROID_28__
 | 
						|
                _defaultList = bottomView.ItemTextColor ?? bottomView.ItemIconTintList
 | 
						|
                    ?? MakeColorStateList(titleColor.ToAndroid().ToArgb(), disabledColor.ToAndroid().ToArgb(), foregroundColor.ToAndroid().ToArgb());
 | 
						|
#else
 | 
						|
                _defaultList = bottomView.ItemTextColor ?? bottomView.ItemIconTintList;
 | 
						|
#endif
 | 
						|
            }
 | 
						|
 | 
						|
            _colorStateList = MakeColorStateList(titleColor, disabledColor, foregroundColor);
 | 
						|
            bottomView.ItemTextColor = _colorStateList;
 | 
						|
            bottomView.ItemIconTintList = _colorStateList;
 | 
						|
 | 
						|
            var menu = bottomView.Menu;
 | 
						|
            if (menu != null && menu.HasVisibleItems && menu.Size() == 4)
 | 
						|
            {
 | 
						|
                var itemUser = menu.GetItem(0);
 | 
						|
                itemUser.SetIcon(itemUser.IsChecked ?
 | 
						|
                    Resource.Drawable.ic_user :
 | 
						|
                    Resource.Drawable.ic_user_regular);
 | 
						|
                var itemRecommend = menu.GetItem(1);
 | 
						|
                itemRecommend.SetIcon(itemRecommend.IsChecked ?
 | 
						|
                    Resource.Drawable.ic_sparkles :
 | 
						|
                    Resource.Drawable.ic_sparkles_regular);
 | 
						|
                var itemRank = menu.GetItem(2);
 | 
						|
                itemRank.SetIcon(itemRank.IsChecked ?
 | 
						|
                    Resource.Drawable.ic_rank :
 | 
						|
                    Resource.Drawable.ic_rank_regular);
 | 
						|
                var itemFavorite = menu.GetItem(3);
 | 
						|
                itemFavorite.SetIcon(itemFavorite.IsChecked ?
 | 
						|
                    Resource.Drawable.ic_bookmark :
 | 
						|
                    Resource.Drawable.ic_bookmark_regular);
 | 
						|
            }
 | 
						|
 | 
						|
            SetBackgroundColor(bottomView, backgroundColor);
 | 
						|
        }
 | 
						|
 | 
						|
        protected virtual void SetBackgroundColor(BottomNavigationView bottomView, Color color)
 | 
						|
        {
 | 
						|
            var oldBackground = bottomView.Background;
 | 
						|
            var colorDrawable = oldBackground as ColorDrawable;
 | 
						|
            var colorChangeRevealDrawable = oldBackground as AppColorChangeRevealDrawable;
 | 
						|
            AColor lastColor = colorChangeRevealDrawable?.EndColor ?? colorDrawable?.Color ?? Color.Default.ToAndroid();
 | 
						|
            AColor newColor;
 | 
						|
 | 
						|
            if (color == Color.Default)
 | 
						|
                newColor = Color.White.ToAndroid();
 | 
						|
            else
 | 
						|
                newColor = color.ToAndroid();
 | 
						|
 | 
						|
            if (!(bottomView.GetChildAt(0) is BottomNavigationMenuView menuView))
 | 
						|
            {
 | 
						|
                if (colorDrawable != null && lastColor == newColor)
 | 
						|
                    return;
 | 
						|
 | 
						|
                if (lastColor != newColor || colorDrawable == null)
 | 
						|
                {
 | 
						|
                    bottomView.SetBackground(new ColorDrawable(newColor));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (colorChangeRevealDrawable != null && lastColor == newColor)
 | 
						|
                    return;
 | 
						|
 | 
						|
                var index = ((IShellItemController)_shellItem).GetItems().IndexOf(_shellItem.CurrentItem);
 | 
						|
                var menu = bottomView.Menu;
 | 
						|
                index = Math.Min(index, menu.Size() - 1);
 | 
						|
 | 
						|
                var child = menuView.GetChildAt(index);
 | 
						|
                if (child == null)
 | 
						|
                    return;
 | 
						|
 | 
						|
                var touchPoint = new Android.Graphics.Point(child.Left + (child.Right - child.Left) / 2, child.Top + (child.Bottom - child.Top) / 2);
 | 
						|
 | 
						|
                bottomView.SetBackground(new AppColorChangeRevealDrawable(lastColor, newColor, touchPoint));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        ColorStateList MakeColorStateList(Color titleColor, Color disabledColor, Color unselectedColor)
 | 
						|
        {
 | 
						|
            var disabledInt = disabledColor.IsDefault ?
 | 
						|
                _defaultList.GetColorForState(new[] { -R.Attribute.StateEnabled }, AColor.Gray) :
 | 
						|
                disabledColor.ToAndroid().ToArgb();
 | 
						|
 | 
						|
            var checkedInt = titleColor.IsDefault ?
 | 
						|
                _defaultList.GetColorForState(new[] { R.Attribute.StateChecked }, AColor.Black) :
 | 
						|
                titleColor.ToAndroid().ToArgb();
 | 
						|
 | 
						|
            var defaultColor = unselectedColor.IsDefault ?
 | 
						|
                _defaultList.DefaultColor :
 | 
						|
                unselectedColor.ToAndroid().ToArgb();
 | 
						|
 | 
						|
            return MakeColorStateList(checkedInt, disabledInt, defaultColor);
 | 
						|
        }
 | 
						|
 | 
						|
        ColorStateList MakeColorStateList(int titleColorInt, int disabledColorInt, int defaultColor)
 | 
						|
        {
 | 
						|
            var states = new int[][] {
 | 
						|
                new int[] { -R.Attribute.StateEnabled },
 | 
						|
                new int[] {R.Attribute.StateChecked },
 | 
						|
                new int[] { }
 | 
						|
            };
 | 
						|
 | 
						|
            var colors = new[] { disabledColorInt, titleColorInt, defaultColor };
 | 
						|
 | 
						|
            return new ColorStateList(states, colors);
 | 
						|
        }
 | 
						|
 | 
						|
        #region IDisposable
 | 
						|
 | 
						|
        public void Dispose()
 | 
						|
        {
 | 
						|
            Dispose(true);
 | 
						|
        }
 | 
						|
 | 
						|
        protected virtual void Dispose(bool disposing)
 | 
						|
        {
 | 
						|
            if (_disposed)
 | 
						|
                return;
 | 
						|
 | 
						|
            _disposed = true;
 | 
						|
 | 
						|
            if (disposing)
 | 
						|
            {
 | 
						|
                _defaultList?.Dispose();
 | 
						|
                _colorStateList?.Dispose();
 | 
						|
 | 
						|
                _shellItem = null;
 | 
						|
                _shellContext = null;
 | 
						|
                _defaultList = null;
 | 
						|
                _colorStateList = null;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion IDisposable
 | 
						|
    }
 | 
						|
}
 |