Last active
May 13, 2021 07:11
-
-
Save mr5z/4c36e45c6b2751bd5ecbcc2f7e9fbb35 to your computer and use it in GitHub Desktop.
Raised Middle Button TabbedPage implementation for Xamarin.Android. Just replace the `Replace_With_Your_Custom_BottomNavigationView` with your own implementation of BNV!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using Android.Content; | |
using Android.Support.Design.Widget; | |
using Android.Support.V4.View; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
using AWidget = Android.Widget; | |
using ATabbedRenderer = Xamarin.Forms.Platform.Android.AppCompat.TabbedPageRenderer; | |
using System.Collections.Specialized; | |
namespace Your.Namespace.Here | |
{ | |
public class RaisedTabbedPageRenderer : ATabbedRenderer | |
{ | |
AWidget.RelativeLayout InternalRelativeLayout | |
{ | |
get | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_relativeLayout", BindingFlags.NonPublic | BindingFlags.Instance); | |
return (AWidget.RelativeLayout)field.GetValue(this); | |
} | |
set | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_relativeLayout", BindingFlags.NonPublic | BindingFlags.Instance); | |
field.SetValue(this, value); | |
} | |
} | |
BottomNavigationView InternalBottomNavigationView | |
{ | |
get | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_bottomNavigationView", BindingFlags.NonPublic | BindingFlags.Instance); | |
return (BottomNavigationView)field.GetValue(this); | |
} | |
set | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_bottomNavigationView", BindingFlags.NonPublic | BindingFlags.Instance); | |
field.SetValue(this, value); | |
} | |
} | |
ViewPager InternalViewPager | |
{ | |
get | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_viewPager", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance); | |
return (ViewPager)field.GetValue(this); | |
} | |
set | |
{ | |
var field = typeof(ATabbedRenderer).GetField("_viewPager", BindingFlags.NonPublic | BindingFlags.Instance); | |
field.SetValue(this, value); | |
} | |
} | |
public RaisedTabbedPageRenderer(Context context) : base(context) | |
{ | |
} | |
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e) | |
{ | |
base.OnElementChanged(e); | |
PerformHack(e); | |
} | |
void PerformHack(ElementChangedEventArgs<TabbedPage> e) | |
{ | |
RemoveView(InternalRelativeLayout); | |
InternalRelativeLayout = new AWidget.RelativeLayout(Context) | |
{ | |
LayoutParameters = new LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent) | |
}; | |
if (InternalBottomNavigationView != null) | |
{ | |
InternalRelativeLayout.RemoveView(InternalBottomNavigationView); | |
InternalBottomNavigationView.SetOnNavigationItemSelectedListener(null); | |
} | |
var bottomNavigationViewLayoutParams = new AWidget.RelativeLayout.LayoutParams( | |
LayoutParams.MatchParent, | |
LayoutParams.WrapContent); | |
bottomNavigationViewLayoutParams.AddRule(AWidget.LayoutRules.AlignParentBottom); | |
// TODO Replace with your custom BottomNavigationView | |
InternalBottomNavigationView = new RaisedBottomNavigationBar(Context) | |
{ | |
LayoutParameters = bottomNavigationViewLayoutParams, | |
Id = GenerateViewId() | |
}; | |
var viewPagerParams = new AWidget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent); | |
viewPagerParams.AddRule(AWidget.LayoutRules.Above, InternalBottomNavigationView.Id); | |
var pager = InternalViewPager; | |
pager.RemoveFromParent(); | |
InternalRelativeLayout.AddView(pager, viewPagerParams); | |
InternalRelativeLayout.AddView(InternalBottomNavigationView, bottomNavigationViewLayoutParams); | |
AddView(InternalRelativeLayout); | |
OnChildrenCollectionChangedInternal(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); | |
TabbedPage tabbedPage = e.NewElement; | |
if (tabbedPage.CurrentPage != null) | |
InvokeMethod("ScrollToCurrentPage"); | |
InvokeMethod("UpdateBarBackgroundColor"); | |
InvokeMethod("UpdateBarTextColor"); | |
InvokeMethod("UpdateItemIconColor"); | |
InvokeMethod("UpdateSwipePaging"); | |
InvokeMethod("UpdateOffscreenPageLimit"); | |
} | |
void OnChildrenCollectionChangedInternal(object sender, NotifyCollectionChangedEventArgs e) | |
{ | |
MethodInfo privMethod = typeof(ATabbedRenderer).GetMethod("OnChildrenCollectionChanged", BindingFlags.NonPublic | BindingFlags.Instance); | |
privMethod.Invoke(this, new object[] { sender, e }); | |
} | |
void InvokeMethod(string methodName) | |
{ | |
MethodInfo privMethod = typeof(ATabbedRenderer).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); | |
privMethod.Invoke(this, new object[] { }); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment