mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 23:25:45 +03:00
bottom navigation tab page on android
This commit is contained in:
parent
ea7290afab
commit
fdc51f33ad
5 changed files with 665 additions and 309 deletions
|
@ -73,6 +73,10 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Mono.Android" />
|
<Reference Include="Mono.Android" />
|
||||||
<Reference Include="Mono.Android.Export" />
|
<Reference Include="Mono.Android.Export" />
|
||||||
|
<Reference Include="Naxam.Ittianyu.BottomNavExtension, Version=1.2.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>.\Naxam.Ittianyu.BottomNavExtension.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.IO.Compression" />
|
<Reference Include="System.IO.Compression" />
|
||||||
|
@ -924,5 +928,8 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh_selected.png" />
|
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh_selected.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable\bottom_nav_bg.xml" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -2,94 +2,427 @@
|
||||||
using Bit.Android.Controls;
|
using Bit.Android.Controls;
|
||||||
using Bit.App.Controls;
|
using Bit.App.Controls;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
using Com.Ittianyu.Bottomnavigationviewex;
|
||||||
using Xamarin.Forms.Platform.Android;
|
using Xamarin.Forms.Platform.Android;
|
||||||
using Android.Support.Design.Widget;
|
using RelativeLayout = Android.Widget.RelativeLayout;
|
||||||
using Xamarin.Forms.Platform.Android.AppCompat;
|
using Platform = Xamarin.Forms.Platform.Android.Platform;
|
||||||
using System.Reflection;
|
|
||||||
using System.Linq;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
|
using Android.Views;
|
||||||
|
using Android.Widget;
|
||||||
|
using Android.Support.Design.Internal;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Support.Design.Widget;
|
||||||
|
|
||||||
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(ExtendedTabbedPageRenderer))]
|
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(ExtendedTabbedPageRenderer))]
|
||||||
namespace Bit.Android.Controls
|
namespace Bit.Android.Controls
|
||||||
{
|
{
|
||||||
public class ExtendedTabbedPageRenderer : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
|
public class ExtendedTabbedPageRenderer : VisualElementRenderer<ExtendedTabbedPage>,
|
||||||
|
BottomNavigationView.IOnNavigationItemSelectedListener
|
||||||
{
|
{
|
||||||
private TabLayout _tabLayout;
|
public static bool ShouldUpdateSelectedIcon;
|
||||||
|
public static Action<IMenuItem, FileImageSource, bool> MenuItemIconSetter;
|
||||||
|
public static float? BottomBarHeight = 50;
|
||||||
|
|
||||||
|
private RelativeLayout _rootLayout;
|
||||||
|
private FrameLayout _pageContainer;
|
||||||
|
private BottomNavigationViewEx _bottomNav;
|
||||||
|
private readonly int _barId;
|
||||||
|
|
||||||
|
public static global::Android.Graphics.Color? BackgroundColor;
|
||||||
|
|
||||||
public ExtendedTabbedPageRenderer(Context context)
|
public ExtendedTabbedPageRenderer(Context context)
|
||||||
: base(context)
|
: base(context)
|
||||||
{ }
|
{
|
||||||
|
AutoPackage = false;
|
||||||
|
_barId = GenerateViewId();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
|
IPageController TabbedController => Element as IPageController;
|
||||||
|
public int LastSelectedIndex { get; internal set; }
|
||||||
|
|
||||||
|
public bool OnNavigationItemSelected(IMenuItem item)
|
||||||
|
{
|
||||||
|
this.SwitchPage(item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetupTabItems()
|
||||||
|
{
|
||||||
|
this.SetupTabItems(_bottomNav);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetupBottomBar()
|
||||||
|
{
|
||||||
|
_bottomNav = this.SetupBottomBar(_rootLayout, _bottomNav, _barId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Action<IMenuItem, FileImageSource, bool> DefaultMenuItemIconSetter = (menuItem, icon, selected) =>
|
||||||
|
{
|
||||||
|
var tabIconId = ResourceUtils.IdFromTitle(icon, ResourceManager.DrawableClass);
|
||||||
|
menuItem.SetIcon(tabIconId);
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<ExtendedTabbedPage> e)
|
||||||
{
|
{
|
||||||
base.OnElementChanged(e);
|
base.OnElementChanged(e);
|
||||||
var view = (ExtendedTabbedPage)Element;
|
|
||||||
|
|
||||||
var field = typeof(ExtendedTabbedPageRenderer).BaseType.GetField("_tabLayout",
|
if(e.OldElement != null)
|
||||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
|
||||||
_tabLayout = field?.GetValue(this) as TabLayout;
|
|
||||||
if(_tabLayout != null)
|
|
||||||
{
|
{
|
||||||
var tab = _tabLayout.GetTabAt(0);
|
e.OldElement.ChildAdded -= PagesChanged;
|
||||||
SetSelectedTabIcon(tab, Element.Children[0].Icon, true);
|
e.OldElement.ChildRemoved -= PagesChanged;
|
||||||
}
|
e.OldElement.ChildrenReordered -= PagesChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabLayout.IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
|
if(e.NewElement == null)
|
||||||
{
|
|
||||||
if(Element == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedIndex = tab.Position;
|
UpdateIgnoreContainerAreas();
|
||||||
var child = Element.Children[selectedIndex];
|
|
||||||
if(Element.Children.Count > selectedIndex && selectedIndex >= 0)
|
if(_rootLayout == null)
|
||||||
{
|
{
|
||||||
Element.CurrentPage = Element.Children[selectedIndex];
|
SetupNativeView();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSelectedTabIcon(tab, child.Icon, true);
|
this.HandlePagesChanged();
|
||||||
|
SwitchContent(Element.CurrentPage);
|
||||||
|
|
||||||
|
Element.ChildAdded += PagesChanged;
|
||||||
|
Element.ChildRemoved += PagesChanged;
|
||||||
|
Element.ChildrenReordered += PagesChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabLayout.IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var child = Element.Children[tab.Position];
|
base.OnElementPropertyChanged(sender, e);
|
||||||
SetSelectedTabIcon(tab, child.Icon, false);
|
if(e.PropertyName == nameof(TabbedPage.CurrentPage))
|
||||||
|
{
|
||||||
|
SwitchContent(Element.CurrentPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetSelectedTabIcon(TabLayout.Tab tab, string icon, bool selected)
|
void PagesChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrEmpty(icon))
|
this.HandlePagesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAttachedToWindow()
|
||||||
|
{
|
||||||
|
base.OnAttachedToWindow();
|
||||||
|
TabbedController?.SendAppearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetachedFromWindow()
|
||||||
|
{
|
||||||
|
base.OnDetachedFromWindow();
|
||||||
|
TabbedController?.SendDisappearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
var width = right - left;
|
||||||
|
var height = bottom - top;
|
||||||
|
|
||||||
|
base.OnLayout(changed, left, top, right, bottom);
|
||||||
|
if(width <= 0 || height <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selected)
|
this.Layout(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
var selectedIcon = string.Format("{0}_selected", icon.Replace(".png", string.Empty));
|
if(disposing)
|
||||||
var selectedResource = IdFromTitle(selectedIcon, ResourceManager.DrawableClass);
|
{
|
||||||
if(selectedResource != 0)
|
Element.ChildAdded -= PagesChanged;
|
||||||
|
Element.ChildRemoved -= PagesChanged;
|
||||||
|
Element.ChildrenReordered -= PagesChanged;
|
||||||
|
|
||||||
|
if(_rootLayout != null)
|
||||||
|
{
|
||||||
|
RemoveAllViews();
|
||||||
|
foreach(Page pageToRemove in Element.Children)
|
||||||
|
{
|
||||||
|
var pageRenderer = Platform.GetRenderer(pageToRemove);
|
||||||
|
if(pageRenderer != null)
|
||||||
|
{
|
||||||
|
pageRenderer.View.RemoveFromParent();
|
||||||
|
pageRenderer.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_bottomNav != null)
|
||||||
|
{
|
||||||
|
_bottomNav.SetOnNavigationItemSelectedListener(null);
|
||||||
|
_bottomNav.Dispose();
|
||||||
|
_bottomNav = null;
|
||||||
|
}
|
||||||
|
_rootLayout.Dispose();
|
||||||
|
_rootLayout = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetupNativeView()
|
||||||
|
{
|
||||||
|
_rootLayout = this.CreateRoot(_barId, GenerateViewId(), out _pageContainer);
|
||||||
|
AddView(_rootLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwitchContent(Page page)
|
||||||
|
{
|
||||||
|
this.ChangePage(_pageContainer, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateIgnoreContainerAreas()
|
||||||
|
{
|
||||||
|
foreach(var child in Element.Children)
|
||||||
|
{
|
||||||
|
child.IgnoresContainerArea = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class TabExtensions
|
||||||
|
{
|
||||||
|
public static Rectangle CreateRect(this Context context, int width, int height)
|
||||||
|
{
|
||||||
|
return new Rectangle(0, 0, context.FromPixels(width), context.FromPixels(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandlePagesChanged(this ExtendedTabbedPageRenderer renderer)
|
||||||
|
{
|
||||||
|
renderer.SetupBottomBar();
|
||||||
|
renderer.SetupTabItems();
|
||||||
|
|
||||||
|
if(renderer.Element.Children.Count == 0)
|
||||||
{
|
{
|
||||||
tab.SetIcon(selectedResource);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnsureTabIndex(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
var resource = IdFromTitle(icon, ResourceManager.DrawableClass);
|
static void EnsureTabIndex(ExtendedTabbedPageRenderer renderer)
|
||||||
tab.SetIcon(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int IdFromTitle(string title, Type type)
|
|
||||||
{
|
{
|
||||||
var name = System.IO.Path.GetFileNameWithoutExtension(title);
|
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
|
||||||
return GetId(type, name);
|
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
|
||||||
|
var menu = (BottomNavigationMenu)bottomNav.Menu;
|
||||||
|
|
||||||
|
var itemIndex = menu.FindItemIndex(bottomNav.SelectedItemId);
|
||||||
|
var pageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
|
||||||
|
if(pageIndex >= 0 && pageIndex != itemIndex && pageIndex < bottomNav.ItemCount)
|
||||||
|
{
|
||||||
|
var menuItem = menu.GetItem(pageIndex);
|
||||||
|
bottomNav.SelectedItemId = menuItem.ItemId;
|
||||||
|
|
||||||
|
if(ExtendedTabbedPageRenderer.ShouldUpdateSelectedIcon && ExtendedTabbedPageRenderer.MenuItemIconSetter != null)
|
||||||
|
{
|
||||||
|
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(menuItem, renderer.Element.CurrentPage.Icon, true);
|
||||||
|
|
||||||
|
if(renderer.LastSelectedIndex != pageIndex)
|
||||||
|
{
|
||||||
|
var lastSelectedPage = renderer.Element.Children[renderer.LastSelectedIndex];
|
||||||
|
var lastSelectedMenuItem = menu.GetItem(renderer.LastSelectedIndex);
|
||||||
|
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(lastSelectedMenuItem, lastSelectedPage.Icon, false);
|
||||||
|
renderer.LastSelectedIndex = pageIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetId(Type type, string propertyName)
|
public static void SwitchPage(this ExtendedTabbedPageRenderer renderer, IMenuItem item)
|
||||||
|
{
|
||||||
|
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
|
||||||
|
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
|
||||||
|
var menu = (BottomNavigationMenu)bottomNav.Menu;
|
||||||
|
|
||||||
|
var index = menu.FindItemIndex(item.ItemId);
|
||||||
|
var pageIndex = index % renderer.Element.Children.Count;
|
||||||
|
var currentPageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
|
||||||
|
|
||||||
|
if(currentPageIndex != pageIndex)
|
||||||
|
{
|
||||||
|
renderer.Element.CurrentPage = renderer.Element.Children[pageIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Layout(this ExtendedTabbedPageRenderer renderer, int width, int height)
|
||||||
|
{
|
||||||
|
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
|
||||||
|
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
|
||||||
|
|
||||||
|
var Context = renderer.Context;
|
||||||
|
|
||||||
|
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
|
||||||
|
MakeMeasureSpec(height, MeasureSpecMode.AtMost));
|
||||||
|
|
||||||
|
((IPageController)renderer.Element).ContainerArea =
|
||||||
|
Context.CreateRect(rootLayout.MeasuredWidth, rootLayout.GetChildAt(0).MeasuredHeight);
|
||||||
|
|
||||||
|
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
|
||||||
|
MakeMeasureSpec(height, MeasureSpecMode.Exactly));
|
||||||
|
rootLayout.Layout(0, 0, rootLayout.MeasuredWidth, rootLayout.MeasuredHeight);
|
||||||
|
|
||||||
|
if(renderer.Element.Children.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tabsHeight = bottomNav.MeasuredHeight;
|
||||||
|
|
||||||
|
var item = (ViewGroup)bottomNav.GetChildAt(0);
|
||||||
|
item.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
|
||||||
|
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
|
||||||
|
|
||||||
|
item.Layout(0, 0, width, tabsHeight);
|
||||||
|
int item_w = width / item.ChildCount;
|
||||||
|
for(int i = 0; i < item.ChildCount; i++)
|
||||||
|
{
|
||||||
|
var frame = (FrameLayout)item.GetChildAt(i);
|
||||||
|
frame.Measure(MakeMeasureSpec(item_w, MeasureSpecMode.Exactly),
|
||||||
|
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
|
||||||
|
frame.Layout(i * item_w, 0, i * item_w + item_w, tabsHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetupTabItems(this ExtendedTabbedPageRenderer renderer, BottomNavigationViewEx bottomNav)
|
||||||
|
{
|
||||||
|
var element = renderer.Element;
|
||||||
|
var menu = (BottomNavigationMenu)bottomNav.Menu;
|
||||||
|
menu.ClearAll();
|
||||||
|
|
||||||
|
var tabsCount = Math.Min(element.Children.Count, bottomNav.MaxItemCount);
|
||||||
|
for(int i = 0; i < tabsCount; i++)
|
||||||
|
{
|
||||||
|
var page = element.Children[i];
|
||||||
|
var menuItem = menu.Add(0, i, 0, page.Title);
|
||||||
|
var setter = ExtendedTabbedPageRenderer.MenuItemIconSetter ?? ExtendedTabbedPageRenderer.DefaultMenuItemIconSetter;
|
||||||
|
setter.Invoke(menuItem, page.Icon, renderer.LastSelectedIndex == i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(element.Children.Count > 0)
|
||||||
|
{
|
||||||
|
bottomNav.EnableShiftingMode(false);
|
||||||
|
bottomNav.EnableItemShiftingMode(false);
|
||||||
|
bottomNav.EnableAnimation(false);
|
||||||
|
bottomNav.SetTextVisibility(false);
|
||||||
|
bottomNav.SetIconsMarginTop(30);
|
||||||
|
bottomNav.SetBackgroundResource(Resource.Drawable.bottom_nav_bg);
|
||||||
|
|
||||||
|
var stateList = new global::Android.Content.Res.ColorStateList(
|
||||||
|
new int[][] {
|
||||||
|
new int[] { global::Android.Resource.Attribute.StateChecked },
|
||||||
|
new int[] { global::Android.Resource.Attribute.StateEnabled}
|
||||||
|
},
|
||||||
|
new int[] {
|
||||||
|
element.TintColor.ToAndroid(), // Selected
|
||||||
|
Color.FromHex("A1A1A1").ToAndroid() // Normal
|
||||||
|
});
|
||||||
|
|
||||||
|
bottomNav.ItemIconTintList = stateList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BottomNavigationViewEx SetupBottomBar(this ExtendedTabbedPageRenderer renderer,
|
||||||
|
global::Android.Widget.RelativeLayout rootLayout, BottomNavigationViewEx bottomNav, int barId)
|
||||||
|
{
|
||||||
|
if(bottomNav != null)
|
||||||
|
{
|
||||||
|
rootLayout.RemoveView(bottomNav);
|
||||||
|
bottomNav.SetOnNavigationItemSelectedListener(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var barParams = new global::Android.Widget.RelativeLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MatchParent,
|
||||||
|
ExtendedTabbedPageRenderer.BottomBarHeight.HasValue ?
|
||||||
|
(int)rootLayout.Context.ToPixels(ExtendedTabbedPageRenderer.BottomBarHeight.Value) :
|
||||||
|
ViewGroup.LayoutParams.WrapContent);
|
||||||
|
barParams.AddRule(LayoutRules.AlignParentBottom);
|
||||||
|
bottomNav = new BottomNavigationViewEx(rootLayout.Context)
|
||||||
|
{
|
||||||
|
LayoutParameters = barParams,
|
||||||
|
Id = barId
|
||||||
|
};
|
||||||
|
if(ExtendedTabbedPageRenderer.BackgroundColor.HasValue)
|
||||||
|
{
|
||||||
|
bottomNav.SetBackgroundColor(ExtendedTabbedPageRenderer.BackgroundColor.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bottomNav.SetOnNavigationItemSelectedListener(renderer);
|
||||||
|
rootLayout.AddView(bottomNav, 1, barParams);
|
||||||
|
|
||||||
|
return bottomNav;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ChangePage(this ExtendedTabbedPageRenderer renderer, FrameLayout pageContainer, Page page)
|
||||||
|
{
|
||||||
|
renderer.Context.HideKeyboard(renderer);
|
||||||
|
if(page == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Platform.GetRenderer(page) == null)
|
||||||
|
{
|
||||||
|
Platform.SetRenderer(page, Platform.CreateRendererWithContext(page, renderer.Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
var pageContent = Platform.GetRenderer(page).View;
|
||||||
|
pageContainer.AddView(pageContent);
|
||||||
|
if(pageContainer.ChildCount > 1)
|
||||||
|
{
|
||||||
|
pageContainer.RemoveViewAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTabIndex(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RelativeLayout CreateRoot(this ExtendedTabbedPageRenderer renderer, int barId, int pageContainerId, out FrameLayout pageContainer)
|
||||||
|
{
|
||||||
|
var rootLayout = new RelativeLayout(renderer.Context)
|
||||||
|
{
|
||||||
|
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
|
||||||
|
};
|
||||||
|
|
||||||
|
var pageParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
|
||||||
|
pageParams.AddRule(LayoutRules.Above, barId);
|
||||||
|
pageContainer = new FrameLayout(renderer.Context)
|
||||||
|
{
|
||||||
|
LayoutParameters = pageParams,
|
||||||
|
Id = pageContainerId
|
||||||
|
};
|
||||||
|
|
||||||
|
rootLayout.AddView(pageContainer, 0, pageParams);
|
||||||
|
return rootLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int MakeMeasureSpec(int size, MeasureSpecMode mode)
|
||||||
|
{
|
||||||
|
return size + (int)mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResourceUtils
|
||||||
|
{
|
||||||
|
public static int IdFromTitle(string title, Type type)
|
||||||
|
{
|
||||||
|
var name = Path.GetFileNameWithoutExtension(title);
|
||||||
|
var id = GetId(type, name);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetId(Type type, string propertyName)
|
||||||
{
|
{
|
||||||
var props = type.GetFields();
|
var props = type.GetFields();
|
||||||
var prop = props.FirstOrDefault(p => p.Name == propertyName);
|
var prop = props.Select(p => p).FirstOrDefault(p => p.Name == propertyName);
|
||||||
if(prop != null)
|
if(prop != null)
|
||||||
{
|
{
|
||||||
return (int)prop.GetValue(type);
|
return (int)prop.GetValue(type);
|
||||||
|
|
BIN
src/Android/Naxam.Ittianyu.BottomNavExtension.dll
Normal file
BIN
src/Android/Naxam.Ittianyu.BottomNavExtension.dll
Normal file
Binary file not shown.
537
src/Android/Resources/Resource.Designer.cs
generated
537
src/Android/Resources/Resource.Designer.cs
generated
File diff suppressed because it is too large
Load diff
13
src/Android/Resources/drawable/bottom_nav_bg.xml
Normal file
13
src/Android/Resources/drawable/bottom_nav_bg.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#D2D6DF" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:top="1dp">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#F5F5F7" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
Loading…
Reference in a new issue