Xamarin/Android webview hide website element/class - webview

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';");

Related

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

OnCreateContextMenu not working with webview

i have web-view that i need to create for it context menu when click on link type this what i did :
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Webview);
wv = (WebView)FindViewById(Resource.Id.WV);
RegisterForContextMenu(wv);
wv.SetWebChromeClient(new WebChromeClient());
wv.SetWebViewClient(new WebViewClient());
wv.Settings.JavaScriptEnabled = true;
wv.Settings.DomStorageEnabled = true;
wv.Settings.SetSupportZoom(true);
wv.Settings.DisplayZoomControls = false;
wv.Settings.BuiltInZoomControls = true;
wv.Settings.CacheMode = CacheModes.Default;
wv.Settings.UseWideViewPort = true;
wv.Settings.LoadWithOverviewMode = true;
wv.SetInitialScale(1);
wv.LoadUrl("file:///android_asset/index.html");
}
public override void OnCreateContextMenu(IContextMenu menu, View v, IContextMenuContextMenuInfo menuInfo)
{
base.OnCreateContextMenu(menu, v, menuInfo);
WebView webView = (WebView)v;
result = webView.GetHitTestResult();
if (result.GetType().ToString().Equals("SRC_ANCHOR_TYPE") || result.GetType().ToString().Equals("ANCHOR_TYPE"))
{
var item = menu.Add("copylink");
item.SetOnMenuItemClickListener(this);
}
}
but "result.GetType()" its its not detect anchor type link the "result.GetType()" is not detect any link in webview when it get pressed longtoch..
If you want to add a item to the menu, you should override OnActionModeStarted method. then add the SetOnMenuItemClickListenerlike following code.
public override void OnActionModeStarted(ActionMode mode)
{
IMenu menu = mode.Menu;
menu.Add("Add To Notes");
menu.GetItem(0).SetOnMenuItemClickListener(new MyMenuItemOnMenuItemClickListener(this));
base.OnActionModeStarted(mode);
}
internal class MyMenuItemOnMenuItemClickListener : Java.Lang.Object, IMenuItemOnMenuItemClickListener
{
private MainActivity mainActivity;
public MyMenuItemOnMenuItemClickListener(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
public bool OnMenuItemClick(IMenuItem item)
{
Toast.MakeText(mainActivity, "You click the Add To Notes", ToastLength.Short).Show();
return true;
}
}
Here is running GIF.
If you want to create a new menu, you can use menu.Clear();
public override void OnActionModeStarted(ActionMode mode)
{
IMenu menu = mode.Menu;
menu.Clear();
menu.Add("Add To Notes");
menu.GetItem(0).SetOnMenuItemClickListener(new MyMenuItemOnMenuItemClickListener(this));
base.OnActionModeStarted(mode);
}
Here is running screenshot.
Update
If you want to get the Type of long click, you should make sure type of result.Type is Webkit.HitTestResult, you use result.GetType(), Type is System.Type. So you can get the correct type, you can refer to the following code.
WebView.HitTestResult result = webView.GetHitTestResult();
Android.Webkit.HitTestResult myresult = result.Type;
You can refer to the debug gif.

How to add radio button to radio group in Xamarin for Android via code behind?

The title already describes what I want to do: I'm working with Xamarin for Android. Now I'd like to have a RadioGroup and fill it with RadioButtons via code behind and not via XAML. How can I do this? I don't find any setter...
Why do I need this? My small Android app has a Load button which loads entries from a web service. Each entry should be represented by a RadioButton so that the user has a flexible selection.
Here's an example I put together for you that creates the Radio Group and Radio Buttons dynamically along with how to determine which button is selected by the user at run-time.
protected override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
var layout = new LinearLayout(this) {
Orientation = Orientation.Vertical
};
// Create Radio Group
var rg = new RadioGroup(this);
layout.AddView(rg);
// Add Radio Buttons to Radio Group
for (int i = 1; i < 6; i++) {
var rb = new RadioButton(this) { Text = $"Radio Button {i}" };
rg.AddView(rb);
}
// Show Radio Button Selected
lblOutput = new TextView(this);
layout.AddView(lblOutput);
rg.CheckedChange += (s, e) => {
lblOutput.Text = $"Radio Button {e.CheckedId} Selected";
};
SetContentView(layout);
}
Output
As an alternative, I've implemented a solution using a ListView:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
Speakers = new List<ISpeaker>();
FindViewById<Button>(Resource.Id.loadButton).Click += LoadButtonOnClick;
}
private async void LoadButtonOnClick(object sender, EventArgs e)
{
Speakers = await LoadSpeakersAsync();
var sourceListView = FindViewById<ListView>(Resource.Id.sourceListView);
sourceListView.Adapter = new ArrayAdapter<ISpeaker>(this, Android.Resource.Layout.SimpleListItem1, Speakers);
}

Visit Last Loaded URL

I'm making an app in Xamarin android where user navigates. The app contains webview. When a user opens webview, url gets loaded and browsing can be done. When he ends the app and opens it again, URL is loaded again instead of viewing last visited URL.
I don't know what I'm doing wrong here.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
webView = FindViewById<WebView>(Resource.Id.webView1);
webView.SetWebViewClient(new MyWebClient());
CookieManager.Instance.SetAcceptCookie(true);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.SetAppCacheEnabled(true);
webView.LoadUrl(getUrl());
webView.SetPadding(0, 0, 0, 0);
webView.Settings.SetSupportZoom(true);
}
public void saveUrl(String url)
{
ISharedPreferences sp = GetSharedPreferences("SP_WEBVIEW_PREFS", FileCreationMode.Private);
ISharedPreferencesEditor editor = sp.Edit();
editor.PutString("SAVED_URL", url);
editor.Commit();
}
public String getUrl()
{
ISharedPreferences sp = GetSharedPreferences("SP_WEBVIEW_PREFS", FileCreationMode.Private);
//If you haven't saved the url before, the default value will be google's page
return sp.GetString("SAVED_URL", "http://google.com");
}
public void onPageFinished(WebView view, String url)
{
this.onPageFinished(view, url);
saveUrl(url);
}
}
internal class MyWebClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
view.LoadUrl(url);
return false;
}
}
You have placed onPageFinished method in an Activity. It should be overridden in MyWebClient class as below:
internal class MyWebClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
view.LoadUrl(url);
return false;
}
public override void OnPageFinished(WebView view, String url)
{
base.OnPageFinished(view, url);
//Save the url here.
//This method itself gives you the last url loaded as it's url Parameter.
ISharedPreferences sp = Application.Context.GetSharedPreferences("SP_WEBVIEW_PREFS", FileCreationMode.Private);
ISharedPreferencesEditor editor = sp.Edit();
editor.PutString("SAVED_URL", url);
editor.Commit().
}
}
This method will be automatically called when URL finished loading and then you will store your loaded URL in this method.

Change "Active" icon on selected NavigationPage when using TabbedPage

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);
}

Resources