Change "Active" icon on selected NavigationPage when using TabbedPage - ios

I'm very, very new to Xamarin.Forms. My task, if it is possible, and I'm not sure if it is, is to change our icon from the default blue when it is active.
I was given icons that are orange and they would like to display those or at least the color instead of the default blue. Again, I'm not sure if this is possible.
This is the code I'm using for the tabbed page.
public class LandingPage : TabbedPage
{
public LandingPage ()
{
NavigationPage homepage = new NavigationPage (new CarouselPage {
Title = "Title",
Children = {
//code removed
}
});
NavigationPage eventspage = new NavigationPage (new ContentPage {
Title = "Calendar Event List",
Content = new EventList ()
});
NavigationPage morepage = new NavigationPage (new MorePage ());
homepage.BarBackgroundColor = Device.OnPlatform (Color.FromHex (DependencyService.Get<IContentStrings>().BarBackgroundColor), Color.Transparent, Color.Transparent);
homepage.BarTextColor = Color.FromHex(DependencyService.Get<IContentStrings>().BarTextColor);
homepage.Title = DependencyService.Get<IContentStrings>().HomeTitle;
homepage.Icon = DependencyService.Get<IContentStrings>().HomeImage;
eventspage.BarBackgroundColor = Device.OnPlatform (Color.FromHex (DependencyService.Get<IContentStrings>().BarBackgroundColor), Color.Transparent, Color.Transparent);
eventspage.BarTextColor = Color.FromHex(DependencyService.Get<IContentStrings>().BarTextColor);
eventspage.Title = DependencyService.Get<IContentStrings>().EventTitle;
eventspage.Icon = DependencyService.Get<IContentStrings>().EventImage;
morepage.BarBackgroundColor = Device.OnPlatform (Color.FromHex (DependencyService.Get<IContentStrings>().BarBackgroundColor), Color.Transparent, Color.Transparent);
morepage.BarTextColor = Color.FromHex(DependencyService.Get<IContentStrings>().BarTextColor);
morepage.Title = DependencyService.Get<IContentStrings>().MoreTitle;
morepage.Icon = DependencyService.Get<IContentStrings>().MoreImage;
Children.Add (homepage);
Children.Add (eventspage);
Children.Add (morepage);
}
}
I'm not sure if I'm able to use a custom renderer or anything. I do not know if I have any options and any guidance is greatly appreciated!

You can set the active tab icon color with a simple custom iOS renderer like this:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer))]
namespace MyApp.iOS.Renderers
{
public class MyTabbedPageRenderer : TabbedRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
TabBar.TintColor = UIColor.Orange;
}
}
}

I found was finally able to find the answer after searching the internet a few hours and then coming back to the app on a different day. To change the default from the blue, I changed the UITabbar tint color in the AppDelegate.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
UIApplication.SharedApplication.SetStatusBarStyle (UIStatusBarStyle.LightContent, false);
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new App ());
//this changes the default iOS tintcolor for the icon when it's activated
UITabBar.Appearance.TintColor = UIColor.FromRGB(223, 112, 13);
return base.FinishedLaunching (app, options);
}

Related

How to call or use a View or Widget from another android class

I have a little issue in android studio Java code !
Im using switch compact to change the background image from a light one to a dark one instead of NightMode. Every thing works fine in a class called "Category Activity" where the switch compact is there, but i want this to work in another class i mean whenever i click on switch compact the background Image change in all activity
Here is the code in "Category Activity" :
// ----------- DAY AND NIGHT MODE ----------------------//
switchCompat = findViewById(R.id.switchCompat);
back_images = new int[]{R.drawable.lightbg, R.drawable.darkbg};
switchCompat = findViewById(R.id.switchCompat);
screenView = findViewById(R.id.layoutcategory);
sharedPreferences = getSharedPreferences("dark_light", 0);
Boolean booleanValue = sharedPreferences.getBoolean("dark_light_mode", true);
if (booleanValue) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
switchCompat.setChecked(true);
screenView.setBackgroundResource(R.drawable.lightbg);
switchCompat.setText(R.string.LightMode);
} else {
switchCompat.setChecked(false);
screenView.setBackgroundResource(R.drawable.darkbg);
switchCompat.setText(R.string.NightMode);
}
switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
switchCompat.setChecked(true);
screenView.setBackgroundResource(R.drawable.lightbg);
switchCompat.setText(R.string.LightMode);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("night_mode", true);
editor.commit();
} else {
screenView.setBackgroundResource(R.drawable.darkbg);
switchCompat.setText(R.string.NightMode);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("night_mode", false);
editor.commit();
}
}
});

show a login page before moving to main app in xamarin.android

so I'm trying to make an android app that starts with a login page (that I thought could be a dialog fragment) and if the user's credentials are correct, then he'll be directed to the main app that is supposed to be a navigation drawer app. I tried to use the dialog fragment but I didn't know how to set it to appear at the very beginning. what should I do?
You should create a Activity as a MainLauncher, Activity you can use a blank Layout.xml like following code, then pop a DialogFragment like following code. Note: you should add MainLauncher = true,NoHistory =true in your Activity attribute. NoHistory =true will make the back button navigate to the desktop.
namespace App2
{
[Activity(Label = "LoginActivity", Theme = "#style/AppTheme.NoActionBar",MainLauncher = true,NoHistory =true)]
public class LoginActivity : AppCompatActivity, OnLoginInforCompleted
{
public void inputLoginInforCompleted(string userName, string passWord)
{
//You can get the username and password here
StartActivity(new Intent(this,typeof(MainActivity)));
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.LoginLayout);
MyDialogFragment dialogFragment = new MyDialogFragment();
dialogFragment.setOnLoginInforCompleted(this);
dialogFragment.Cancelable = false;
var SupportFragmentManager = this.FragmentManager;
dialogFragment.Show(SupportFragmentManager, "dialog");
}
}
}
I achieve the a callback interface OnLoginInforCompleted, If User click the Login Button, will navigate to the navigation drawer page.
public interface OnLoginInforCompleted
{
void inputLoginInforCompleted(String userName, String passWord);
}
Here is code about MyDialogFragment .
public class MyDialogFragment : DialogFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.layout3, container, false);
Button button = view.FindViewById<Button>(Resource.Id.button1);
EditText MyeditText1 = view.FindViewById<EditText>(Resource.Id.editText1);
EditText MyeditText2 = view.FindViewById<EditText>(Resource.Id.editText2);
button.Click += delegate {
//set the data to the loginpage
mOnLoginInforCompleted.inputLoginInforCompleted(MyeditText1.Text.ToString(), MyeditText2.Text.ToString());
Dismiss();
};
return view;
}
//set for Callback
private OnLoginInforCompleted mOnLoginInforCompleted;
public void setOnLoginInforCompleted(OnLoginInforCompleted onLoginInforCompleted)
{
mOnLoginInforCompleted = onLoginInforCompleted;
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
return base.OnCreateDialog(savedInstanceState);
}
}
Here is running GIF.
Here is my demo, you can refer to it.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/App2.zip

Xamarin/Android webview hide website element/class

I'm trying to make a little android app showing a webview loading a website.
I got it to show it with the following code snippets. But what I need now is to hide some elements on the header and the footer(a menu for example). I thought I could do it not loading some classes from the webpage, but I'm not sure how to properly do it. Do anyone have some experience on this to share some light? :)
Thanks in advance.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
fab.Click += FabOnClick;
DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, Resource.String.navigation_drawer_open, Resource.String.navigation_drawer_close);
drawer.AddDrawerListener(toggle);
toggle.SyncState();
NavigationView navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
navigationView.SetNavigationItemSelectedListener(this);
wbv = FindViewById<WebView>(Resource.Id.webView1);
wbv.SetWebViewClient(new ExtendWebViewClient());
WebSettings webSettings = wbv.Settings;
webSettings.JavaScriptEnabled = true;
wbv.LoadUrl(txtUrl);
}
internal class ExtendWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
view.LoadUrl(url);
return true;
}
}
edit: Just to reflect the changes to the second class
public class ExtendWebViewClient : WebViewClient
{
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
string js = "var myElements = document.getElementsByClassName('fusion-main-menu');" +
" myElements[0].style.display = 'none'; ";
if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
view.EvaluateJavascript(js, null);
}
else
{
view.LoadUrl(js);
}
}
}
Since you have enabled javascript, there will be a function to run the script in the webview.
This is the code of WebView using Xamarin.Forms.WebView and this is how you can hide any element of webview using it's id.
var hide = await webview.EvaluateJavaScriptAsync("document.getElementById('UserName').style.display = 'none';");

Xamarin iOS Hide cancel button from Search Bar

I wanted to hide 'cancel' button in my iOS search bar. I have implemented the following custom renderer code but it seems not to to work. If anyone knows solution , please share.
public class iOSSearchBar : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> args)
{
base.OnElementChanged(args);
UISearchBar bar = (UISearchBar)this.Control;
bar.AutocapitalizationType = UITextAutocapitalizationType.None;
bar.AutocorrectionType = UITextAutocorrectionType.No;
//bar.BarStyle = UIBarStyle.Default;
//bar.BarTintColor = UIColor.LightGray;
//bar.KeyboardType = UIKeyboardType.ASCIICapable;
bar.SearchBarStyle = UISearchBarStyle.Minimal;
bar.SetShowsCancelButton(false, false);
bar.ShowsCancelButton = false;
}
}
Thanks in advance
This worked for me.
https://gist.github.com/xleon/9f94a8482162460ceaf9
using System;
using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using UIKit;
using System.Diagnostics;
[assembly: ExportRenderer(typeof(SearchBar), typeof(Namespace.iOS.Renderers.ExtendedSearchBarRenderer))]
namespace Namespace.iOS.Renderers
{
public class ExtendedSearchBarRenderer : SearchBarRenderer
{
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Text")
{
Control.ShowsCancelButton = false;
}
}
}
}
Write code to hide cancel button in layoutsubviews method.
public override void LayoutSubviews()
{
base.LayoutSubviews();
UISearchBar bar = (UISearchBar)this.Control;
bar.ShowsCancelButton = false;
}
Following is also working or me, no need to subclass searcher:
SearchBar.TextChanged += delegate
{
SearchBar.ShowsCancelButton = false;
};
I think i managed to remove it manually with:
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Subviews[0].Subviews[0].RemoveFromSuperview();
}
}
I spend some more time searching for this, so adding here in case someone else wants to do both.
In case you also need to remove the X button as well, I found the solution in this comment

Why Data Can not Pass to Second Activity

Using XamarinStudio and below code base on the Sample in the tutorial. Here the questions.
Do I need to generate the AndroidManifest from the Project Option> Android Application when testing the App ?
Why there is no data passing over even I have generated an AndroidManifest , the code :
---Activity 1
[Activity (Label = "HelloMultiScreen", MainLauncher = true,Icon = "#drawable/icon")]
public class FirstActivity : Activity
{
int count = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
//Use UI created in Main.axml
SetContentView (Resource.Layout.Main);
var showSecond = FindViewById (Resource.Id.showSecond);
showSecond.Click += (sender, e) => {
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity (typeof(SecondActivity));
};
}
}
---Activity 2
[Activity (Label = "SecondActivity")]
public class SecondActivity : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create your application here
SetContentView (Resource.Layout.Second);
var label = FindViewById (Resource.Id.screen2Label);
label.Text = Intent.GetStringExtra("FirstData") ?? "Data not available";
}
}
Thanks
Ok I found the problem when I remade the project myself.
The problem lies in this piece of code:
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity (typeof(SecondActivity));
What happens is that you make an Intent with the right data. But you start a new activity without that data.
To fix it change the code to this:
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity(second);`

Resources