I am working on a Xamarin.Forms application. I have this tabbed page renderer in iOS:
public class TabbedPageRenderer : TabbedRenderer
{
private MainPage _page;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_page = (MainPage)e.NewElement;
}
else
{
_page = (MainPage)e.OldElement;
}
try
{
var tabbarController = (UITabBarController)this.ViewController;
if (null != tabbarController)
{
tabbarController.ViewControllerSelected += OnTabBarReselected;
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
if (TabBar.SelectedItem.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "pause.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "play.png";
}
App.pauseCard = true;
}
}
}
This basically changes the icon on my Play tab to pause and play. This is working good in iOS. But I am struggling on how to have the same function (basically convert this to Android) in Android side.
Can any point me to the right direction? Basically help me? :-)
Note: I am pretty new with Android development.
EDIT: This is what it would look like in iOS.
Pause Mode:
Play Mode:
There is a blog post by Xamarin's James Montemagno which explains how to achieve this requirement.
Basically, it uses Custom Tab which inherits from TabbedPage which initialize an event UpdateIcons to be fired on Tab Current Page Changed event CurrentPageChanged
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}
Now Android needs a custom renderer to subscribe to the UpdateIcons event and perform icon changes
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}
Related
I've implemented native ZXing-embedded library in my Xamarin.Android project and everything's working fine except one issue that when I try to scan the QR or Barcodes from some distance, then it returns some random irrelevant values which are totally different from the original ones. After checking this post I've tried restricting the scan modes but it made no difference and it is still returning wrong values. Any help would be really appreciable.
Thanks in advance!
Update 2:
Here's is my code, you can check and let me know if there's something that needs to be corrected in it:
public class CustomScannerActivity : Activity, DecoratedBarcodeView.ITorchListener
{
public const int CUSTOMIZED_REQUEST_CODE = 1;
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
private ImageButton switchFlashlightButton;
private ImageButton cameraButton;
private ViewfinderView viewfinderView;
TextView txtViewBottomText;
private bool torchOn;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
this.ActionBar.Hide();
SetContentView(Resource.Layout.activity_custom_scannerview);
barcodeScannerView = (DecoratedBarcodeView)FindViewById(Resource.Id.zxing_barcode_scanner);
barcodeScannerView.SetTorchListener(this);
var greenOverlay = (View)FindViewById(Resource.Id.view1);
Android.Util.DisplayMetrics displayMetrics = Resources.DisplayMetrics;
var scanWidth = (int)(displayMetrics.WidthPixels * 0.65);
barcodeScannerView.BarcodeView.FramingRectSize = new Size(scanWidth, 100);
greenOverlay.LayoutParameters.Width = scanWidth;
greenOverlay.LayoutParameters.Height = scanWidth;
CameraSettings settings = barcodeScannerView.BarcodeView.CameraSettings;
switchFlashlightButton = (ImageButton)FindViewById(Resource.Id.switch_flashlight);
cameraButton = (ImageButton)FindViewById(Resource.Id.camera);
viewfinderView = (ViewfinderView)FindViewById(Resource.Id.zxing_viewfinder_view);
txtViewBottomText = (TextView)FindViewById(Resource.Id.zxing_status_view);
txtViewBottomText.Text = AppResources.ScanAutomatically;
if (MainActivity.camPosition)
{
settings.RequestedCameraId = Convert.ToInt32(Android.Hardware.CameraFacing.Front);
switchFlashlightButton.Visibility = ViewStates.Gone;
barcodeScannerView.BarcodeView.CameraSettings = settings;
barcodeScannerView.Resume();
}
else
{
settings.RequestedCameraId = Convert.ToInt32(Android.Hardware.CameraFacing.Back);
switchFlashlightButton.Visibility = ViewStates.Visible;
barcodeScannerView.BarcodeView.CameraSettings = settings;
barcodeScannerView.Resume();
}
switchFlashlightButton.Click += (s, e) =>
{
if (!torchOn && !MainActivity.camPosition)
{
barcodeScannerView.SetTorchOn();
}
else
{
barcodeScannerView.SetTorchOff();
}
torchOn = !torchOn;
};
cameraButton.Click += (s, e) =>
{
//CameraSettings settings = barcodeScannerView.BarcodeView.CameraSettings;
if (barcodeScannerView.BarcodeView.IsPreviewActive)
{
barcodeScannerView.Pause();
}
//swap the id of the camera to be used
if (settings.RequestedCameraId == Convert.ToInt32(Android.Hardware.CameraFacing.Front))
{
settings.RequestedCameraId = Convert.ToInt32(Android.Hardware.CameraFacing.Back);
switchFlashlightButton.Visibility = ViewStates.Visible;
barcodeScannerView.SetTorchOff();
MainActivity.camPosition = false;
barcodeScannerView.BarcodeView.CameraSettings = settings;
barcodeScannerView.Resume();
}
else
{
settings.RequestedCameraId = Convert.ToInt32(Android.Hardware.CameraFacing.Front);
switchFlashlightButton.Visibility = ViewStates.Gone;
barcodeScannerView.SetTorchOff();
MainActivity.camPosition = true;
barcodeScannerView.BarcodeView.CameraSettings = settings;
barcodeScannerView.Resume();
}
};
// if the device does not have flashlight in its camera,
// then remove the switch flashlight button...
if (!hasFlash())
{
switchFlashlightButton.Visibility = ViewStates.Gone;
}
capture = new CaptureManager(this, barcodeScannerView);
capture.InitializeFromIntent(Intent, savedInstanceState);
capture.Decode();
}
protected override void OnResume()
{
base.OnResume();
if (capture != null)
{
capture.OnResume();
}
}
protected override void OnPause()
{
base.OnPause();
if (capture != null)
{
capture.OnPause();
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if (capture != null)
{
capture.OnDestroy();
}
}
protected override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
if (capture != null)
{
capture.OnSaveInstanceState(outState);
}
}
//public override bool OnKeyDown([GeneratedEnum] Keycode keyCode, KeyEvent e)
//{
// return barcodeScannerView.OnKeyDown(keyCode, e) || base.OnKeyDown(keyCode, e);
//}
private bool hasFlash()
{
return this.ApplicationContext.PackageManager.HasSystemFeature(Android.Content.PM.PackageManager.FeatureCameraFlash);//"android.hardware.camera.flash"
}
public void OnTorchOff()
{
}
public void OnTorchOn()
{
}
}
I'm making a xamarin.form app,
I have a custom render for streaming the camera inside a view , I've followed the tutorial here:
camera stream tutorial
I've managed to correctly show the camera stream inside a view, now I'm trying to create a button that toggle the flash:
here is my custom renderer:
using System;
using System.Diagnostics;
using Hangover.Camera.Factory;
using Hangover.GUIPersonalizzata;
using Xamarin.Forms;
//Questa classe permette di visualizzare lo stream della fotocamera
namespace Hangover.Camera.Views
{
public class CameraStream:View
{
public static readonly BindableProperty CameraProperty = BindableProperty.Create(
propertyName: "Camera",
returnType: typeof(CameraOptions),
declaringType: typeof(CameraStream),
defaultValue: CameraOptions.Rear);
//Funzioni Fotocamera
private Fotocamera _fotocamera;
public event EventHandler flash_event;
//costruttore di convenienza
public CameraStream()
{
}
public CameraStream(Fotocamera fotocamera){
_fotocamera = fotocamera;
}
public CameraOptions Camera
{
get { return (CameraOptions)GetValue(CameraProperty); }
set { SetValue(CameraProperty, value); }
}
public void gestisciFlash(BottoneSwitch btn){
if (flash_event != null)
flash_event.Invoke(btn, null);
}
}
}
and here is the iOS implementation:
using System;
using System.Diagnostics;
using Hangover.Camera.Factory;
using Hangover.Camera.Views;
using Hangover.GUIPersonalizzata;
using Hangover.iOS.CustomRenderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CameraStream), typeof(CameraStreamRenderer))]
namespace Hangover.iOS.CustomRenderer
{
public class CameraStreamRenderer : ViewRenderer<CameraStream, UICameraPreview>,ICameraFunctions
{
UICameraPreview uiCameraPreview; // fotocamera nativa
protected override void OnElementChanged(ElementChangedEventArgs<CameraStream> elem)
{
base.OnElementChanged(elem);
if (Control == null)
{
uiCameraPreview = new UICameraPreview(elem.NewElement.Camera);
SetNativeControl(uiCameraPreview);
var camera_stream = (CameraStream)elem.NewElement;
camera_stream.flash_event += (object sender, EventArgs e) => {
Debug.Write("teeeest");
};
}
}
//Invocato quando la view viene chiusa
protected override void Dispose(bool disposing)
{
if (disposing)
{
Control.CaptureSession.Dispose();
Control.Dispose();
}
base.Dispose(disposing);
}
public void attivaFlash()
{
Debug.Write("flash");
Debug.Write("flash");
Debug.Write("flash");
}
public void distattivaFlash()
{
throw new NotImplementedException();
}
public void scattaFoto()
{
throw new NotImplementedException();
}
public void ruotaFotocamera(BottoneSwitch btn)
{
if (!btn.isON){// mostro la post
Debug.Write("mostra fotocamera post");
}else{//mostra ant
Debug.Write("mostra fotocamera ant");
}
}
}
}
so using this event:
public void gestisciFlash(BottoneSwitch btn){
if (flash_event != null)
flash_event.Invoke(btn, null);
}
I should be able to print "teeest" but flash_event is always null and I don't know what to do.
I've tried the solution presented here firing custom render event but with no luck.
Any suggestions?
EDIT
protected override void OnElementChanged(ElementChangedEventArgs<CameraStream> e)
{
if(e.OldElement != null){
}
if(e.NewElement != null){
if (Control == null)
{
uiCameraPreview = new UICameraPreview(new Camera.CameraOptions());
SetNativeControl(uiCameraPreview);
}
var camera_stream = (CameraStream)e.NewElement;
camera_stream.flash_event += (object sender, EventArgs ea) => {
attivaFlash();
};
}
base.OnElementChanged(e);
}
refactored the code as suggested by #Benl still not working , this:
public void gestisciFlash(BottoneSwitch btn){
if (flash_event != null)
flash_event.Invoke(btn, null);
}
Is still null.
Edit:
Assumption: Some camera device generating the flash/torch light event is attached.
CameraStreamRenderer.cs:
OnElementChanged(ElementChangedEventArgs<CameraStream> e)
{
base.OnElementChanged(e);
if (Control == null)
{
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
uiCameraPreview = new UICameraPreview(e.NewElement.Camera);
SetNativeControl(uiCameraPreview);
}
if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
uiCameraPreview.Flash -= OnFlash;
}
if (e.NewElement != null)
{
// Configure the control and subscribe to event handlers
uiCameraPreview.Flash += OnFlash;
}
}
void OnFlash(object sender, EventArgs e)
{
Debug.WriteLine("Flash");
}
However, the flash event must be generated somewhere, not shown in the original question.
Assuming the flash event might be generated in UICameraPreview in an Observer with assumed key "torchActive".
UICameraPreview.cs:
public event EventHandler<EventArgs> Flash;
protected virtual void OnFlash()
{
Flash?.Invoke(this, new EventArgs());
}
void Initialize()
{
...
AVCaptureDevice device = ...
...
if (device == null)
{
return;
}
device.AddObserver(
key: "torchActive",
options: NSKeyValueObservingOptions.New,
observer: (c) =>
{
OnFlash();
});
device.RemoveObserver not shown above.
I have a a map that displays a route between points. This is working but now I want to pass some color values from PCL. I have a custom renderer for android and a class acting as bridge between PCL and android with bindable properties in it.
(For the map I use the PCL implementation and extends it with the custom renderer)
For now I got:
(android : CustomMapRenderer)
[assembly: ExportRenderer(typeof(CustomMap), typeof(MapOverlay.Droid.CustomMapRenderer))]
namespace MapOverlay.Droid
{
public class CustomMapRenderer : MapRenderer , ICustomMap
{
List<Position> routeCoordinates;
Int32 RouteColor;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
routeCoordinates = formsMap.RouteCoordinates;
Control.GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
if (e.PropertyName == "VisibleRegion")
{
var polylineOptions = new PolylineOptions();
polylineOptions.InvokeColor(0x66FF0000);
foreach (var position in routeCoordinates)
{
polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
}
NativeMap.AddPolyline(polylineOptions);
}
}
public void working()
{
Log.Debug("xxxx", "WORKING");
}
}
}
Now the class acting as bridge from PCL to Android
(PCL : CustomMap)
namespace SomeNamespace
{
public class CustomMap : Map
{
public static readonly BindableProperty RouteCoordinatesProperty =
BindableProperty.Create<CustomMap, List<Position>>(p => p.RouteCoordinates, new List<Position>());
public static readonly BindableProperty RouteColorProperty =
BindableProperty.Create<CustomMap, int>(p => p.RouteColor, 0x66FF0000);
//Property used to add points to the map. Then polyline utility will draw a line beteween thoses points
public List<Position> RouteCoordinates
{
get { return (List<Position>)base.GetValue(RouteCoordinatesProperty); }
set {
base.SetValue(RouteCoordinatesProperty, value);
}
}
public Int32 RouteColor
{
get { return (Int32)base.GetValue(RouteColorProperty); }
set { base.SetValue(RouteColorProperty, value); }
}
public CustomMap()
{
RouteCoordinates = new List<Position>();
}
}
}
So as you can see I added an Int32 RouteColor variable wich should be used in the CustomMapRenderer to change the color of the displayed route.
But when I change this value in my PCL code like so :
mCustomMap.RouteColor = 0x22AA0000;
It triggers an OnElementPropertyChanged response but not an OnElementChanged event.
So I can't get the changed value. I only know that it DID changed (with the OnElementPropertyChanged).
If someone knows how to bypass this phenomena... All suggestions are welcome ;-)
Thanks in advance !
Element represents the forms element, which in this case should be CustomMap. You can use it to retrieve the property values.
For e.g.:
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
....
//if RouteColor is the property that changed
if (e.PropertyName == nameof(CustomMap.RouteColor))
{
//get new value
var newColor = (Element as CustomMap)?.RouteColor;
//and, update native control
....
I had completed my App's home page in Xamarin.Forms Portable.
Now i want to add a Flotation Action Button In my Android Project !
Is there any way to add FAB for Android in my existing home page, which was coded in Xamarin.Forms Portable.
OR
I want to create a separate home page for Android and add call it as a MainPage for android ?
Thanks and Regards.
Before the official support library came out I ported the FAB over.
There is now a Xamarin.Forms sample in my GitHub repo that you can use: https://github.com/jamesmontemagno/FloatingActionButton-for-Xamarin.Android
Build a Custom Control
For the FAB's properties to be bindable in Xamarin.Forms, we need a custom control with bindable properties.
public class FloatingActionButtonView : View
{
public static readonly BindableProperty ImageNameProperty = BindableProperty.Create<FloatingActionButtonView,string>( p => p.ImageName, string.Empty);
public string ImageName
{
get { return (string)GetValue (ImageNameProperty); }
set { SetValue (ImageNameProperty, value); }
}
public static readonly BindableProperty ColorNormalProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorNormal, Color.White);
public Color ColorNormal
{
get { return (Color)GetValue (ColorNormalProperty); }
set { SetValue (ColorNormalProperty, value); }
}
public static readonly BindableProperty ColorPressedProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorPressed, Color.White);
public Color ColorPressed
{
get { return (Color)GetValue (ColorPressedProperty); }
set { SetValue (ColorPressedProperty, value); }
}
public static readonly BindableProperty ColorRippleProperty = BindableProperty.Create<FloatingActionButtonView,Color>( p => p.ColorRipple, Color.White);
public Color ColorRipple
{
get { return (Color)GetValue (ColorRippleProperty); }
set { SetValue (ColorRippleProperty, value); }
}
...
}
We will then map each property to a corresponding property on the native FAB control.
Attach a Renderer
If we want to use a native control in Xamarin.Forms, we need a renderer. For simplicity, lets use a ViewRenderer. This renderer will map our custom FloatingActionButtonView to an Android.Widget.FrameLayout.
public class FloatingActionButtonViewRenderer : ViewRenderer<FloatingActionButtonView, FrameLayout>
{
...
private readonly Android.Content.Context context;
private readonly FloatingActionButton fab;
public FloatingActionButtonViewRenderer()
{
context = Xamarin.Forms.Forms.Context;
fab = new FloatingActionButton(context);
...
}
protected override void OnElementChanged(ElementChangedEventArgs<FloatingActionButtonView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
if (e.OldElement != null)
e.OldElement.PropertyChanged -= HandlePropertyChanged;
if (this.Element != null) {
//UpdateContent ();
this.Element.PropertyChanged += HandlePropertyChanged;
}
Element.Show = Show;
Element.Hide = Hide;
SetFabImage(Element.ImageName);
fab.ColorNormal = Element.ColorNormal.ToAndroid();
fab.ColorPressed = Element.ColorPressed.ToAndroid();
fab.ColorRipple = Element.ColorRipple.ToAndroid();
var frame = new FrameLayout(Forms.Context);
frame.RemoveAllViews();
frame.AddView(fab);
SetNativeControl (frame);
}
public void Show(bool animate = true)
{
fab.Show(animate);
}
public void Hide(bool animate = true)
{
fab.Hide(animate);
}
void HandlePropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Content") {
Tracker.UpdateLayout ();
}
else if (e.PropertyName == FloatingActionButtonView.ColorNormalProperty.PropertyName)
{
fab.ColorNormal = Element.ColorNormal.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorPressedProperty.PropertyName)
{
fab.ColorPressed = Element.ColorPressed.ToAndroid();
}
else if (e.PropertyName == FloatingActionButtonView.ColorRippleProperty.PropertyName)
{
fab.ColorRipple = Element.ColorRipple.ToAndroid();
}
...
}
void SetFabImage(string imageName)
{
if(!string.IsNullOrWhiteSpace(imageName))
{
try
{
var drawableNameWithoutExtension = Path.GetFileNameWithoutExtension(imageName);
var resources = context.Resources;
var imageResourceName = resources.GetIdentifier(drawableNameWithoutExtension, "drawable", context.PackageName);
fab.SetImageBitmap(Android.Graphics.BitmapFactory.DecodeResource(context.Resources, imageResourceName));
}
catch(Exception ex)
{
throw new FileNotFoundException("There was no Android Drawable by that name.", ex);
}
}
}
}
Pull it all Together
OK! We've built the custom control, and mapped it to a renderer. The last step is laying out the control in our view.
public class MainPage : ContentPage
{
public MainPage()
{
var fab = new FloatingActionButtonView() {
ImageName = "ic_add.png",
ColorNormal = Color.FromHex("ff3498db"),
ColorPressed = Color.Black,
ColorRipple = Color.FromHex("ff3498db")
};
// Main page layout
var pageLayout = new StackLayout {
Children =
{
new Label {
VerticalOptions = LayoutOptions.CenterAndExpand,
XAlign = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}};
var absolute = new AbsoluteLayout() {
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand };
// Position the pageLayout to fill the entire screen.
// Manage positioning of child elements on the page by editing the pageLayout.
AbsoluteLayout.SetLayoutFlags(pageLayout, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(pageLayout, new Rectangle(0f, 0f, 1f, 1f));
absolute.Children.Add(pageLayout);
// Overlay the FAB in the bottom-right corner
AbsoluteLayout.SetLayoutFlags(fab, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(fab, new Rectangle(1f, 1f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
absolute.Children.Add(fab);
Content = absolute;
}
}
Complete code on Github : Floating Action Button Xamarin.Forms
I have an anchor which has three elements. Each element will has to respond for a click event.
I have this as and Android web view app.
Surprisingly click event works in android browser, but when I try that android webview app, nothing happens. Please refer the code below.
I don't know what I am missing so the click events doesn't work in android webview app.
$("#cont2 li a").live('click', function (e) {
//e.preventDefault();
this.blur();
var name = $(this).attr("name");
var staffid = $(this).attr("staffid");
var recordid = $(this).attr("recordid");
var primary = $(this).attr("primary");
if (name == "deletestaff") {
// delete sales staff
var dretVal = confirm("Delete contact staff " + $(this).attr("staffname") + "?");
if (dretVal == false) {
return false;
} else {
var txtprimaryrecordid = $("#txtprimaryrecordid").val();
var txtprimarystaffid = $("#txtprimarystaffid").val();
if (txtprimaryrecordid == 'undefined') {
txtprimaryrecordid = "";
}
if (txtprimarystaffid == 'undefined') {
txtprimarystaffid = "";
}
if (txtprimaryrecordid == recordid) {
$("#txtprimaryrecordid").val("");
}
if (txtprimarystaffid == staffid) {
$("#txtprimarystaffid").val("");
}
$(this).parents('li').remove();
// show deleted item
$('#staffs input[type=checkbox]').each(function () {
var delstaffid = $(this).attr("staffid");
if (staffid == delstaffid) {
$(this).attr("checked", false).checkboxradio("refresh");
}
});
}
}
Got it. Just had to implement WebChromeClient...
private class WebChromeClient extends WebChromeClient{
#Override
public boolean onJsAlert(WebView view, String url, String message,JsResult result)
{
Log.e("alert triggered", message);
return false;
}
}