Reputation: 976
I am using custom TabbedPage
in my project for showing a badges(count)
in Tab bar
. I am using the below code for showing a custom tab bar
but it is always returning null
value in CustomTabbedPageRenderer.cs
class OnWindowVisibilityChanged
method's activity.ActionBar
. I have tried the many workaround like changing the Theme
as Theme.AppCompat.Light.DarkActionBar
and added the below line in Window.RequestFeature(WindowFeatures.ActionBar);
MainActivity.cs , but unfortunately these didn't help me.
MainActivity.cs
namespace Bakery.Droid
{
[Activity(Label = "Bakery.Droid", Icon = "@mipmap/icon_launcher", Theme = "@style/MyTheme", MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
Home.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace Bakery
{
public class Home : CustomTabPage
{
public Home()
{
NavigationPage.SetHasNavigationBar(this, false);
var burger = new NavigationPage(new Burger());
burger.Icon = "burger.png";
burger.Title = "Burger";
var sandwich = new NavigationPage(new Sandwich());
sandwich.Icon = "sandwich.png";
sandwich.Title = "Sandwich";
var pizza = new NavigationPage(new Pizza());
pizza.Icon = "pizza.png";
pizza.Title = "Pizza";
var roll = new NavigationPage(new Roll());
roll.Icon = "roll.png";
roll.Title = "Roll";
//adding childrens into the tab
Children.Clear();
Children.Add(burger);
Children.Add(sandwich);
Children.Add(pizza);
Children.Add(roll);
}
protected override void OnAppearing()
{
base.OnAppearing();
}
}
}
CustomTabPage.cs
using System;
using Xamarin.Forms;
namespace Bakery
{
public class CustomTabPage : TabbedPage
{
}
}
styles.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
</resources>
CustomTabbedPageRenderer.cs
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace Bakery.Droid
{
public class CustomTabbedPageRenderer : TabbedRenderer
{
Activity activity;
List<string> filenames;
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
filenames = e.NewElement.Children.Select(t => t.Icon.File).ToList();
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
activity = this.Context as Activity;
}
protected override void OnWindowVisibilityChanged(Android.Views.ViewStates visibility)
{
try
{
base.OnWindowVisibilityChanged(visibility);
var actionBar = activity.ActionBar;
var colorDrawable = new ColorDrawable(Android.Graphics.Color.Yellow);
actionBar.SetStackedBackgroundDrawable(colorDrawable);
System.Diagnostics.Debug.WriteLine("Onwindow visible");
ActionBarTabsSetup(actionBar);
}
catch (Exception Exception)
{
System.Diagnostics.Debug.WriteLine("Exception: " + Exception.ToString());
}
}
void ActionBarTabsSetup(ActionBar actionBar)
{
for (var i = 0; i < actionBar.NavigationItemCount; ++i)
{
var tab = actionBar.GetTabAt(i);
var id = GetImageFromFilename(i);
if (id != 0)
TabSetup(tab, id);
}
}
void TabSetup(ActionBar.Tab tab, int resID)
{
var relLay = new Android.Widget.RelativeLayout(activity)
{
LayoutParameters = new LayoutParams(LayoutParams.WrapContent, 180)
};
var linLay = new LinearLayout(activity)
{
LayoutParameters = new LayoutParams(LayoutParams.WrapContent, 180),
Orientation = Orientation.Vertical,
};
linLay.SetHorizontalGravity(Android.Views.GravityFlags.Center);
var imageView = new ImageView(activity);
imageView.SetImageResource(resID);
imageView.SetPadding(-35, 4, -35, 0);
imageView.SetMinimumWidth(60);
var textView = new TextView(activity)
{
Text = tab.Text
};
linLay.AddView(imageView);
linLay.AddView(textView);
relLay.AddView(linLay);
var badgeView = new TextView(activity)
{
Text = "2"
};
var badgeImageView = new ImageView(activity);
badgeImageView.SetImageResource(Resource.Drawable.red);
badgeImageView.SetMinimumWidth(5);
badgeImageView.SetMinimumHeight(5);
badgeImageView.SetPadding(77, 5, 0, 0);
badgeView.SetPadding(85, 0, 0, 0);
relLay.AddView(badgeImageView);
relLay.AddView(badgeView);
tab.SetCustomView(relLay);
}
int GetImageFromFilename(int n)
{
var filename = filenames[n].Split('.');
var id = Resources.GetIdentifier(filename[0], "drawable", activity.PackageName);
return id;
}
}
}
Upvotes: 0
Views: 1055
Reputation: 10831
I am using the below code for showing a custom tab bar but it is always returning
null
value inCustomTabbedPageRenderer.cs
classOnWindowVisibilityChanged
method'sactivity.ActionBar
.
The ActionBar is null
because it is never set in the activity. You need to set the actionbar first:
In MainActivity.cs
Set the SupportActionBar like below:
//Create your own theme "MyTheme"
[Activity(Label = "CustomTabbedPageDemo", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
//Get the ActionBar Layout in Resouce\layout\Toolbar.axml
var toolbar=(Toolbar)LayoutInflater.Inflate(Resource.Layout.Toolbar, null);
//Set the Support ActionBar
SetSupportActionBar(toolbar);
SupportActionBar.Title = "My ActionBar";
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
Create your own theme to replace the default one. Xamarin.Forms
requires theme inherited from Theme.AppCompat.XXX.XXX
:
<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">#5A8622</item>
</style>
Basic Toolbar.axml
example:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
Modify your CustomTabPageRenderer.cs
change the namespace of ActionBar
from Android.App
to using Android.Support.V7.App
and retrieve the ActionBar
through activity.SupportActionBar
:
using Android.Support.V7.App;
...
protected override void OnWindowVisibilityChanged(Android.Views.ViewStates visibility)
{
try
{
base.OnWindowVisibilityChanged(visibility);
//get the support actionbar
var actionBar = activity.SupportActionBar;
var colorDrawable = new ColorDrawable(Android.Graphics.Color.Yellow);
actionBar.SetStackedBackgroundDrawable(colorDrawable);
System.Diagnostics.Debug.WriteLine("Onwindow visible");
ActionBarTabsSetup(actionBar);
}
catch (Exception Exception)
{
System.Diagnostics.Debug.WriteLine("Exception: " + Exception.ToString());
}
}
Upvotes: 1