├── .gitignore ├── CustomNavigationBarSample.Android ├── Assets │ └── AboutAssets.txt ├── CustomNavigationBarSample.Android.csproj ├── MainActivity.cs ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Renderers │ └── CustomNavigationPageRenderer.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.Designer.cs │ ├── drawable-hdpi │ │ └── icon.png │ ├── drawable-xhdpi │ │ └── icon.png │ ├── drawable-xxhdpi │ │ └── icon.png │ ├── drawable │ │ ├── icon.png │ │ └── monkeybackground.jpg │ ├── layout │ │ ├── Tabbar.axml │ │ └── Toolbar.axml │ └── values │ │ └── styles.xml └── packages.config ├── CustomNavigationBarSample.iOS ├── AppDelegate.cs ├── CustomNavigationBarSample.iOS.csproj ├── Entitlements.plist ├── Info.plist ├── Main.cs ├── Properties │ └── AssemblyInfo.cs ├── Renderers │ └── CustomPageRenderer.cs ├── Resources │ ├── Default-568h@2x.png │ ├── Default-Portrait.png │ ├── Default-Portrait@2x.png │ ├── Default.png │ ├── Default@2x.png │ ├── Icon-60@2x.png │ ├── Icon-60@3x.png │ ├── Icon-76.png │ ├── Icon-Small-40.png │ ├── Icon-Small-40@2x.png │ ├── Icon-Small-40@3x.png │ ├── Icon-Small.png │ ├── Icon-Small@2x.png │ ├── Icon-Small@3x.png │ ├── LaunchScreen.storyboard │ ├── icon.png │ └── monkeybackground.jpg ├── iTunesArtwork ├── iTunesArtwork@2x └── packages.config ├── CustomNavigationBarSample.sln ├── CustomNavigationBarSample ├── App.xaml ├── App.xaml.cs ├── BarBackgroundPage.xaml ├── BarBackgroundPage.xaml.cs ├── CustomNavigationBarSample.csproj ├── CustomNavigationPage.cs ├── CustomPage.xaml ├── CustomPage.xaml.cs ├── FormattedTitlePage.xaml ├── FormattedTitlePage.xaml.cs ├── GradientTitlePage.xaml ├── GradientTitlePage.xaml.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── Properties │ └── AssemblyInfo.cs ├── TitleBorderPage.xaml ├── TitleBorderPage.xaml.cs ├── TitleImagePage.xaml ├── TitleImagePage.xaml.cs ├── TitlePositionPage.xaml ├── TitlePositionPage.xaml.cs └── packages.config ├── LICENSE ├── README.md ├── gifs ├── android │ ├── android_full_video.gif │ ├── back_image_background_droid.gif │ ├── gradientBackground_android.gif │ ├── titleFontPosition_android.gif │ └── title_background_droid.gif └── ios │ ├── gradient_iOS.gif │ ├── opacity_ios.gif │ ├── titleFontPosition_iOS.gif │ └── title_customization_.iOS.gif └── imgs ├── android ├── formatted_text_android.png └── image_title_android.png └── ios └── title_font_position_iOS.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/CustomNavigationBarSample.Android.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8.0.30703 8 | 2.0 9 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F} 10 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 11 | Library 12 | Properties 13 | CustomNavigationBarSample.Droid 14 | CustomNavigationBarSample.Android 15 | 512 16 | true 17 | Resources\Resource.Designer.cs 18 | Off 19 | Properties\AndroidManifest.xml 20 | true 21 | v8.0 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | true 31 | full 32 | false 33 | bin\Debug\ 34 | DEBUG;TRACE 35 | prompt 36 | 4 37 | True 38 | None 39 | armeabi,armeabi-v7a,x86 40 | 41 | 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | False 49 | SdkOnly 50 | 51 | 52 | 53 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\FormsViewGroup.dll 54 | True 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ..\packages\Xamarin.Android.Arch.Core.Common.1.0.0\lib\MonoAndroid80\Xamarin.Android.Arch.Core.Common.dll 65 | True 66 | 67 | 68 | ..\packages\Xamarin.Android.Arch.Lifecycle.Common.1.0.1\lib\MonoAndroid80\Xamarin.Android.Arch.Lifecycle.Common.dll 69 | True 70 | 71 | 72 | ..\packages\Xamarin.Android.Arch.Lifecycle.Runtime.1.0.0\lib\MonoAndroid80\Xamarin.Android.Arch.Lifecycle.Runtime.dll 73 | True 74 | 75 | 76 | ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Animated.Vector.Drawable.dll 77 | True 78 | 79 | 80 | ..\packages\Xamarin.Android.Support.Annotations.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Annotations.dll 81 | True 82 | 83 | 84 | ..\packages\Xamarin.Android.Support.Compat.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Compat.dll 85 | True 86 | 87 | 88 | ..\packages\Xamarin.Android.Support.Core.UI.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Core.UI.dll 89 | True 90 | 91 | 92 | ..\packages\Xamarin.Android.Support.Core.Utils.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Core.Utils.dll 93 | True 94 | 95 | 96 | ..\packages\Xamarin.Android.Support.Design.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Design.dll 97 | True 98 | 99 | 100 | ..\packages\Xamarin.Android.Support.Fragment.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Fragment.dll 101 | True 102 | 103 | 104 | ..\packages\Xamarin.Android.Support.Media.Compat.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Media.Compat.dll 105 | True 106 | 107 | 108 | ..\packages\Xamarin.Android.Support.Transition.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Transition.dll 109 | True 110 | 111 | 112 | ..\packages\Xamarin.Android.Support.v4.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v4.dll 113 | True 114 | 115 | 116 | ..\packages\Xamarin.Android.Support.v7.AppCompat.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v7.AppCompat.dll 117 | True 118 | 119 | 120 | ..\packages\Xamarin.Android.Support.v7.CardView.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v7.CardView.dll 121 | True 122 | 123 | 124 | ..\packages\Xamarin.Android.Support.v7.MediaRouter.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v7.MediaRouter.dll 125 | True 126 | 127 | 128 | ..\packages\Xamarin.Android.Support.v7.Palette.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v7.Palette.dll 129 | True 130 | 131 | 132 | ..\packages\Xamarin.Android.Support.v7.RecyclerView.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.v7.RecyclerView.dll 133 | True 134 | 135 | 136 | ..\packages\Xamarin.Android.Support.Vector.Drawable.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Vector.Drawable.dll 137 | True 138 | 139 | 140 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Core.dll 141 | True 142 | 143 | 144 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.dll 145 | True 146 | 147 | 148 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll 149 | True 150 | 151 | 152 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll 153 | True 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | Designer 180 | 181 | 182 | 183 | 184 | 185 | {ea66853c-dfe6-4076-88dd-35397dd160df} 186 | CustomNavigationBarSample 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Android.App; 4 | using Android.Content.PM; 5 | using Android.Runtime; 6 | using Android.Views; 7 | using Android.Widget; 8 | using Android.OS; 9 | 10 | namespace CustomNavigationBarSample.Droid 11 | { 12 | [Activity(Label = "CustomNavigationBarSample", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 13 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 14 | { 15 | protected override void OnCreate(Bundle bundle) 16 | { 17 | TabLayoutResource = Resource.Layout.Tabbar; 18 | ToolbarResource = Resource.Layout.Toolbar; 19 | 20 | base.OnCreate(bundle); 21 | 22 | global::Xamarin.Forms.Forms.Init(this, bundle); 23 | LoadApplication(new App()); 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("CustomNavigationBarSample.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("CustomNavigationBarSample.Android")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | 32 | // Add some common permissions, these can be removed if not needed 33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 35 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Renderers/CustomNavigationPageRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Android.App; 6 | using Android.Content; 7 | using Android.OS; 8 | using Android.Runtime; 9 | using Android.Views; 10 | using Android.Widget; 11 | using Xamarin.Forms; 12 | using CustomNavigationBarSample; 13 | using CustomNavigationBarSample.Droid.Renderers; 14 | using Xamarin.Forms.Platform.Android.AppCompat; 15 | using Xamarin.Forms.Platform.Android; 16 | using Android.Content.Res; 17 | using Android.Support.V4.App; 18 | using Android.Text; 19 | using System.ComponentModel; 20 | using Android.Graphics.Drawables; 21 | using Android.Graphics; 22 | using static Xamarin.Forms.Platform.Android.FontExtensions; 23 | using Android.Util; 24 | using Java.Lang; 25 | using Android.Text.Style; 26 | using Android.Support.V7.Widget; 27 | 28 | [assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))] 29 | namespace CustomNavigationBarSample.Droid.Renderers 30 | { 31 | public class CustomNavigationPageRenderer : NavigationPageRenderer 32 | { 33 | Android.Support.V7.Widget.Toolbar _toolbar; 34 | LinearLayout _titleViewLayout; 35 | AppCompatTextView _titleTextView; 36 | AppCompatTextView _subTitleTextView; 37 | Android.Widget.FrameLayout _parentLayout; 38 | 39 | Drawable _originalDrawable; 40 | Drawable _originalToolbarBackground; 41 | Drawable _originalWindowContent; 42 | ColorStateList _originalColorStateList; 43 | Typeface _originalFont; 44 | 45 | public CustomNavigationPageRenderer(Context context) : base(context) 46 | { 47 | 48 | } 49 | 50 | protected override void OnConfigurationChanged(Configuration newConfig) 51 | { 52 | base.OnConfigurationChanged(newConfig); 53 | 54 | // SetupToolbarCustomization(Element?.Navigation?.NavigationStack?.Last()); 55 | } 56 | 57 | protected override void SetupPageTransition(Android.Support.V4.App.FragmentTransaction transaction, bool isPush) 58 | { 59 | Page lastPage = null; 60 | 61 | if (isPush) 62 | { 63 | if (Element?.Navigation?.NavigationStack?.Count() >= 2) 64 | { 65 | var previousPage = Element?.Navigation?.NavigationStack[Element.Navigation.NavigationStack.Count() - 2]; 66 | previousPage.PropertyChanged -= LastPage_PropertyChanged; 67 | } 68 | 69 | 70 | 71 | lastPage = Element?.Navigation?.NavigationStack?.Last(); 72 | SetupToolbarCustomization(lastPage); 73 | lastPage.PropertyChanged += LastPage_PropertyChanged; 74 | } 75 | else if (Element?.Navigation?.NavigationStack?.Count() >= 2) 76 | { 77 | var previousPage = Element?.Navigation?.NavigationStack?.Last(); 78 | previousPage.PropertyChanged -= LastPage_PropertyChanged; 79 | 80 | lastPage = Element?.Navigation?.NavigationStack[Element.Navigation.NavigationStack.Count() - 2]; 81 | lastPage.PropertyChanged += LastPage_PropertyChanged; 82 | SetupToolbarCustomization(lastPage); 83 | 84 | } 85 | 86 | 87 | base.SetupPageTransition(transaction, isPush); 88 | 89 | } 90 | 91 | private void LastPage_PropertyChanged(object sender, PropertyChangedEventArgs e) 92 | { 93 | var lastPage = sender as Page; 94 | if (e.PropertyName == CustomNavigationPage.HasShadowProperty.PropertyName) 95 | { 96 | UpdateToolbarShadow(_toolbar, CustomNavigationPage.GetHasShadow(lastPage),Context as Activity,_originalWindowContent); 97 | } 98 | else if (e.PropertyName == CustomNavigationPage.TitleBackgroundProperty.PropertyName) 99 | { 100 | UpdateTitleViewLayoutBackground(_titleViewLayout, CustomNavigationPage.GetTitleBackground(lastPage), _originalDrawable); 101 | 102 | } 103 | else if (e.PropertyName == CustomNavigationPage.BarBackgroundProperty.PropertyName) 104 | { 105 | UpdateToolbarBackground(_toolbar, lastPage, Context as Activity, _originalToolbarBackground); 106 | 107 | } 108 | else if (e.PropertyName == CustomNavigationPage.GradientColorsProperty.PropertyName) 109 | { 110 | UpdateToolbarBackground(_toolbar, lastPage, Context as Activity, _originalToolbarBackground); 111 | 112 | } 113 | else if (e.PropertyName == CustomNavigationPage.GradientDirectionProperty.PropertyName) 114 | { 115 | UpdateToolbarBackground(_toolbar, lastPage, Context as Activity, _originalToolbarBackground); 116 | 117 | } 118 | else if (e.PropertyName == CustomNavigationPage.BarBackgroundOpacityProperty.PropertyName) 119 | { 120 | UpdateToolbarBackground(_toolbar, lastPage, Context as Activity, _originalToolbarBackground); 121 | 122 | } 123 | else if (e.PropertyName == CustomNavigationPage.TitleBorderCornerRadiusProperty.PropertyName) 124 | { 125 | 126 | _titleViewLayout?.SetBackground(CreateShape(ShapeType.Rectangle, (int)CustomNavigationPage.GetTitleBorderWidth(lastPage), (int)CustomNavigationPage.GetTitleBorderCornerRadius(lastPage), CustomNavigationPage.GetTitleFillColor(lastPage), CustomNavigationPage.GetTitleBorderColor(lastPage))); 127 | 128 | } 129 | else if (e.PropertyName == CustomNavigationPage.TitleBorderWidthProperty.PropertyName) 130 | { 131 | 132 | _titleViewLayout?.SetBackground(CreateShape(ShapeType.Rectangle, (int)CustomNavigationPage.GetTitleBorderWidth(lastPage), (int)CustomNavigationPage.GetTitleBorderCornerRadius(lastPage), CustomNavigationPage.GetTitleFillColor(lastPage), CustomNavigationPage.GetTitleBorderColor(lastPage))); 133 | 134 | } 135 | else if (e.PropertyName == CustomNavigationPage.TitleBorderColorProperty.PropertyName) 136 | { 137 | 138 | _titleViewLayout?.SetBackground(CreateShape(ShapeType.Rectangle, (int)CustomNavigationPage.GetTitleBorderWidth(lastPage), (int)CustomNavigationPage.GetTitleBorderCornerRadius(lastPage), CustomNavigationPage.GetTitleFillColor(lastPage), CustomNavigationPage.GetTitleBorderColor(lastPage))); 139 | 140 | } 141 | else if (e.PropertyName == CustomNavigationPage.TitleFillColorProperty.PropertyName) 142 | { 143 | 144 | _titleViewLayout?.SetBackground(CreateShape(ShapeType.Rectangle, (int)CustomNavigationPage.GetTitleBorderWidth(lastPage), (int)CustomNavigationPage.GetTitleBorderCornerRadius(lastPage), CustomNavigationPage.GetTitleFillColor(lastPage), CustomNavigationPage.GetTitleBorderColor(lastPage))); 145 | 146 | } 147 | else if (e.PropertyName == CustomNavigationPage.TitlePositionProperty.PropertyName) 148 | { 149 | UpdateTitleViewLayoutAlignment(_titleViewLayout, _titleTextView, _subTitleTextView,CustomNavigationPage.GetTitlePosition(lastPage)); 150 | //UpdateTitleViewLayout(lastPage, _titleViewLayout, _titleTextView, _subTitleTextView, _originalDrawable); 151 | 152 | 153 | 154 | 155 | } 156 | else if (e.PropertyName == CustomNavigationPage.TitlePaddingProperty.PropertyName) 157 | { 158 | UpdateTitleViewLayoutPadding(_titleViewLayout, CustomNavigationPage.GetTitlePadding(lastPage)); 159 | } 160 | else if (e.PropertyName == CustomNavigationPage.TitleMarginProperty.PropertyName) 161 | { 162 | UpdateTitleViewLayoutMargin(_titleViewLayout, CustomNavigationPage.GetTitleMargin(lastPage)); 163 | } 164 | else if (e.PropertyName == CustomNavigationPage.TitleColorProperty.PropertyName) 165 | { 166 | UpdateToolbarTextColor(_titleTextView, CustomNavigationPage.GetTitleColor(lastPage), _originalColorStateList); 167 | 168 | } 169 | else if (e.PropertyName == CustomNavigationPage.TitleFontProperty.PropertyName) 170 | { 171 | UpdateToolbarTextFont(_titleTextView, CustomNavigationPage.GetTitleFont(lastPage), _originalFont); 172 | 173 | } 174 | else if (e.PropertyName == Page.TitleProperty.PropertyName) 175 | { 176 | UpdateTitleText(_titleTextView, lastPage.Title); 177 | 178 | } 179 | else if (e.PropertyName == CustomPage.FormattedTitleProperty.PropertyName && (lastPage is CustomPage)) 180 | { 181 | var cPage = lastPage as CustomPage; 182 | UpdateFormattedTitleText(_titleTextView, cPage.FormattedTitle,cPage.Title); 183 | 184 | } 185 | else if (e.PropertyName == CustomNavigationPage.SubtitleColorProperty.PropertyName) 186 | { 187 | UpdateToolbarTextColor(_subTitleTextView, CustomNavigationPage.GetSubtitleColor(lastPage), _originalColorStateList); 188 | 189 | } 190 | else if (e.PropertyName == CustomNavigationPage.SubtitleFontProperty.PropertyName) 191 | { 192 | UpdateToolbarTextFont(_subTitleTextView, CustomNavigationPage.GetSubtitleFont(lastPage), _originalFont); 193 | 194 | } 195 | else if (e.PropertyName == CustomPage.SubtitleProperty.PropertyName && (lastPage is CustomPage)) 196 | { 197 | var cPage = lastPage as CustomPage; 198 | if (!string.IsNullOrEmpty(cPage.Subtitle)) 199 | { 200 | _subTitleTextView.Text = cPage.Subtitle; 201 | _subTitleTextView.Visibility = ViewStates.Visible; 202 | } 203 | else 204 | { 205 | ClearTextView(_subTitleTextView, true); 206 | } 207 | 208 | } 209 | else if (e.PropertyName == CustomPage.FormattedTitleProperty.PropertyName && (lastPage is CustomPage)) 210 | { 211 | var cPage = lastPage as CustomPage; 212 | 213 | if (cPage.FormattedSubtitle != null && cPage.FormattedSubtitle.Spans.Count > 0) 214 | { 215 | _subTitleTextView.TextFormatted = cPage.FormattedSubtitle.ToAttributed(Font.Default, Xamarin.Forms.Color.Default, _subTitleTextView); 216 | 217 | _subTitleTextView.Visibility = ViewStates.Visible; 218 | } 219 | else 220 | { 221 | ClearTextView(_subTitleTextView, true); 222 | } 223 | 224 | } 225 | 226 | } 227 | public override void OnViewRemoved(Android.Views.View child) 228 | { 229 | base.OnViewRemoved(child); 230 | if (child.GetType() == typeof(Android.Support.V7.Widget.Toolbar)) 231 | { 232 | if (_toolbar != null) 233 | { 234 | var lastPage = Element?.Navigation?.NavigationStack?.Last(); 235 | _toolbar.ChildViewAdded -= OnToolbarChildViewAdded; 236 | lastPage.PropertyChanged -= LastPage_PropertyChanged; 237 | } 238 | } 239 | } 240 | public override void OnViewAdded(Android.Views.View child) 241 | { 242 | base.OnViewAdded(child); 243 | if (child.GetType() == typeof(Android.Support.V7.Widget.Toolbar)) 244 | { 245 | var lastPage = Element?.Navigation?.NavigationStack?.Last(); 246 | 247 | /*if (_toolbar !=null) 248 | { 249 | _toolbar.ChildViewAdded -= OnToolbarChildViewAdded; 250 | var lPage = Element?.Navigation?.NavigationStack?.Last(); 251 | lPage.PropertyChanged -= LastPage_PropertyChanged; 252 | }*/ 253 | 254 | _toolbar = (Android.Support.V7.Widget.Toolbar)child; 255 | _originalToolbarBackground = _toolbar.Background; 256 | 257 | var originalContent = (Context as Activity)?.Window?.DecorView?.FindViewById(Window.IdAndroidContent); 258 | if (originalContent != null) 259 | { 260 | _originalWindowContent =originalContent.Foreground; 261 | } 262 | 263 | _parentLayout = new Android.Widget.FrameLayout(_toolbar.Context) 264 | { 265 | LayoutParameters = new Android.Widget.FrameLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent) 266 | }; 267 | 268 | //Create custom title view layout 269 | _titleViewLayout = new Android.Widget.LinearLayout(_parentLayout.Context) 270 | { 271 | Orientation = Android.Widget.Orientation.Vertical, 272 | LayoutParameters = new Android.Widget.FrameLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent) 273 | }; 274 | 275 | //Create custom title text view 276 | _titleTextView = new AppCompatTextView(_parentLayout.Context) 277 | { 278 | LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent) 279 | }; 280 | 281 | //Create custom subtitle text view 282 | _subTitleTextView = new AppCompatTextView(_parentLayout.Context) 283 | { 284 | LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent) 285 | }; 286 | 287 | //Add title/subtitle to title view layout 288 | _titleViewLayout.AddView(_titleTextView); 289 | _titleViewLayout.AddView(_subTitleTextView); 290 | 291 | //Add title view layout to main layout 292 | _parentLayout.AddView(_titleViewLayout); 293 | 294 | //Add main layout to toolbar 295 | _toolbar.AddView(_parentLayout); 296 | 297 | _toolbar.ChildViewAdded += OnToolbarChildViewAdded; 298 | 299 | 300 | 301 | 302 | lastPage.PropertyChanged += LastPage_PropertyChanged; 303 | 304 | SetupToolbarCustomization(lastPage); 305 | } 306 | } 307 | 308 | void SetupToolbarCustomization(Page lastPage) 309 | { 310 | 311 | if (lastPage != null && _titleViewLayout != null) 312 | { 313 | UpdateTitleViewLayout(lastPage, _titleViewLayout, _titleTextView, _subTitleTextView, _originalDrawable); 314 | 315 | UpdateToolbarTitle(lastPage, _titleTextView,_subTitleTextView, _originalFont, _originalColorStateList); 316 | 317 | UpdateToolbarStyle(_toolbar, lastPage, Context as Activity,_originalToolbarBackground, _originalWindowContent); 318 | 319 | } 320 | } 321 | 322 | 323 | 324 | #region Title View Layout 325 | void UpdateTitleViewLayout(Page lastPage, Android.Widget.LinearLayout titleViewLayout, AppCompatTextView titleTextView, AppCompatTextView subTitleTextView, Android.Graphics.Drawables.Drawable defaultBackground) 326 | { 327 | 328 | UpdateTitleViewLayoutAlignment(titleViewLayout, titleTextView, subTitleTextView, CustomNavigationPage.GetTitlePosition(lastPage)); 329 | 330 | if (!string.IsNullOrEmpty(CustomNavigationPage.GetTitleBackground(lastPage))) 331 | { 332 | UpdateTitleViewLayoutBackground(titleViewLayout, CustomNavigationPage.GetTitleBackground(lastPage), defaultBackground); 333 | 334 | } 335 | else 336 | { 337 | _titleViewLayout?.SetBackground(CreateShape(ShapeType.Rectangle, (int)CustomNavigationPage.GetTitleBorderWidth(lastPage), (int)CustomNavigationPage.GetTitleBorderCornerRadius(lastPage), CustomNavigationPage.GetTitleFillColor(lastPage), CustomNavigationPage.GetTitleBorderColor(lastPage))); 338 | } 339 | 340 | UpdateTitleViewLayoutMargin(titleViewLayout, CustomNavigationPage.GetTitleMargin(lastPage)); 341 | 342 | UpdateTitleViewLayoutPadding(titleViewLayout, CustomNavigationPage.GetTitlePadding(lastPage)); 343 | 344 | 345 | } 346 | 347 | void UpdateTitleViewLayoutAlignment(LinearLayout titleViewLayout, AppCompatTextView titleTextView, AppCompatTextView subTitleTextView, CustomNavigationPage.TitleAlignment alignment) 348 | { 349 | var titleViewParams = titleViewLayout.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; 350 | var titleTextViewParams = titleTextView.LayoutParameters as LinearLayout.LayoutParams; 351 | var subTitleTextViewParams = subTitleTextView.LayoutParameters as LinearLayout.LayoutParams; 352 | 353 | switch (alignment) 354 | { 355 | case CustomNavigationPage.TitleAlignment.Start: 356 | titleViewParams.Gravity = GravityFlags.Start | GravityFlags.CenterVertical; 357 | titleTextViewParams.Gravity = GravityFlags.Start; 358 | subTitleTextViewParams.Gravity = GravityFlags.Start; 359 | 360 | break; 361 | case CustomNavigationPage.TitleAlignment.Center: 362 | 363 | titleViewParams.Gravity = GravityFlags.Center; 364 | titleTextViewParams.Gravity = GravityFlags.Center; 365 | subTitleTextViewParams.Gravity = GravityFlags.Center; 366 | break; 367 | case CustomNavigationPage.TitleAlignment.End: 368 | titleViewParams.Gravity = GravityFlags.End | GravityFlags.CenterVertical; 369 | titleTextViewParams.Gravity = GravityFlags.End; 370 | subTitleTextViewParams.Gravity = GravityFlags.End; 371 | break; 372 | 373 | } 374 | 375 | 376 | titleViewLayout.LayoutParameters = titleViewParams; 377 | } 378 | void UpdateTitleViewLayoutBackground(LinearLayout titleViewLayout, string backgroundResource, Android.Graphics.Drawables.Drawable defaultBackground) 379 | { 380 | 381 | if (!string.IsNullOrEmpty(backgroundResource)) 382 | { 383 | titleViewLayout?.SetBackgroundResource(this.Context.Resources.GetIdentifier(backgroundResource, "drawable", Android.App.Application.Context.PackageName)); 384 | } 385 | else 386 | { 387 | titleViewLayout?.SetBackground(defaultBackground); 388 | } 389 | } 390 | void UpdateTitleViewLayoutPadding(LinearLayout titleViewLayout, Thickness padding) 391 | { 392 | titleViewLayout?.SetPadding((int)padding.Left, (int)padding.Top, (int)padding.Right, (int)padding.Bottom); 393 | } 394 | 395 | void UpdateTitleViewLayoutMargin(LinearLayout titleViewLayout, Thickness margin) 396 | { 397 | var titleViewParams = titleViewLayout.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; 398 | 399 | titleViewParams?.SetMargins((int)margin.Left, (int)margin.Top, (int)margin.Right, (int)margin.Bottom); 400 | titleViewLayout.LayoutParameters = titleViewParams; 401 | } 402 | #endregion 403 | #region Toolbar 404 | void UpdateToolbarStyle(Android.Support.V7.Widget.Toolbar toolbar, Page lastPage, Activity activity, Android.Graphics.Drawables.Drawable defaultBackground, Android.Graphics.Drawables.Drawable windowContent) 405 | { 406 | 407 | UpdateToolbarBackground(toolbar, lastPage, activity, defaultBackground); 408 | UpdateToolbarShadow(toolbar, CustomNavigationPage.GetHasShadow(lastPage), activity, windowContent); 409 | 410 | 411 | 412 | } 413 | void UpdateToolbarBackground(Android.Support.V7.Widget.Toolbar toolbar, Page lastPage, Activity activity, Android.Graphics.Drawables.Drawable defaultBackground) 414 | { 415 | 416 | if (string.IsNullOrEmpty(CustomNavigationPage.GetBarBackground(lastPage)) && CustomNavigationPage.GetGradientColors(lastPage) == null) 417 | { 418 | 419 | toolbar.SetBackground(defaultBackground); 420 | } 421 | else 422 | { 423 | if (!string.IsNullOrEmpty(CustomNavigationPage.GetBarBackground(lastPage))) 424 | { 425 | 426 | toolbar.SetBackgroundResource(this.Context.Resources.GetIdentifier(CustomNavigationPage.GetBarBackground(lastPage), "drawable", Android.App.Application.Context.PackageName)); 427 | 428 | } 429 | 430 | if (CustomNavigationPage.GetGradientColors(lastPage) != null) 431 | { 432 | var colors = CustomNavigationPage.GetGradientColors(lastPage); 433 | var direction = GradientDrawable.Orientation.TopBottom; 434 | switch (CustomNavigationPage.GetGradientDirection(lastPage)) 435 | { 436 | case CustomNavigationPage.GradientDirection.BottomToTop: 437 | direction = GradientDrawable.Orientation.BottomTop; 438 | break; 439 | case CustomNavigationPage.GradientDirection.RightToLeft: 440 | direction = GradientDrawable.Orientation.RightLeft; 441 | break; 442 | case CustomNavigationPage.GradientDirection.LeftToRight: 443 | direction = GradientDrawable.Orientation.LeftRight; 444 | break; 445 | } 446 | 447 | GradientDrawable gradient = new GradientDrawable(direction, new int[] { colors.Item1.ToAndroid().ToArgb(), colors.Item2.ToAndroid().ToArgb() }); 448 | gradient.SetCornerRadius(0f); 449 | toolbar.SetBackground(gradient); 450 | 451 | 452 | } 453 | } 454 | toolbar.Background.SetAlpha((int)(CustomNavigationPage.GetBarBackgroundOpacity(lastPage) * 255)); 455 | 456 | } 457 | 458 | void UpdateToolbarShadow(Android.Support.V7.Widget.Toolbar toolbar, bool hasShadow, Activity activity, Android.Graphics.Drawables.Drawable windowContent) 459 | { 460 | var androidContent = activity?.Window?.DecorView?.FindViewById(Window.IdAndroidContent); 461 | if (androidContent != null) 462 | { 463 | if (hasShadow && activity != null) 464 | { 465 | 466 | GradientDrawable shadowGradient = new GradientDrawable(GradientDrawable.Orientation.RightLeft, new int[] { Android.Graphics.Color.Transparent.ToArgb(), Android.Graphics.Color.Gray.ToArgb() }); 467 | shadowGradient.SetCornerRadius(0f); 468 | 469 | 470 | androidContent.Foreground = shadowGradient; 471 | 472 | toolbar.Elevation = 4; 473 | } 474 | else 475 | { 476 | 477 | androidContent.Foreground = windowContent; 478 | 479 | toolbar.Elevation = 0; 480 | } 481 | } 482 | 483 | } 484 | #endregion 485 | #region Title TextView 486 | void UpdateToolbarTitle(Page lastPage, AppCompatTextView titleTextView, AppCompatTextView subTitleTextView, Typeface originalFont, ColorStateList defaultColorStateList) 487 | { 488 | //Check support for CustomPage 489 | if (lastPage is CustomPage) 490 | { 491 | var cPage = lastPage as CustomPage; 492 | 493 | //Update main title formatted text 494 | UpdateFormattedTitleText(titleTextView, cPage.FormattedTitle, lastPage.Title); 495 | 496 | //Update subtitle text view 497 | UpdateToolbarSubtitle(cPage, subTitleTextView, originalFont, defaultColorStateList); 498 | 499 | } 500 | else 501 | { 502 | subTitleTextView.TextFormatted = new Java.Lang.String(""); 503 | subTitleTextView.Text = string.Empty; 504 | subTitleTextView.Visibility = ViewStates.Gone; 505 | 506 | //Update main title text 507 | UpdateTitleText(titleTextView, lastPage.Title); 508 | } 509 | 510 | //Update main title color 511 | UpdateToolbarTextColor(titleTextView, CustomNavigationPage.GetTitleColor(lastPage), defaultColorStateList); 512 | 513 | //Update main title font 514 | UpdateToolbarTextFont(titleTextView, CustomNavigationPage.GetTitleFont(lastPage), originalFont); 515 | 516 | } 517 | void UpdateFormattedTitleText(AppCompatTextView titleTextView, FormattedString formattedString, string defaulTitle) 518 | { 519 | if (formattedString != null && formattedString.Spans.Count > 0) 520 | { 521 | titleTextView.TextFormatted = formattedString.ToAttributed(Font.Default, Xamarin.Forms.Color.Default, titleTextView); 522 | } 523 | else 524 | { 525 | //Update if not formatted text then update with normal title text 526 | UpdateTitleText(titleTextView, defaulTitle); 527 | } 528 | 529 | } 530 | void UpdateTitleText(AppCompatTextView titleTextView, string text) 531 | { 532 | if (!string.IsNullOrEmpty(text)) 533 | { 534 | titleTextView.Text = text; 535 | } 536 | else 537 | { 538 | titleTextView.Text = string.Empty; 539 | titleTextView.TextFormatted = new Java.Lang.String(""); 540 | } 541 | } 542 | 543 | #endregion 544 | #region Subtitle TextView 545 | void UpdateToolbarSubtitle(CustomPage cPage, AppCompatTextView subTitleTextView, Typeface originalFont, ColorStateList defaultColorStateList) 546 | { 547 | ClearTextView(subTitleTextView, true); 548 | 549 | if (cPage.FormattedSubtitle != null && cPage.FormattedSubtitle.Spans.Count > 0) 550 | { 551 | subTitleTextView.TextFormatted = cPage.FormattedSubtitle.ToAttributed(Font.Default, Xamarin.Forms.Color.Default, _subTitleTextView); 552 | 553 | subTitleTextView.Visibility = ViewStates.Visible; 554 | } 555 | else if (!string.IsNullOrEmpty(cPage.Subtitle)) 556 | { 557 | UpdateToolbarTextColor(subTitleTextView, CustomNavigationPage.GetSubtitleColor(cPage), _originalColorStateList); 558 | UpdateToolbarTextFont(subTitleTextView, CustomNavigationPage.GetSubtitleFont(cPage), _originalFont); 559 | 560 | subTitleTextView.Text = cPage.Subtitle; 561 | subTitleTextView.Visibility = ViewStates.Visible; 562 | } 563 | } 564 | #endregion 565 | #region General TextView 566 | void UpdateToolbarTextColor(AppCompatTextView textView, Xamarin.Forms.Color? titleColor, ColorStateList defaultColorStateList) 567 | { 568 | if (titleColor != null) 569 | { 570 | textView.SetTextColor(titleColor?.ToAndroid() ?? Android.Graphics.Color.White); 571 | } 572 | else 573 | { 574 | textView.SetTextColor(defaultColorStateList); 575 | } 576 | } 577 | void UpdateToolbarTextFont(AppCompatTextView textView, Font customFont, Typeface originalFont) 578 | { 579 | if (customFont != null) 580 | { 581 | textView.Typeface =customFont.ToTypeface(); 582 | 583 | float tValue = customFont.ToScaledPixel(); 584 | textView.SetTextSize(ComplexUnitType.Sp, tValue); 585 | } 586 | else 587 | { 588 | textView.Typeface = originalFont; 589 | } 590 | } 591 | void ClearTextView(TextView textView, bool hide) 592 | { 593 | textView.TextFormatted = new Java.Lang.String(""); 594 | textView.Text = string.Empty; 595 | if (hide) 596 | { 597 | textView.Visibility = ViewStates.Gone; 598 | } 599 | 600 | } 601 | #endregion 602 | 603 | Drawable CreateShape(ShapeType type,int strokeWidth,int cornerRadius,Xamarin.Forms.Color? fillColor,Xamarin.Forms.Color? strokeColor) 604 | { 605 | GradientDrawable shape = new GradientDrawable(); 606 | shape.SetShape(type); 607 | if(fillColor !=null) 608 | { 609 | shape.SetColor(fillColor?.ToAndroid() ?? Xamarin.Forms.Color.Transparent.ToAndroid()); 610 | } 611 | 612 | if (strokeColor != null) 613 | { 614 | shape.SetStroke(strokeWidth, strokeColor?.ToAndroid()??Xamarin.Forms.Color.Transparent.ToAndroid()); 615 | } 616 | 617 | 618 | shape.SetCornerRadius(cornerRadius); 619 | 620 | return shape; 621 | } 622 | 623 | 624 | protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 625 | { 626 | base.OnElementPropertyChanged(sender, e); 627 | 628 | } 629 | private void OnToolbarChildViewAdded(object sender, ChildViewAddedEventArgs e) 630 | { 631 | var view = e.Child.GetType(); 632 | 633 | if (e.Child.GetType() == typeof(AppCompatTextView)) 634 | { 635 | 636 | var textView = (AppCompatTextView)e.Child; 637 | textView.Visibility = ViewStates.Gone; 638 | _originalDrawable = textView.Background; 639 | _originalFont = textView.Typeface; 640 | _originalColorStateList = textView.TextColors; 641 | 642 | var lastPage = Element?.Navigation?.NavigationStack?.Last(); 643 | SetupToolbarCustomization(lastPage); 644 | 645 | 646 | 647 | } 648 | } 649 | 650 | } 651 | } 652 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.Android/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.Android/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.Android/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.Android/Resources/drawable/icon.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/drawable/monkeybackground.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.Android/Resources/drawable/monkeybackground.jpg -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/layout/Tabbar.axml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/layout/Toolbar.axml: -------------------------------------------------------------------------------- 1 | 2 | 19 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 26 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.Android/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace CustomNavigationBarSample.iOS 9 | { 10 | // The UIApplicationDelegate for the application. This class is responsible for launching the 11 | // User Interface of the application, as well as listening (and optionally responding) to 12 | // application events from iOS. 13 | [Register("AppDelegate")] 14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 15 | { 16 | // 17 | // This method is invoked when the application has loaded and is ready to run. In this 18 | // method you should instantiate the window, load the UI into it and then make the window 19 | // visible. 20 | // 21 | // You have 17 seconds to return from this method, or iOS will terminate your application. 22 | // 23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 24 | { 25 | global::Xamarin.Forms.Forms.Init(); 26 | LoadApplication(new App()); 27 | 28 | return base.FinishedLaunching(app, options); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/CustomNavigationBarSample.iOS.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | iPhoneSimulator 7 | 8.0.30703 8 | 2.0 9 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03} 10 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 11 | Exe 12 | CustomNavigationBarSample.iOS 13 | Resources 14 | CustomNavigationBarSample.iOS 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\iPhoneSimulator\Debug 23 | DEBUG 24 | prompt 25 | 4 26 | false 27 | i386, x86_64 28 | None 29 | true 30 | 31 | 32 | none 33 | true 34 | bin\iPhoneSimulator\Release 35 | prompt 36 | 4 37 | None 38 | i386, x86_64 39 | false 40 | 41 | 42 | true 43 | full 44 | false 45 | bin\iPhone\Debug 46 | DEBUG 47 | prompt 48 | 4 49 | false 50 | ARMv7, ARM64 51 | iPhone Developer 52 | true 53 | Entitlements.plist 54 | 55 | 56 | none 57 | true 58 | bin\iPhone\Release 59 | prompt 60 | 4 61 | ARMv7, ARM64 62 | false 63 | iPhone Developer 64 | Entitlements.plist 65 | 66 | 67 | none 68 | True 69 | bin\iPhone\Ad-Hoc 70 | prompt 71 | 4 72 | False 73 | ARMv7, ARM64 74 | True 75 | Automatic:AdHoc 76 | iPhone Distribution 77 | Entitlements.plist 78 | 79 | 80 | none 81 | True 82 | bin\iPhone\AppStore 83 | prompt 84 | 4 85 | False 86 | ARMv7, ARM64 87 | Automatic:AppStore 88 | iPhone Distribution 89 | Entitlements.plist 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll 126 | 127 | 128 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll 129 | 130 | 131 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll 132 | 133 | 134 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll 135 | 136 | 137 | 138 | 139 | 140 | {ea66853c-dfe6-4076-88dd-35397dd160df} 141 | CustomNavigationBarSample 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UISupportedInterfaceOrientations 11 | 12 | UIInterfaceOrientationPortrait 13 | UIInterfaceOrientationLandscapeLeft 14 | UIInterfaceOrientationLandscapeRight 15 | 16 | UISupportedInterfaceOrientations~ipad 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationPortraitUpsideDown 20 | UIInterfaceOrientationLandscapeLeft 21 | UIInterfaceOrientationLandscapeRight 22 | 23 | MinimumOSVersion 24 | 8.0 25 | CFBundleDisplayName 26 | CustomNavigationBarSample 27 | CFBundleIdentifier 28 | com.crossgeeks.customnavigationbarsample 29 | CFBundleVersion 30 | 1.0 31 | CFBundleIconFiles 32 | 33 | Icon-60@2x 34 | Icon-60@3x 35 | Icon-76 36 | Icon-76@2x 37 | Default 38 | Default@2x 39 | Default-568h@2x 40 | Default-Portrait 41 | Default-Portrait@2x 42 | Icon-Small-40 43 | Icon-Small-40@2x 44 | Icon-Small-40@3x 45 | Icon-Small 46 | Icon-Small@2x 47 | Icon-Small@3x 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | 52 | 53 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace CustomNavigationBarSample.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CustomNavigationBarSample.iOS")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CustomNavigationBarSample.iOS")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Renderers/CustomPageRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Foundation; 7 | using UIKit; 8 | using Xamarin.Forms; 9 | using Xamarin.Forms.Platform.iOS; 10 | using CustomNavigationBarSample; 11 | using CustomNavigationBarSample.iOS.Renderers; 12 | using CoreGraphics; 13 | using CoreAnimation; 14 | 15 | [assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))] 16 | 17 | namespace CustomNavigationBarSample.iOS.Renderers 18 | { 19 | public class CustomPageRenderer : PageRenderer 20 | { 21 | UILabel titleLabel; 22 | UILabel subtitleLabel; 23 | UIView containerView; 24 | UIView titleView; 25 | UIView marginView; 26 | nfloat lastNavBarHeight = 0.0f; 27 | nfloat lastNavBarWidth = 0.0f; 28 | protected override void OnElementChanged(VisualElementChangedEventArgs e) 29 | { 30 | base.OnElementChanged(e); 31 | System.Diagnostics.Debug.WriteLine("Element"); 32 | } 33 | public override void ViewWillAppear(bool animated) 34 | { 35 | base.ViewWillAppear(animated); 36 | 37 | SetupNavBar(NavigationController.NavigationBar.Bounds.Size); 38 | SetTitlePosition(CustomNavigationPage.GetTitlePosition(Element), CustomNavigationPage.GetTitlePadding(Element), CustomNavigationPage.GetTitleMargin(Element), new CGRect(0, 0, Math.Max(subtitleLabel.IntrinsicContentSize.Width, titleLabel.IntrinsicContentSize.Width), (titleLabel.IntrinsicContentSize.Height + subtitleLabel.IntrinsicContentSize.Height + (subtitleLabel.IntrinsicContentSize.Height > 0.0f ? 3.0f : 0.0f)))); 39 | 40 | System.Diagnostics.Debug.WriteLine("Preparing"); 41 | } 42 | public override void ViewWillLayoutSubviews() 43 | { 44 | base.ViewWillLayoutSubviews(); 45 | System.Diagnostics.Debug.WriteLine("SubViews"); 46 | } 47 | public override void ViewDidLayoutSubviews() 48 | { 49 | base.ViewDidLayoutSubviews(); 50 | if(lastNavBarWidth != NavigationController?.NavigationBar?.Bounds.Size.Width || lastNavBarHeight != NavigationController?.NavigationBar?.Bounds.Size.Height) 51 | { 52 | lastNavBarHeight = NavigationController?.NavigationBar?.Bounds.Size.Height ?? 0.0f; 53 | lastNavBarWidth = NavigationController?.NavigationBar?.Bounds.Size.Width ?? 0.0f; 54 | SetupNavBar(new CGSize(lastNavBarWidth, lastNavBarHeight)); 55 | 56 | } 57 | 58 | SetTitlePosition( CustomNavigationPage.GetTitlePosition(Element), CustomNavigationPage.GetTitlePadding(Element),CustomNavigationPage.GetTitleMargin(Element), new CGRect(0, 0, Math.Max(subtitleLabel.IntrinsicContentSize.Width, titleLabel.IntrinsicContentSize.Width), (titleLabel.IntrinsicContentSize.Height + subtitleLabel.IntrinsicContentSize.Height + (subtitleLabel.IntrinsicContentSize.Height > 0.0f ? 3.0f : 0.0f)))); 59 | 60 | System.Diagnostics.Debug.WriteLine("didSubViews"); 61 | 62 | 63 | 64 | } 65 | void SetupNavBar(CGSize size) 66 | { 67 | if (NavigationController != null && titleView != null) 68 | { 69 | var page = Element as Page; 70 | containerView.Frame = new CGRect(0, 0, size.Width, size.Height); 71 | 72 | 73 | titleView.Layer.BorderWidth = CustomNavigationPage.GetTitleBorderWidth(Element); 74 | 75 | titleView.Layer.CornerRadius = CustomNavigationPage.GetTitleBorderCornerRadius(Element); 76 | 77 | titleView.Layer.BorderColor = CustomNavigationPage.GetTitleBorderColor(Element)?.ToCGColor() ?? UIColor.Clear.CGColor; 78 | 79 | 80 | 81 | SetupTextFont(titleLabel, CustomNavigationPage.GetTitleFont(page), CustomNavigationPage.GetTitleColor(page)); 82 | 83 | SetupBackground(); 84 | 85 | if (!string.IsNullOrEmpty(CustomNavigationPage.GetTitleBackground(Element))) 86 | { 87 | try 88 | { 89 | 90 | var image = UIImage.FromBundle(CustomNavigationPage.GetTitleBackground(Element)); 91 | titleView.Frame = new CGRect(titleView.Frame.X, titleView.Frame.Y, titleView.Frame.Width == 0?Math.Min(size.Width,image.Size.Width): Math.Min(titleView.Frame.Width, image.Size.Width), titleView.Frame.Height == 0 ? Math.Min(size.Height, image.Size.Height) : Math.Min(titleView.Frame.Height, image.Size.Height)); 92 | 93 | titleView.BackgroundColor = UIColor.FromPatternImage(image); 94 | 95 | } 96 | catch (Exception ex) 97 | { 98 | titleView.BackgroundColor = CustomNavigationPage.GetTitleFillColor(Element)?.ToUIColor() ?? UIColor.Clear; 99 | 100 | } 101 | 102 | } 103 | else 104 | { 105 | titleView.BackgroundColor = CustomNavigationPage.GetTitleFillColor(Element)?.ToUIColor() ?? UIColor.Clear; 106 | } 107 | 108 | 109 | ParentViewController.NavigationItem.TitleView = containerView; 110 | ParentViewController.NavigationItem.TitleView.SetNeedsDisplay(); 111 | } 112 | } 113 | 114 | public override void ViewDidLoad() 115 | { 116 | base.ViewDidLoad(); 117 | containerView = new UIView() 118 | { 119 | AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth 120 | }; 121 | 122 | titleView = new UIView() 123 | { 124 | 125 | }; 126 | 127 | marginView = new UIView() 128 | { 129 | 130 | }; 131 | 132 | titleLabel = new UILabel() 133 | { 134 | Text = Title 135 | 136 | }; 137 | 138 | subtitleLabel = new UILabel() 139 | { 140 | Hidden = true 141 | }; 142 | 143 | titleView.Add(titleLabel); 144 | titleView.Add(subtitleLabel); 145 | marginView.Add(titleView); 146 | containerView.Add(marginView); 147 | 148 | Element.PropertyChanged += Element_PropertyChanged; 149 | } 150 | public override void ViewDidAppear(bool animated) 151 | { 152 | base.ViewDidAppear(animated); 153 | 154 | } 155 | void SetTitlePosition( CustomNavigationPage.TitleAlignment alignment,Thickness padding, Thickness margin, CGRect vFrame) 156 | { 157 | 158 | var marginX = margin.Top; 159 | var marginY = margin.Left; 160 | var marginWidth = margin.Left + margin.Right; 161 | var marginHeight = margin.Top + margin.Bottom; 162 | var paddingWidth = padding.Left + padding.Right; 163 | var paddingHeight = padding.Top + padding.Bottom; 164 | var paddingX = padding.Left; 165 | var paddingY = padding.Top; 166 | 167 | if(CustomNavigationPage.GetTitleBackground(Element) !=null && vFrame.Width == 0 && vFrame.Height == 0) 168 | { 169 | vFrame = titleView.Frame; 170 | } 171 | 172 | 173 | marginView.Frame = new CGRect(vFrame.X, vFrame.Y, vFrame.Width, vFrame.Height); 174 | 175 | 176 | 177 | 178 | double offset = 0; 179 | 180 | titleLabel.AutoresizingMask = UIViewAutoresizing.All; 181 | switch (alignment) 182 | { 183 | case CustomNavigationPage.TitleAlignment.Start: 184 | marginView.Frame = new CGRect( vFrame.X, marginView.Frame.Y, marginView.Bounds.Width + marginWidth + paddingWidth, marginView.Bounds.Height + marginHeight + paddingHeight); 185 | var startCenter = marginView.Center; 186 | startCenter.Y = marginView.Superview.Center.Y; 187 | marginView.Center = startCenter; 188 | titleLabel.TextAlignment = UITextAlignment.Left; 189 | subtitleLabel.TextAlignment = UITextAlignment.Left; 190 | offset = marginX; 191 | break; 192 | case CustomNavigationPage.TitleAlignment.Center: 193 | offset = marginX; 194 | marginView.Frame = new CGRect(marginView.Frame.X , marginView.Frame.Y , marginView.Bounds.Width + marginWidth + paddingWidth, marginView.Bounds.Height + marginHeight + paddingHeight); 195 | marginView.Center = marginView.Superview.Center; 196 | titleLabel.TextAlignment = UITextAlignment.Center; 197 | subtitleLabel.TextAlignment = UITextAlignment.Center; 198 | break; 199 | case CustomNavigationPage.TitleAlignment.End: 200 | 201 | var endCenter = marginView.Center; 202 | endCenter.Y = marginView.Superview.Center.Y; 203 | marginView.Center = endCenter; 204 | 205 | titleLabel.TextAlignment = UITextAlignment.Right; 206 | subtitleLabel.TextAlignment = UITextAlignment.Right; 207 | marginView.Frame = new CGRect(marginView.Superview.Frame.Width - marginView.Frame.Width - offset -marginWidth-paddingWidth, marginView.Frame.Y , marginView.Bounds.Width + marginWidth + paddingWidth, marginView.Bounds.Height +marginHeight + paddingHeight); 208 | offset = marginView.Frame.Width - vFrame.Width - paddingWidth - marginX; 209 | break; 210 | } 211 | 212 | titleView.Frame = new CGRect(offset , vFrame.Y + marginY, vFrame.Width + paddingWidth, vFrame.Height + paddingHeight); 213 | 214 | var cPage = Element as CustomPage; 215 | 216 | 217 | 218 | if (cPage != null && (!string.IsNullOrEmpty(cPage.Subtitle) || (cPage.FormattedSubtitle != null && cPage.FormattedSubtitle.Spans.Count > 0))) 219 | { 220 | 221 | 222 | titleLabel.Frame = new CGRect(paddingX, paddingY, titleView.Frame.Width , titleLabel.IntrinsicContentSize.Height); 223 | 224 | 225 | subtitleLabel.Frame = new CGRect(titleLabel.Frame.X, titleLabel.Frame.Y+titleLabel.Frame.Height + 3, titleView.Frame.Width, subtitleLabel.Frame.Height); 226 | 227 | } 228 | else 229 | { 230 | 231 | titleLabel.Frame = new CGRect(paddingX, paddingY, titleLabel.IntrinsicContentSize.Width, titleLabel.IntrinsicContentSize.Height ); 232 | 233 | } 234 | 235 | } 236 | 237 | public override void ViewWillTransitionToSize(CGSize toSize, IUIViewControllerTransitionCoordinator coordinator) 238 | { 239 | base.ViewWillTransitionToSize(toSize, coordinator); 240 | SetupNavBar(new CGSize(NavigationController?.NavigationBar?.Bounds.Size.Width ?? 0.0f, NavigationController?.NavigationBar?.Bounds.Height ?? 0.0f)); 241 | 242 | 243 | } 244 | UIImage CreateGradientBackground(Color startColor, Color endColor, CustomNavigationPage.GradientDirection direction) 245 | { 246 | var gradientLayer = new CAGradientLayer(); 247 | gradientLayer.Bounds = NavigationController.NavigationBar.Bounds; 248 | gradientLayer.Colors = new CGColor[] { startColor.ToCGColor(), endColor.ToCGColor() }; 249 | 250 | switch(direction) 251 | { 252 | case CustomNavigationPage.GradientDirection.LeftToRight: 253 | gradientLayer.StartPoint = new CGPoint(0.0, 0.5); 254 | gradientLayer.EndPoint = new CGPoint(1.0, 0.5); 255 | break; 256 | case CustomNavigationPage.GradientDirection.RightToLeft: 257 | gradientLayer.StartPoint = new CGPoint(1.0, 0.5); 258 | gradientLayer.EndPoint = new CGPoint(0.0, 0.5); 259 | break; 260 | case CustomNavigationPage.GradientDirection.BottomToTop: 261 | gradientLayer.StartPoint = new CGPoint(1.0, 1.0); 262 | gradientLayer.EndPoint = new CGPoint(0.0, 0.0); 263 | break; 264 | default: 265 | gradientLayer.StartPoint = new CGPoint(1.0, 0.0); 266 | gradientLayer.EndPoint = new CGPoint(0.0, 1.0); 267 | break; 268 | } 269 | 270 | UIGraphics.BeginImageContext(gradientLayer.Bounds.Size); 271 | gradientLayer.RenderInContext(UIGraphics.GetCurrentContext()); 272 | UIImage image = UIGraphics.GetImageFromCurrentImageContext(); 273 | UIGraphics.EndImageContext(); 274 | 275 | 276 | return image; 277 | 278 | } 279 | public override void ViewDidDisappear(bool animated) 280 | { 281 | base.ViewDidDisappear(animated); 282 | } 283 | void SetupShadow(bool hasShadow) 284 | { 285 | if(hasShadow) 286 | { 287 | NavigationController.NavigationBar.Layer.ShadowColor = UIColor.Gray.CGColor; 288 | NavigationController.NavigationBar.Layer.ShadowOffset = new CGSize(0, 0); 289 | NavigationController.NavigationBar.Layer.ShadowOpacity = 1; 290 | } 291 | else 292 | { 293 | NavigationController.NavigationBar.Layer.ShadowColor = UIColor.Clear.CGColor; 294 | NavigationController.NavigationBar.Layer.ShadowOffset = new CGSize(0, 0); 295 | NavigationController.NavigationBar.Layer.ShadowOpacity = 0; 296 | } 297 | 298 | } 299 | 300 | void SetupBackground(UIImage image,float alpha) 301 | { 302 | NavigationController.NavigationBar.SetBackgroundImage(image, UIBarMetrics.Default); 303 | NavigationController.NavigationBar.Alpha = alpha; 304 | } 305 | void SetupBackground() 306 | { 307 | if (string.IsNullOrEmpty(CustomNavigationPage.GetBarBackground(Element)) && CustomNavigationPage.GetGradientColors(Element) == null) 308 | { 309 | 310 | SetupBackground(null, CustomNavigationPage.GetBarBackgroundOpacity(Element)); 311 | } 312 | else 313 | { 314 | if (!string.IsNullOrEmpty(CustomNavigationPage.GetBarBackground(Element))) 315 | { 316 | SetupBackground(UIImage.FromBundle(CustomNavigationPage.GetBarBackground(Element)), CustomNavigationPage.GetBarBackgroundOpacity(Element)); 317 | } 318 | else if (CustomNavigationPage.GetGradientColors(Element) != null) 319 | { 320 | SetupBackground(CreateGradientBackground(CustomNavigationPage.GetGradientColors(Element).Item1, CustomNavigationPage.GetGradientColors(Element).Item2, CustomNavigationPage.GetGradientDirection(Element)), CustomNavigationPage.GetBarBackgroundOpacity(Element)); 321 | 322 | } 323 | } 324 | } 325 | 326 | void SetupTextFont(UILabel label,Font font,Color? titleColor) 327 | { 328 | 329 | var cPage = Element as CustomPage; 330 | if (cPage!=null && cPage.FormattedTitle != null && cPage.FormattedTitle.Spans.Count > 0) 331 | { 332 | SetupFormattedText(titleLabel, cPage.FormattedTitle, cPage.Title); 333 | } 334 | else 335 | { 336 | SetupText(label, (Element as Page).Title,titleColor, CustomNavigationPage.GetTitleFont(Element)); 337 | 338 | } 339 | 340 | if (cPage != null && cPage.FormattedSubtitle != null && cPage.FormattedSubtitle.Spans.Count > 0) 341 | { 342 | subtitleLabel.Hidden = false; 343 | SetupFormattedText(subtitleLabel, cPage.FormattedSubtitle, cPage.Subtitle); 344 | 345 | } 346 | else if (cPage != null && !string.IsNullOrEmpty(cPage.Subtitle)) 347 | { 348 | subtitleLabel.Hidden = false; 349 | SetupText(subtitleLabel, cPage.Subtitle, CustomNavigationPage.GetSubtitleColor(cPage), CustomNavigationPage.GetSubtitleFont(Element)); 350 | 351 | subtitleLabel.SetNeedsDisplay(); 352 | } 353 | else 354 | { 355 | subtitleLabel.Text = string.Empty; 356 | subtitleLabel.Frame = CGRect.Empty; 357 | subtitleLabel.Hidden = true; 358 | } 359 | 360 | 361 | label.SizeToFit(); 362 | subtitleLabel.SizeToFit(); 363 | titleView.SizeToFit(); 364 | 365 | } 366 | void SetupTextColor(UILabel label,UIColor color) 367 | { 368 | label.TextColor = color; 369 | } 370 | 371 | void SetupFormattedText(UILabel label, FormattedString formattedString, string defaulTitle) 372 | { 373 | label.AttributedText = formattedString.ToAttributed(Font.Default, Xamarin.Forms.Color.Default); 374 | label.SetNeedsDisplay(); 375 | } 376 | 377 | void SetupText(UILabel label, string text,Color? textColor, Font font) 378 | { 379 | 380 | if (!string.IsNullOrEmpty(text)) 381 | { 382 | label.Text = text; 383 | } 384 | else 385 | { 386 | label.Text = string.Empty; 387 | label.AttributedText = new NSAttributedString(); 388 | } 389 | 390 | if(textColor !=null) 391 | { 392 | label.TextColor = textColor?.ToUIColor(); 393 | } 394 | 395 | label.Font = font.ToUIFont(); 396 | } 397 | private void Element_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 398 | { 399 | var page = sender as Page; 400 | System.Diagnostics.Debug.WriteLine(e.PropertyName); 401 | if (e.PropertyName == Page.TitleProperty.PropertyName || e.PropertyName == CustomNavigationPage.TitleFontProperty.PropertyName || e.PropertyName == CustomPage.SubtitleProperty.PropertyName || e.PropertyName == CustomNavigationPage.SubtitleFontProperty.PropertyName) 402 | { 403 | SetupTextFont(titleLabel, CustomNavigationPage.GetTitleFont(page), CustomNavigationPage.GetTitleColor(page)); 404 | 405 | SetTitlePosition(CustomNavigationPage.GetTitlePosition(page), CustomNavigationPage.GetTitlePadding(Element), CustomNavigationPage.GetTitleMargin(Element), new CGRect(0, 0, Math.Max(subtitleLabel.IntrinsicContentSize.Width, titleLabel.IntrinsicContentSize.Width), (titleLabel.IntrinsicContentSize.Height + subtitleLabel.IntrinsicContentSize.Height + (subtitleLabel.IntrinsicContentSize.Height > 0.0f ? 3.0f : 0.0f)))); 406 | 407 | } 408 | else if (e.PropertyName == CustomNavigationPage.TitleColorProperty.PropertyName) 409 | { 410 | var color =CustomNavigationPage.GetTitleColor(page); 411 | if (color !=null) 412 | { 413 | titleLabel.TextColor = color?.ToUIColor(); 414 | } 415 | 416 | 417 | } 418 | else if (e.PropertyName == CustomNavigationPage.SubtitleColorProperty.PropertyName) 419 | { 420 | var color = CustomNavigationPage.GetSubtitleColor(page); 421 | if (color != null) 422 | { 423 | subtitleLabel.TextColor = color?.ToUIColor(); 424 | } 425 | 426 | 427 | } 428 | else if (e.PropertyName == CustomNavigationPage.TitlePositionProperty.PropertyName || e.PropertyName == CustomNavigationPage.TitlePaddingProperty.PropertyName || e.PropertyName == CustomNavigationPage.TitleMarginProperty.PropertyName) 429 | { 430 | 431 | SetTitlePosition(CustomNavigationPage.GetTitlePosition(Element), CustomNavigationPage.GetTitlePadding(Element), CustomNavigationPage.GetTitleMargin(Element), new CGRect(0, 0, Math.Max(subtitleLabel.IntrinsicContentSize.Width, titleLabel.IntrinsicContentSize.Width), (titleLabel.IntrinsicContentSize.Height + subtitleLabel.IntrinsicContentSize.Height + (subtitleLabel.IntrinsicContentSize.Height > 0.0f ? 3.0f : 0.0f)))); 432 | 433 | 434 | } 435 | else if (e.PropertyName == CustomNavigationPage.GradientColorsProperty.PropertyName || e.PropertyName == CustomNavigationPage.GradientDirectionProperty.PropertyName || e.PropertyName == CustomNavigationPage.BarBackgroundProperty.PropertyName || e.PropertyName == CustomNavigationPage.BarBackgroundOpacityProperty.PropertyName) 436 | { 437 | SetupBackground(); 438 | 439 | } 440 | else if (e.PropertyName == CustomNavigationPage.HasShadowProperty.PropertyName) 441 | { 442 | SetupShadow(CustomNavigationPage.GetHasShadow(page)); 443 | 444 | } 445 | else if (e.PropertyName == CustomPage.FormattedTitleProperty.PropertyName && (page is CustomPage)) 446 | { 447 | var cPage = page as CustomPage; 448 | SetupFormattedText(titleLabel, cPage.FormattedTitle, cPage.Title); 449 | 450 | }else if (e.PropertyName == CustomNavigationPage.TitleBackgroundProperty.PropertyName) 451 | { 452 | if (!string.IsNullOrEmpty(CustomNavigationPage.GetTitleBackground(Element))) 453 | { 454 | titleView.BackgroundColor = UIColor.FromPatternImage(UIImage.FromBundle(CustomNavigationPage.GetTitleBackground(Element))); 455 | 456 | } 457 | else 458 | { 459 | titleView.BackgroundColor = null; 460 | } 461 | } 462 | else if (e.PropertyName == CustomNavigationPage.TitleBorderWidthProperty.PropertyName) 463 | { 464 | titleView.Layer.BorderWidth = CustomNavigationPage.GetTitleBorderWidth(Element); 465 | } 466 | else if (e.PropertyName == CustomNavigationPage.TitleBorderCornerRadiusProperty.PropertyName) 467 | { 468 | titleView.Layer.CornerRadius = CustomNavigationPage.GetTitleBorderCornerRadius(Element); 469 | } 470 | else if (e.PropertyName == CustomNavigationPage.TitleBorderColorProperty.PropertyName) 471 | { 472 | titleView.Layer.BorderColor = CustomNavigationPage.GetTitleBorderColor(Element)?.ToCGColor()??UIColor.Clear.CGColor; 473 | } 474 | else if (e.PropertyName == CustomNavigationPage.TitleFillColorProperty.PropertyName) 475 | { 476 | titleView.BackgroundColor = CustomNavigationPage.GetTitleFillColor(Element)?.ToUIColor() ?? UIColor.Clear; 477 | } 478 | } 479 | 480 | public override void ViewDidUnload() 481 | { 482 | base.ViewDidUnload(); 483 | titleLabel = null; 484 | subtitleLabel = null; 485 | Element.PropertyChanged -= Element_PropertyChanged; 486 | } 487 | } 488 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Default.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Default@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-60@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-60@3x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-76.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small-40.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small-40@3x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small@2x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/Icon-Small@3x.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/icon.png -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/Resources/monkeybackground.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/Resources/monkeybackground.jpg -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/iTunesArtwork: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/iTunesArtwork -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/iTunesArtwork@2x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/CustomNavigationBarSample.iOS/iTunesArtwork@2x -------------------------------------------------------------------------------- /CustomNavigationBarSample.iOS/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /CustomNavigationBarSample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomNavigationBarSample.Android", "CustomNavigationBarSample.Android\CustomNavigationBarSample.Android.csproj", "{6B94F8A4-A80D-4765-AE3A-69FFA080E18F}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomNavigationBarSample", "CustomNavigationBarSample\CustomNavigationBarSample.csproj", "{552B83D3-223E-4BFB-A758-404C249102AF}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomNavigationBarSample.iOS", "CustomNavigationBarSample.iOS\CustomNavigationBarSample.iOS.csproj", "{84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Ad-Hoc|Any CPU = Ad-Hoc|Any CPU 15 | Ad-Hoc|iPhone = Ad-Hoc|iPhone 16 | Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator 17 | AppStore|Any CPU = AppStore|Any CPU 18 | AppStore|iPhone = AppStore|iPhone 19 | AppStore|iPhoneSimulator = AppStore|iPhoneSimulator 20 | Debug|Any CPU = Debug|Any CPU 21 | Debug|iPhone = Debug|iPhone 22 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 23 | Release|Any CPU = Release|Any CPU 24 | Release|iPhone = Release|iPhone 25 | Release|iPhoneSimulator = Release|iPhoneSimulator 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU 29 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU 30 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU 31 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU 32 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU 33 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU 34 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU 35 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU 36 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU 37 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU 38 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|Any CPU.Build.0 = Release|Any CPU 39 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|Any CPU.Deploy.0 = Release|Any CPU 40 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhone.ActiveCfg = Release|Any CPU 41 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhone.Build.0 = Release|Any CPU 42 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhone.Deploy.0 = Release|Any CPU 43 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU 44 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU 45 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU 46 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 49 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhone.ActiveCfg = Debug|Any CPU 50 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhone.Build.0 = Debug|Any CPU 51 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhone.Deploy.0 = Debug|Any CPU 52 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 53 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 54 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU 55 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|Any CPU.Deploy.0 = Release|Any CPU 58 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhone.ActiveCfg = Release|Any CPU 59 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhone.Build.0 = Release|Any CPU 60 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhone.Deploy.0 = Release|Any CPU 61 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 62 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 63 | {6B94F8A4-A80D-4765-AE3A-69FFA080E18F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU 64 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU 65 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU 66 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU 67 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU 68 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU 69 | {552B83D3-223E-4BFB-A758-404C249102AF}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU 70 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|Any CPU.ActiveCfg = Release|Any CPU 71 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|Any CPU.Build.0 = Release|Any CPU 72 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|iPhone.ActiveCfg = Release|Any CPU 73 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|iPhone.Build.0 = Release|Any CPU 74 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU 75 | {552B83D3-223E-4BFB-A758-404C249102AF}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU 76 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 77 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 78 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|iPhone.ActiveCfg = Debug|Any CPU 79 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|iPhone.Build.0 = Debug|Any CPU 80 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 81 | {552B83D3-223E-4BFB-A758-404C249102AF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 82 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 83 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|Any CPU.Build.0 = Release|Any CPU 84 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|iPhone.ActiveCfg = Release|Any CPU 85 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|iPhone.Build.0 = Release|Any CPU 86 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 87 | {552B83D3-223E-4BFB-A758-404C249102AF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 88 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone 89 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone 90 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone 91 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator 92 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator 93 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone 94 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.AppStore|iPhone.ActiveCfg = AppStore|iPhone 95 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.AppStore|iPhone.Build.0 = AppStore|iPhone 96 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator 97 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator 98 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Debug|Any CPU.ActiveCfg = Debug|iPhone 99 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Debug|iPhone.ActiveCfg = Debug|iPhone 100 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Debug|iPhone.Build.0 = Debug|iPhone 101 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator 102 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator 103 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Release|Any CPU.ActiveCfg = Release|iPhone 104 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Release|iPhone.ActiveCfg = Release|iPhone 105 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Release|iPhone.Build.0 = Release|iPhone 106 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator 107 | {84ED5E5E-FD31-4DD5-98CC-131BA0BDED03}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator 108 | EndGlobalSection 109 | GlobalSection(SolutionProperties) = preSolution 110 | HideSolutionNode = FALSE 111 | EndGlobalSection 112 | GlobalSection(ExtensibilityGlobals) = postSolution 113 | SolutionGuid = {E8876259-2F08-436A-AD0E-E1214EA9CE56} 114 | EndGlobalSection 115 | EndGlobal 116 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Xamarin.Forms; 7 | 8 | namespace CustomNavigationBarSample 9 | { 10 | public partial class App : Application 11 | { 12 | public static List> Colors = new List> 13 | { 14 | new Tuple("Default", Color.Default), 15 | new Tuple("Amber", Color.FromHex("#FFC107")), 16 | new Tuple("Black", Color.FromHex("#212121")), 17 | new Tuple("Blue", Color.FromHex("#2196F3")), 18 | new Tuple("Blue Grey", Color.FromHex("#607D8B")), 19 | new Tuple("Brown", Color.FromHex("#795548")), 20 | new Tuple("Cyan", Color.FromHex("#00BCD4")), 21 | new Tuple("Dark Orange", Color.FromHex("#FF5722")), 22 | new Tuple("Dark Purple", Color.FromHex("#673AB7")), 23 | new Tuple("Green", Color.FromHex("#4CAF50")), 24 | new Tuple("Grey", Color.FromHex("#9E9E9E")), 25 | new Tuple("Indigo", Color.FromHex("#3F51B5")), 26 | new Tuple("Light Blue", Color.FromHex("#02A8F3")), 27 | new Tuple("Light Green", Color.FromHex("#8AC249")), 28 | new Tuple("Lime", Color.FromHex("#CDDC39")), 29 | new Tuple("Orange", Color.FromHex("#FF9800")), 30 | new Tuple("Pink", Color.FromHex("#E91E63")), 31 | new Tuple("Purple", Color.FromHex("#94499D")), 32 | new Tuple("Red", Color.FromHex("#D32F2F")), 33 | new Tuple("Teal", Color.FromHex("#009587")), 34 | new Tuple("White", Color.FromHex("#FFFFFF")), 35 | new Tuple("Yellow", Color.FromHex("#FFEB3B")), 36 | }; 37 | public App() 38 | { 39 | InitializeComponent(); 40 | 41 | MainPage = new CustomNavigationPage(new CustomNavigationBarSample.MainPage()); 42 | } 43 | 44 | protected override void OnStart() 45 | { 46 | // Handle when your app starts 47 | } 48 | 49 | protected override void OnSleep() 50 | { 51 | // Handle when your app sleeps 52 | } 53 | 54 | protected override void OnResume() 55 | { 56 | // Handle when your app resumes 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/BarBackgroundPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/BarBackgroundPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class BarBackgroundPage : ContentPage 14 | { 15 | public BarBackgroundPage() 16 | { 17 | InitializeComponent(); 18 | Title = "Monkey Title"; 19 | opacitySlider.Value = 0.6f; 20 | CustomNavigationPage.SetTitleColor(this,Color.Navy); 21 | CustomNavigationPage.SetBarBackground(this, Device.RuntimePlatform == Device.iOS ? "monkeybackground.jpg": "monkeybackground"); 22 | } 23 | 24 | private void OpacitySlider_ValueChanged(object sender, ValueChangedEventArgs e) 25 | { 26 | CustomNavigationPage.SetBarBackgroundOpacity(this, (float)e.NewValue); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/CustomNavigationBarSample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 11.0 6 | Debug 7 | AnyCPU 8 | {552B83D3-223E-4BFB-A758-404C249102AF} 9 | Library 10 | Properties 11 | CustomNavigationBarSample 12 | CustomNavigationBarSample 13 | 512 14 | v4.5 15 | Profile259 16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | App.xaml 40 | 41 | 42 | BarBackgroundPage.xaml 43 | 44 | 45 | 46 | CustomPage.xaml 47 | 48 | 49 | FormattedTitlePage.xaml 50 | 51 | 52 | GradientTitlePage.xaml 53 | 54 | 55 | MainPage.xaml 56 | 57 | 58 | 59 | TitleBorderPage.xaml 60 | 61 | 62 | TitleImagePage.xaml 63 | 64 | 65 | TitlePositionPage.xaml 66 | 67 | 68 | 69 | 70 | Designer 71 | MSBuild:UpdateDesignTimeXaml 72 | 73 | 74 | Designer 75 | MSBuild:UpdateDesignTimeXaml 76 | 77 | 78 | 79 | 80 | MSBuild:UpdateDesignTimeXaml 81 | Designer 82 | 83 | 84 | 85 | 86 | MSBuild:UpdateDesignTimeXaml 87 | Designer 88 | 89 | 90 | 91 | 92 | MSBuild:UpdateDesignTimeXaml 93 | Designer 94 | 95 | 96 | 97 | 98 | MSBuild:UpdateDesignTimeXaml 99 | Designer 100 | 101 | 102 | 103 | 104 | MSBuild:UpdateDesignTimeXaml 105 | Designer 106 | 107 | 108 | 109 | 110 | MSBuild:UpdateDesignTimeXaml 111 | Designer 112 | 113 | 114 | 115 | 116 | MSBuild:UpdateDesignTimeXaml 117 | Designer 118 | 119 | 120 | 121 | 122 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Core.dll 123 | 124 | 125 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Platform.dll 126 | 127 | 128 | ..\packages\Xamarin.Forms.2.5.0.122203\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Xaml.dll 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/CustomNavigationPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xamarin.Forms; 7 | 8 | namespace CustomNavigationBarSample 9 | { 10 | public class CustomNavigationPage : NavigationPage 11 | { 12 | public enum TitleAlignment 13 | { 14 | Start, 15 | Center, 16 | End 17 | } 18 | 19 | public enum GradientDirection 20 | { 21 | LeftToRight, 22 | RightToLeft, 23 | TopToBottom, 24 | BottomToTop 25 | } 26 | 27 | 28 | public static readonly BindableProperty TitlePositionProperty = BindableProperty.CreateAttached("TitlePosition", typeof(TitleAlignment), typeof(CustomNavigationPage), Device.RuntimePlatform == Device.iOS ? TitleAlignment.Center: TitleAlignment.Start); 29 | 30 | public static TitleAlignment GetTitlePosition(BindableObject view) 31 | { 32 | 33 | return (TitleAlignment)view.GetValue(TitlePositionProperty); 34 | } 35 | 36 | public static void SetTitlePosition(BindableObject view, TitleAlignment value) 37 | { 38 | view.SetValue(TitlePositionProperty, value); 39 | } 40 | 41 | 42 | public static readonly BindableProperty TitleBackgroundProperty = BindableProperty.CreateAttached("TitleBackground", typeof(string), typeof(CustomNavigationPage), string.Empty); 43 | 44 | public static string GetTitleBackground(BindableObject view) 45 | { 46 | 47 | return (string)view.GetValue(TitleBackgroundProperty); 48 | } 49 | 50 | public static void SetTitleBackground(BindableObject view, string value) 51 | { 52 | view.SetValue(TitleBackgroundProperty, value); 53 | } 54 | 55 | public static readonly BindableProperty TitleFontProperty = BindableProperty.CreateAttached("TitleFont", typeof(Font), typeof(CustomNavigationPage), Font.SystemFontOfSize(NamedSize.Medium)); 56 | 57 | public static Font GetTitleFont(BindableObject view) 58 | { 59 | 60 | return (Font)view.GetValue(TitleFontProperty); 61 | } 62 | 63 | public static void SetTitleFont(BindableObject view, Font value) 64 | { 65 | view.SetValue(TitleFontProperty, value); 66 | } 67 | 68 | 69 | public static readonly BindableProperty TitlePaddingProperty = BindableProperty.CreateAttached("TitlePadding", typeof(Thickness), typeof(CustomNavigationPage), default(Thickness)); 70 | 71 | public static Thickness GetTitlePadding(BindableObject view) 72 | { 73 | 74 | return (Thickness)view.GetValue(TitlePaddingProperty); 75 | } 76 | 77 | public static void SetTitlePadding(BindableObject view, Thickness value) 78 | { 79 | view.SetValue(TitlePaddingProperty, value); 80 | } 81 | 82 | 83 | 84 | public static readonly BindableProperty TitleMarginProperty = BindableProperty.CreateAttached("TitleMargin", typeof(Thickness), typeof(CustomNavigationPage), default(Thickness)); 85 | 86 | public static Thickness GetTitleMargin(BindableObject view) 87 | { 88 | 89 | return (Thickness)view.GetValue(TitleMarginProperty); 90 | } 91 | 92 | public static void SetTitleMargin(BindableObject view, Thickness value) 93 | { 94 | view.SetValue(TitleMarginProperty, value); 95 | } 96 | 97 | 98 | public static readonly BindableProperty BarBackgroundProperty = BindableProperty.CreateAttached("BarBackground", typeof(string), typeof(CustomNavigationPage), string.Empty); 99 | 100 | public static string GetBarBackground(BindableObject view) 101 | { 102 | 103 | return (string)view.GetValue(BarBackgroundProperty); 104 | } 105 | 106 | public static void SetBarBackground(BindableObject view, string value) 107 | { 108 | view.SetValue(BarBackgroundProperty, value); 109 | } 110 | 111 | 112 | public static readonly BindableProperty GradientColorsProperty = BindableProperty.CreateAttached("GradientColors", typeof(Tuple), typeof(CustomNavigationPage), null); 113 | 114 | public static Tuple GetGradientColors(BindableObject view) 115 | { 116 | 117 | return (Tuple)view.GetValue(GradientColorsProperty); 118 | } 119 | 120 | public static void SetGradientColors(BindableObject view, Tuple value) 121 | { 122 | view.SetValue(GradientColorsProperty, value); 123 | } 124 | 125 | public static readonly BindableProperty GradientDirectionProperty = BindableProperty.CreateAttached("GradientDirection", typeof(GradientDirection), typeof(CustomNavigationPage), GradientDirection.TopToBottom); 126 | 127 | public static GradientDirection GetGradientDirection(BindableObject view) 128 | { 129 | 130 | return (GradientDirection)view.GetValue(GradientDirectionProperty); 131 | } 132 | 133 | public static void SetGradientDirection(BindableObject view, GradientDirection value) 134 | { 135 | view.SetValue(GradientDirectionProperty, value); 136 | } 137 | 138 | public static readonly BindableProperty SubtitleFontProperty = BindableProperty.CreateAttached("SubtitleFont", typeof(Font), typeof(CustomNavigationPage), Font.SystemFontOfSize(NamedSize.Small)); 139 | 140 | public static Font GetSubtitleFont(BindableObject view) 141 | { 142 | 143 | return (Font)view.GetValue(SubtitleFontProperty); 144 | } 145 | 146 | public static void SetSubtitleFont(BindableObject view, Font value) 147 | { 148 | view.SetValue(SubtitleFontProperty, value); 149 | } 150 | 151 | public static readonly BindableProperty TitleColorProperty = BindableProperty.CreateAttached("TitleColor", typeof(Color?), typeof(CustomNavigationPage),null); 152 | 153 | public static Color? GetTitleColor(BindableObject view) 154 | { 155 | 156 | return (Color?)view.GetValue(TitleColorProperty); 157 | } 158 | 159 | public static void SetTitleColor(BindableObject view, Color? value) 160 | { 161 | view.SetValue(TitleColorProperty, value); 162 | } 163 | 164 | public static readonly BindableProperty SubtitleColorProperty = BindableProperty.CreateAttached("SubtitleColor", typeof(Color?), typeof(CustomNavigationPage), null); 165 | 166 | public static Color? GetSubtitleColor(BindableObject view) 167 | { 168 | 169 | return (Color?)view.GetValue(SubtitleColorProperty); 170 | } 171 | 172 | public static void SetSubtitleColor(BindableObject view, Color? value) 173 | { 174 | view.SetValue(SubtitleColorProperty, value); 175 | } 176 | 177 | 178 | public static readonly BindableProperty HasShadowProperty = BindableProperty.CreateAttached("HasShadow", typeof(bool), typeof(CustomNavigationPage), false); 179 | 180 | public static bool GetHasShadow(BindableObject view) 181 | { 182 | 183 | return (bool)view.GetValue(HasShadowProperty); 184 | } 185 | 186 | public static void SetHasShadow(BindableObject view, bool value) 187 | { 188 | view.SetValue(HasShadowProperty, value); 189 | } 190 | 191 | 192 | public static readonly BindableProperty TitleBorderCornerRadiusProperty = BindableProperty.CreateAttached("TitleBorderCornerRadius", typeof(float), typeof(CustomNavigationPage), 0.0f); 193 | 194 | public static float GetTitleBorderCornerRadius(BindableObject view) 195 | { 196 | 197 | return (float)view.GetValue(TitleBorderCornerRadiusProperty); 198 | } 199 | 200 | public static void SetTitleBorderCornerRadius(BindableObject view,float value) 201 | { 202 | view.SetValue(TitleBorderCornerRadiusProperty, value); 203 | } 204 | 205 | public static readonly BindableProperty TitleBorderColorProperty = BindableProperty.CreateAttached("TitleBorderColor", typeof(Color?), typeof(CustomNavigationPage), null); 206 | 207 | public static Color? GetTitleBorderColor(BindableObject view) 208 | { 209 | 210 | return (Color?)view.GetValue(TitleBorderColorProperty); 211 | } 212 | 213 | public static void SetTitleBorderColor(BindableObject view, Color? value) 214 | { 215 | view.SetValue(TitleBorderColorProperty, value); 216 | } 217 | 218 | public static readonly BindableProperty TitleFillColorProperty = BindableProperty.CreateAttached("TitleFillColor", typeof(Color?), typeof(CustomNavigationPage), null); 219 | 220 | public static Color? GetTitleFillColor(BindableObject view) 221 | { 222 | 223 | return (Color?)view.GetValue(TitleFillColorProperty); 224 | } 225 | 226 | public static void SetTitleFillColor(BindableObject view, Color? value) 227 | { 228 | view.SetValue(TitleFillColorProperty, value); 229 | } 230 | 231 | public static readonly BindableProperty TitleBorderWidthProperty = BindableProperty.CreateAttached("TitleBorderWidth", typeof(float), typeof(CustomNavigationPage), 0.0f); 232 | 233 | public static float GetTitleBorderWidth(BindableObject view) 234 | { 235 | 236 | return (float)view.GetValue(TitleBorderWidthProperty); 237 | } 238 | 239 | public static void SetTitleBorderWidth(BindableObject view, float value) 240 | { 241 | view.SetValue(TitleBorderWidthProperty, value); 242 | } 243 | 244 | public static readonly BindableProperty BarBackgroundOpacityProperty = BindableProperty.CreateAttached("BarBackgroundOpacity", typeof(float), typeof(CustomNavigationPage), 1.0f); 245 | 246 | public static float GetBarBackgroundOpacity(BindableObject view) 247 | { 248 | 249 | return (float)view.GetValue(BarBackgroundOpacityProperty); 250 | } 251 | 252 | public static void SetBarBackgroundOpacity(BindableObject view, float value) 253 | { 254 | view.SetValue(BarBackgroundOpacityProperty, value); 255 | } 256 | public CustomNavigationPage(Page page) : base(page) 257 | { 258 | 259 | } 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/CustomPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/CustomPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class CustomPage : ContentPage 14 | { 15 | 16 | public static readonly BindableProperty FormattedTitleProperty = BindableProperty.Create(nameof(FormattedTitle),typeof(FormattedString),typeof(CustomPage),null); 17 | 18 | public FormattedString FormattedTitle 19 | { 20 | get { return (FormattedString)GetValue(FormattedTitleProperty); } 21 | set 22 | { 23 | SetValue(FormattedTitleProperty, value); 24 | } 25 | } 26 | 27 | public static readonly BindableProperty FormattedSubtitleProperty = BindableProperty.Create(nameof(FormattedSubtitle),typeof(FormattedString), typeof(CustomPage), null); 28 | 29 | public FormattedString FormattedSubtitle 30 | { 31 | get { return (FormattedString)GetValue(FormattedSubtitleProperty); } 32 | set 33 | { 34 | SetValue(FormattedSubtitleProperty, value); 35 | } 36 | } 37 | 38 | public static readonly BindableProperty SubtitleProperty = BindableProperty.Create(nameof(Subtitle),typeof(string),typeof(CustomPage),null); 39 | 40 | 41 | public string Subtitle 42 | { 43 | get { return (string)GetValue(SubtitleProperty); } 44 | set 45 | { 46 | SetValue(SubtitleProperty, value); 47 | } 48 | } 49 | 50 | 51 | public CustomPage() 52 | { 53 | InitializeComponent(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/FormattedTitlePage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 6 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/FormattedTitlePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | using static CustomNavigationBarSample.CustomNavigationPage; 10 | 11 | namespace CustomNavigationBarSample 12 | { 13 | [XamlCompilation(XamlCompilationOptions.Compile)] 14 | public partial class FormattedTitlePage : CustomPage 15 | { 16 | public FormattedTitlePage() 17 | { 18 | this.FormattedTitle = new FormattedString(); 19 | this.FormattedTitle.Spans.Add(new Span() 20 | { 21 | Text = "My ", 22 | FontSize = 14, 23 | ForegroundColor = Color.Orange, 24 | }); 25 | 26 | this.FormattedTitle.Spans.Add(new Span() 27 | { 28 | Text = "Awesome ", 29 | FontSize = 18, 30 | ForegroundColor = Color.Navy, 31 | }); 32 | 33 | this.FormattedTitle.Spans.Add(new Span() 34 | { 35 | Text = "Title", 36 | FontSize = 16, 37 | ForegroundColor = Color.LightGreen, 38 | }); 39 | 40 | this.FormattedSubtitle = new FormattedString(); 41 | this.FormattedSubtitle.Spans.Add(new Span() 42 | { 43 | Text = "Just ", 44 | FontSize = 10, 45 | ForegroundColor = Color.Brown, 46 | }); 47 | 48 | this.FormattedSubtitle.Spans.Add(new Span() 49 | { 50 | Text = "a nice ", 51 | FontSize = 14, 52 | ForegroundColor = Color.DarkSalmon, 53 | }); 54 | 55 | this.FormattedSubtitle.Spans.Add(new Span() 56 | { 57 | Text = "Subtitle", 58 | FontSize = 12, 59 | ForegroundColor = Color.Purple, 60 | }); 61 | CustomNavigationPage.SetTitlePosition(this, TitleAlignment.Center); 62 | 63 | InitializeComponent(); 64 | 65 | 66 | 67 | 68 | 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/GradientTitlePage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 27 | 28 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/GradientTitlePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class GradientTitlePage : ContentPage 14 | { 15 | 16 | public GradientTitlePage() 17 | { 18 | Title = "My Title"; 19 | CustomNavigationPage.SetTitleMargin(this, new Thickness(5, 5, 5, 5)); 20 | InitializeComponent(); 21 | 22 | startColorPicker.ItemsSource = App.Colors; 23 | endColorPicker.ItemsSource = App.Colors; 24 | titleColorPicker.ItemsSource = App.Colors; 25 | 26 | titleColorPicker.SelectedIndex = App.Colors.Count - 2; 27 | startColorPicker.SelectedIndex = 1; 28 | endColorPicker.SelectedIndex = App.Colors.Count - 1; 29 | gradientDirectionPicker.SelectedIndex = 0; 30 | 31 | } 32 | 33 | private void ColorPicker_SelectedIndexChanged(object sender, EventArgs e) 34 | { 35 | 36 | if (startColorPicker.SelectedIndex != -1 && endColorPicker.SelectedIndex!=-1) 37 | { 38 | var startColor = App.Colors.FirstOrDefault(n => n.Item1 == startColorPicker.Items[startColorPicker.SelectedIndex]).Item2; 39 | var endColor = App.Colors.FirstOrDefault(n => n.Item1 == endColorPicker.Items[endColorPicker.SelectedIndex]).Item2; 40 | CustomNavigationPage.SetGradientColors(this, new Tuple(startColor, endColor)); 41 | } 42 | } 43 | 44 | 45 | private void GradientDirectionPicker_SelectedIndexChanged(object sender, EventArgs e) 46 | { 47 | var picker = (Picker)sender; 48 | int selectedIndex = picker.SelectedIndex; 49 | 50 | if (selectedIndex != -1) 51 | { 52 | switch (picker.Items[selectedIndex]) 53 | { 54 | case "Top to Bottom": 55 | CustomNavigationPage.SetGradientDirection(this, CustomNavigationPage.GradientDirection.TopToBottom); 56 | break; 57 | case "Right to Left": 58 | CustomNavigationPage.SetGradientDirection(this, CustomNavigationPage.GradientDirection.RightToLeft); 59 | break; 60 | case "Left to Right": 61 | CustomNavigationPage.SetGradientDirection(this, CustomNavigationPage.GradientDirection.LeftToRight); 62 | break; 63 | case "Bottom to Top": 64 | CustomNavigationPage.SetGradientDirection(this, CustomNavigationPage.GradientDirection.BottomToTop); 65 | break; 66 | } 67 | } 68 | } 69 | 70 | private void TitleColorPicker_SelectedIndexChanged(object sender, EventArgs e) 71 | { 72 | var picker = (Picker)sender; 73 | int selectedIndex = picker.SelectedIndex; 74 | 75 | if (selectedIndex != -1) 76 | { 77 | 78 | var titleColor = App.Colors.FirstOrDefault(n => n.Item1 == picker.Items[selectedIndex]).Item2; 79 | CustomNavigationPage.SetTitleColor(this, titleColor); 80 | } 81 | 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xamarin.Forms; 7 | 8 | namespace CustomNavigationBarSample 9 | { 10 | public partial class MainPage : CustomPage 11 | { 12 | IList options = new List() 13 | { 14 | "Title Font/Position", 15 | "Formatted Title", 16 | "Gradient Background", 17 | "Title Customization", 18 | "Image Title", 19 | "Bar Image Background" 20 | }; 21 | 22 | public MainPage() 23 | { 24 | CustomNavigationPage.SetTitleMargin(this, new Thickness(0, 0, 5, 0)); 25 | CustomNavigationPage.SetTitleColor(this, Color.Gray); 26 | CustomNavigationPage.SetSubtitleColor(this, Color.ForestGreen); 27 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.End); 28 | CustomNavigationPage.SetSubtitleFont(this, Font.SystemFontOfSize(NamedSize.Micro)); 29 | InitializeComponent(); 30 | listView.ItemsSource = options; 31 | } 32 | 33 | private async void ItemSelected(object sender, SelectedItemChangedEventArgs e) 34 | { 35 | var listView = sender as ListView; 36 | switch(e.SelectedItem) 37 | { 38 | case "Title Font/Position": 39 | await Navigation.PushAsync(new TitlePositionPage()); 40 | break; 41 | case "Formatted Title": 42 | await Navigation.PushAsync(new FormattedTitlePage()); 43 | break; 44 | case "Gradient Background": 45 | await Navigation.PushAsync(new GradientTitlePage()); 46 | break; 47 | case "Title Customization": 48 | await Navigation.PushAsync(new TitleBorderPage()); 49 | break; 50 | case "Image Title": 51 | await Navigation.PushAsync(new TitleImagePage()); 52 | break; 53 | case "Bar Image Background": 54 | await Navigation.PushAsync(new BarBackgroundPage()); 55 | break; 56 | } 57 | listView.SelectedItem = null; 58 | } 59 | 60 | private void Switch_Toggled(object sender, ToggledEventArgs e) 61 | { 62 | CustomNavigationPage.SetHasShadow(this, e.Value); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("CustomNavigationBarSample")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("CustomNavigationBarSample")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitleBorderPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 11 | 12 | 16 | 17 | 21 | 22 | 26 | 27 | 31 | 32 | 41 | 42 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitleBorderPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class TitleBorderPage : ContentPage 14 | { 15 | public TitleBorderPage() 16 | { 17 | Title = "Bordered Title"; 18 | 19 | 20 | InitializeComponent(); 21 | titleEntry.Text = Title; 22 | titleBorderColorPicker.ItemsSource = App.Colors; 23 | titleFillColorPicker.ItemsSource = App.Colors; 24 | 25 | titleBorderColorPicker.SelectedIndex = 5; 26 | 27 | titleFillColorPicker.SelectedIndex = 10; 28 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.Center); 29 | 30 | } 31 | 32 | private void BorderRadiuSlider_ValueChanged(object sender, ValueChangedEventArgs e) 33 | { 34 | CustomNavigationPage.SetTitleBorderCornerRadius(this, (float)e.NewValue); 35 | } 36 | 37 | private void BorderWidthSlider_ValueChanged(object sender, ValueChangedEventArgs e) 38 | { 39 | CustomNavigationPage.SetTitleBorderWidth(this, (float)e.NewValue); 40 | } 41 | 42 | private void TitlePaddingSlider_ValueChanged(object sender, ValueChangedEventArgs e) 43 | { 44 | 45 | CustomNavigationPage.SetTitlePadding(this, new Thickness((float)e.NewValue, (float)e.NewValue, (float)e.NewValue, (float)e.NewValue)); 46 | } 47 | 48 | private void TitleMarginSlider_ValueChanged(object sender, ValueChangedEventArgs e) 49 | { 50 | CustomNavigationPage.SetTitleMargin(this, new Thickness((float)e.NewValue, (float)e.NewValue, (float)e.NewValue, (float)e.NewValue)); 51 | 52 | } 53 | 54 | private void TitleFillColorPicker_SelectedIndexChanged(object sender, EventArgs e) 55 | { 56 | var picker = (Picker)sender; 57 | int selectedIndex = picker.SelectedIndex; 58 | 59 | if (selectedIndex != -1) 60 | { 61 | 62 | var titleColor = App.Colors.FirstOrDefault(n => n.Item1 == picker.Items[selectedIndex]).Item2; 63 | CustomNavigationPage.SetTitleFillColor(this, titleColor); 64 | } 65 | } 66 | 67 | private void TitleBorderColorPicker_SelectedIndexChanged(object sender, EventArgs e) 68 | { 69 | var picker = (Picker)sender; 70 | int selectedIndex = picker.SelectedIndex; 71 | 72 | if (selectedIndex != -1) 73 | { 74 | 75 | var titleColor = App.Colors.FirstOrDefault(n => n.Item1 == picker.Items[selectedIndex]).Item2; 76 | CustomNavigationPage.SetTitleBorderColor(this, titleColor); 77 | } 78 | } 79 | 80 | private void TitleEntry_TextChanged(object sender, TextChangedEventArgs e) 81 | { 82 | Title = e.NewTextValue; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitleImagePage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitleImagePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class TitleImagePage : ContentPage 14 | { 15 | public TitleImagePage() 16 | { 17 | 18 | CustomNavigationPage.SetTitleBackground(this, "icon"); 19 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.Center); 20 | InitializeComponent(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitlePositionPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 11 | 12 | 30 | 31 | -------------------------------------------------------------------------------- /CustomNavigationBarSample/TitlePositionPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace CustomNavigationBarSample 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class TitlePositionPage : CustomPage 14 | { 15 | public TitlePositionPage() 16 | { 17 | InitializeComponent(); 18 | positionPicker.SelectedIndex = 0; 19 | fontSizePicker.SelectedIndex = 2; 20 | } 21 | 22 | private void PositionPickerSelectedIndexChanged(object sender, EventArgs e) 23 | { 24 | var picker = (Picker)sender; 25 | int selectedIndex = picker.SelectedIndex; 26 | 27 | if (selectedIndex != -1) 28 | { 29 | switch(picker.Items[selectedIndex]) 30 | { 31 | case "Start": 32 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.Start); 33 | break; 34 | case "Center": 35 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.Center); 36 | break; 37 | case "End": 38 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.End); 39 | break; 40 | } 41 | } 42 | } 43 | 44 | private void FontSizePickerSelectedIndexChanged(object sender, EventArgs e) 45 | { 46 | var picker = (Picker)sender; 47 | int selectedIndex = picker.SelectedIndex; 48 | 49 | if (selectedIndex != -1) 50 | { 51 | switch (picker.Items[selectedIndex]) 52 | { 53 | case "Micro": 54 | CustomNavigationPage.SetTitleFont(this,Font.SystemFontOfSize(NamedSize.Micro)); 55 | break; 56 | case "Small": 57 | CustomNavigationPage.SetTitleFont(this, Font.SystemFontOfSize(NamedSize.Small)); 58 | break; 59 | case "Medium": 60 | CustomNavigationPage.SetTitleFont(this, Font.SystemFontOfSize(NamedSize.Medium)); 61 | break; 62 | case "Large": 63 | CustomNavigationPage.SetTitleFont(this, Font.SystemFontOfSize(NamedSize.Large)); 64 | break; 65 | } 66 | } 67 | } 68 | 69 | private void ShowSubtitle_Toggled(object sender, ToggledEventArgs e) 70 | { 71 | Subtitle = e.Value ? "My Subtitle" : string.Empty; 72 | } 73 | } 74 | 75 | 76 | } -------------------------------------------------------------------------------- /CustomNavigationBarSample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CrossGeeks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CustomNavigationBarSample 2 | 3 | Navigation Bar Customization in Xamarin Forms 4 | 5 | Blog post: http://www.xamboy.com/2017/12/06/navigation-bar-customization-in-xamarin-forms/ 6 | 7 |

8 | 9 |

10 | 11 | ### Features 12 | 13 | - Title/Subtitle positioning 14 | - Subtitle 15 | - Bar Gradient Background 16 | - Title Font Customization 17 | - Subtitle Font Customization 18 | - Formatted Title 19 | - Formatted Subtitle 20 | - Image title 21 | - Bar Background 22 | - Bar Shadow 23 | - Bar Opacity 24 | - Title Margin 25 | - Title Padding 26 | - Title Border 27 | - Title Background 28 | 29 |

30 | 31 | 32 |

33 | 34 | 35 |

36 | 37 | 38 |

39 | 40 | ### Usage on a Xamarin Forms page 41 | 42 | ```cs 43 | //Sets the title position to end 44 | 45 | CustomNavigationPage.SetTitlePosition(this, CustomNavigationPage.TitleAlignment.End); 46 | 47 | //Sets shadow for bar bottom 48 | 49 | CustomNavigationPage.SetHasShadow(this,true); 50 | 51 | //Gets if has shadow or not 52 | 53 | bool hasShadow = CustomNavigationPage.GetHasShadow(this); 54 | 55 | //Sets the title text font to Micro 56 | CustomNavigationPage.SetTitleFont(this, Font.SystemFontOfSize(NamedSize.Micro)); 57 | 58 | //Sets the title color 59 | CustomNavigationPage.SetTitleColor(this,Color.Navy); 60 | 61 | //Sets bar background 62 | CustomNavigationPage.SetBarBackground(this, Device.RuntimePlatform == Device.iOS ? "monkeybackground.jpg": "monkeybackground"); 63 | 64 | //Sets bar background opacity 65 | CustomNavigationPage.SetBarBackgroundOpacity(this,0.6f); 66 | ``` 67 | 68 | ### Future 69 | 70 | - UWP and other platforms support 71 | - Support Badges 72 | - Kerning 73 | - Back Button Customization 74 | - Toolbar Items Customization 75 | - Buttons/Picker as title 76 | - Rotated Title 77 | - Animations 78 | - Traslucent Bar 79 | - Collapsable Bar 80 | - Bar Templates 81 | -------------------------------------------------------------------------------- /gifs/android/android_full_video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/android/android_full_video.gif -------------------------------------------------------------------------------- /gifs/android/back_image_background_droid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/android/back_image_background_droid.gif -------------------------------------------------------------------------------- /gifs/android/gradientBackground_android.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/android/gradientBackground_android.gif -------------------------------------------------------------------------------- /gifs/android/titleFontPosition_android.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/android/titleFontPosition_android.gif -------------------------------------------------------------------------------- /gifs/android/title_background_droid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/android/title_background_droid.gif -------------------------------------------------------------------------------- /gifs/ios/gradient_iOS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/ios/gradient_iOS.gif -------------------------------------------------------------------------------- /gifs/ios/opacity_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/ios/opacity_ios.gif -------------------------------------------------------------------------------- /gifs/ios/titleFontPosition_iOS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/ios/titleFontPosition_iOS.gif -------------------------------------------------------------------------------- /gifs/ios/title_customization_.iOS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/gifs/ios/title_customization_.iOS.gif -------------------------------------------------------------------------------- /imgs/android/formatted_text_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/imgs/android/formatted_text_android.png -------------------------------------------------------------------------------- /imgs/android/image_title_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/imgs/android/image_title_android.png -------------------------------------------------------------------------------- /imgs/ios/title_font_position_iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/CustomNavigationBarSample/457f66454d540feeedbf4b1fbbbcb2d4c8d693d7/imgs/ios/title_font_position_iOS.png --------------------------------------------------------------------------------