How to set WKWebviewConfiguration for a xamarin forms webview? - xamarin.forms

I have a Xamarin forms project where I need to set certain configurations for allowing file access. In native xamarin ios project, it was set through the WKWebviewConfiguration like,
_scormWKPreferences = new WKPreferences
{
JavaScriptEnabled = true
};
ClearCookies();
_scormWKPreferences.SetValueForKey(NSObject.FromObject(true), (NSString)"allowFileAccessFromFileURLs");
// _scormWKPreferences.SetValueForKey(NSObject.FromObject(true), (NSString)"allowUniversalAccessFromFileURLs");
_scormWKWebconfiguration = new WKWebViewConfiguration();
_scormWKWebconfiguration.Preferences = _scormWKPreferences;
_scormWKUserContentController = new WKUserContentController();
_scormWKUserContentController.AddScriptMessageHandler(this, WKSCRIPT_HANDLER);
_scormWKWebconfiguration.UserContentController = _scormWKUserContentController;
CGRect viewRect = new CGRect(0, 0, View.Frame.Width, View.Frame.Height);
_courseWKWebview = new WKWebView(viewRect, _scormWKWebconfiguration);
I have to achieve the same in the forms project as well. Currently, I have added a Custom Renderer in the iOS module but not able to set the configuration. Please find the CustomRenderer below.
[assembly: ExportRenderer(typeof(WebView), typeof(ScholarApp.Droid.Reader.Scorm.ScormCustomRenderer))]
namespace ScholarApp.Droid.Reader.Scorm
{
public class ScormCustomRenderer : Xamarin.Forms.Platform.iOS.WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement == null && e.NewElement != null)
{
WKPreferences wkPreferences = new WKPreferences
{
JavaScriptEnabled = true
};
wkPreferences.SetValueForKey(NSObject.FromObject(true), (NSString)"allowFileAccessFromFileURLs");
WKWebViewConfiguration wkConfig = new WKWebViewConfiguration();
wkConfig.Preferences = wkPreferences;
WKWebView wkWebView = new WKWebView(Frame, wkConfig);
}
}
}
}
How can I set this configuration to my WebView?

Also you may try to pass the configuration via the parametrized WkWebViewRenderer constructor
public class CustomWebViewRenderer : WkWebViewRenderer
{
static WKWebViewConfiguration CreateConfiguration() => new WKWebViewConfiguration
{
Preferences = new WKPreferences
{
JavaScriptEnabled = true
}
};
public CustomWebViewRenderer() : base(CreateConfiguration()) { }
}

You can adapt your renderer:
public class MyWebViewRenderer : ViewRenderer<WebView, WKWebView>
{
WKWebView _wkWebView;
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
WKPreferences wkPreferences = new WKPreferences
{
JavaScriptEnabled = true
};
wkPreferences.SetValueForKey(NSObject.FromObject(true), (NSString)"allowFileAccessFromFileURLs");
WKWebViewConfiguration wkConfig = new WKWebViewConfiguration();
wkConfig.Preferences = wkPreferences;
_wkWebView = new WKWebView(Frame, config);
SetNativeControl(_wkWebView);
}
if (e.NewElement != null)
{
Control.LoadRequest(new NSUrlRequest(new NSUrl(Element.Source as UrlWebViewSource).Url)));
}
}
}

Related

How can I Add pin Mark to Image in xamarin.forms?

How can I Add pin Mark to Image and get the Current Position of this Mark in xamarin.forms
You can use custom renders to custom the pin in each platform like:
Ios:
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
annotationView.Image = UIImage.FromFile("pin.png");
annotationView.CalloutOffset = new CGPoint(0, 0);
annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
((CustomMKAnnotationView)annotationView).Name = customPin.Name;
((CustomMKAnnotationView)annotationView).Url = customPin.Url;
}
annotationView.CanShowCallout = true;
return annotationView;
}
android:
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
marker.SetSnippet(pin.Address);
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
return marker;
}

Xamarin Maps on android custom pins query

I am working on a xamarin forms app using xamarin forms maps for Android at the moment that tracks my location and depending on my proximity to a custom pin i have placed on the map will change in size depending on my proximity.
Basically if within a few meters the icon is 32x32 and farther away its 24x24.
Ive created a custom map renderer that places my pins from a JSON file and this is ok.
When my map form page loads in both my simulator and an actual android device the methods run and get my proximity based on my location and appropriately alter the size of the map pin.
However, this does not work as i move around.
For some reason my overridden CreateMarker method does not trigger when my location changes unless i call Content=customMap. Doing this only causes my map to load over and over and basically will not work.
I have a method in my about page called UpdateMap3() that is called when the users location changes. However, as stated i cant get the pins to update their size as i get nearer the pins while the app is running.
Ive included my forms page code behind below and markup below that and finally my map renderer below that.
Any help would be hugely appreciated.
Thanls
using System;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms.Maps;
using Xamarin.Essentials;
using Distance = Xamarin.Forms.Maps.Distance;
using Google.Protobuf.WellKnownTypes;
using static Google.Protobuf.Reflection.FieldDescriptorProto.Types;
namespace MAPS.Views
{
public partial class AboutPage : ContentPage
{
IlocationUpdateService loc;
public AboutPage()
{
InitializeComponent();
// Task.Delay(2000);
UpdateMap();
}
async void OnActionSheetCancelDeleteClicked()
{
bool answer = await DisplayAlert("Location Request", "Please enable location services to use this app", "Settings", "Cancel");
if (answer == true)
{
DependencyService.Get<ILocSettings>().OpenSettings();
}
}
protected override void OnAppearing()
{
base.OnAppearing();
bool gpsStat = DependencyService.Get<ILocSettings>().isGpsAvailable();
if (gpsStat == false)
{
OnActionSheetCancelDeleteClicked();
}
loc = DependencyService.Get<IlocationUpdateService>();
loc.LocationChanged += (object sender, ILocationEventArgs args) =>
{
String lat1 = args.Latitude.ToString();
String lng1 = args.Longitude.ToString();
//String lat1 = "55.099300";
// String lng1 = "-8.279740";
UpdateMap3(lat1, lng1); ;
};
loc.GetUsedLocation();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
loc = null;
}
List<Place> placesList = new List<Place>();
private async void UpdateMap()
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
var request = new Xamarin.Essentials.GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(30));
var location = await Geolocation.GetLocationAsync(request);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat,place.geometry.location.lng);
// string color = getDist(location1, location);
string color = "purple";
if (color == "purple")
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity+"*",
Name = "Xamarin",
icon = "icon.png",
Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
else
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity,
Name = "Xamarin",
icon = "pin.png",
Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
}
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(location.Latitude, location.Longitude), Distance.FromKilometers(0.15))); ;
Content = customMap;
}
public string getDist(Location loc, Xamarin.Essentials.Location currentLoc)
{
string color = "red";
// bool geo = false;
double latEnd = loc.lat;
double lngEnd = loc.lng;
/// Position(currentLoc.lat, currentLoc.lng);
double dist = currentLoc.CalculateDistance(latEnd, lngEnd, DistanceUnits.Kilometers);
if (dist < 0.05) //5m distance
{
color = "purple";
}
else
{
color = "red";
}
return color;
}
public void getNewPins()
{
InitializeComponent();
}
public void getPin()
{
var pr = new PopUp();
}
private async void UpdateMap3(String lat, String lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat, place.geometry.location.lng);
Xamarin.Essentials.Location location = new Xamarin.Essentials.Location(Convert.ToDouble(lat), Convert.ToDouble(lng));
string color = getDist(location1, location);
if (color == "purple")
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity,
Name = "Xamarin",
icon = "icon.png",
Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> {pin2};
customMap.Pins.Add(pin2);
}
else
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,
Position = new Position(place.geometry.location.lat, place.geometry.location.lng),
Label = place.id,
Address = place.vicinity+"*",
Name = "Xamarin",
icon = "pin.png",
Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> { pin2 };
customMap.Pins.Add(pin2);
// Content.IsEnabled = true;
// customMap.CustomPins.Remove(pin);
}
}
// customMap.Pins.Clear();
// customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(Convert.ToDouble(lat), Convert.ToDouble(lng)), Distance.FromKilometers(0.15))); ;
// Content = customMap;
// customMap.Pins.Add(pins);
}
}
}
Below is my forms page markup.
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAPS;assembly=MAPS"
x:Class="MAPS.Views.AboutPage" Title="Explore">
<StackLayout>
<local:CustomMap x:Name="customMap" IsShowingUser="True"
MapType="Street" />
</StackLayout>
</ContentPage>
Below is my Android custom renderer
using Android.Content;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Widget;
using MAPS;
using MAPS.Droid;
using MAPS.Views;
using Newtonsoft.Json;
using Rg.Plugins.Popup;
using Rg.Plugins.Popup.Animations;
using Rg.Plugins.Popup.Contracts;
using Rg.Plugins.Popup.Enums;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using static MAPS.Droid.CustomMapRenderer;
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace MAPS.Droid
{
public class CustomMapRenderer : Xamarin.Forms.Maps.Android.MapRenderer, GoogleMap.IInfoWindowAdapter
{
List<CustomPin> customPins;
public string popInfo;
public CustomMapRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
NativeMap.InfoWindowClick -= OnInfoWindowClick;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
Control.GetMapAsync(this);
}
}
protected override void OnMapReady(GoogleMap map)
{
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
}
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
// CustomPin p = new CustomPin();
//foreach (var cp in customPins)
//{
// if (cp.Position == pin.Position)
// {
// p = cp;
// }
//}
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
// marker.SetIcon(BitmapDescriptorFactory.FromFile(p.icon));
if (pin.Address.Contains('*'))
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin2));
}
else
{
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
}
marker.Visible(true);
var a = NativeMap.AddMarker(marker);
a.ShowInfoWindow();
// marker.SetSnippet(pin.Address.Replace("*", " "));
return marker;
}
void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
{
getPlaceData(markerdata.markerData.title, markerdata.markerData.lat, markerdata.markerData.lng);
showPopUp();
}
public Android.Views.View GetInfoContents(Marker marker)
{
return null;
}
public void myMod(Marker marker)
{
}
public Android.Views.View GetInfoWindow(Marker marker)
{
markerdata.markerData.title = marker.Title;
markerdata.markerData.lat = marker.Position.Latitude.ToString("0.#####");
markerdata.markerData.lng = marker.Position.Longitude.ToString("0.#####");
// ds.Id = marker.Id;
// getPlaceData(marker.Title, marker.Position.Latitude.ToString("0.#####"), marker.Position.Longitude.ToString("0.#####"));
// showPopUp();
return null;
}
public string Number;
private async void showPopUp()
{
var Pr = new Views.PopUp();
var scaleAnimation = new ScaleAnimation
{
PositionIn = MoveAnimationOptions.Right,
PositionOut = MoveAnimationOptions.Left
};
Pr.Animation = scaleAnimation;
await PopupNavigation.PushAsync(Pr);
}
CustomPin GetCustomPin(Marker annotation)
{
return null;
}
private void getPlaceData(String name, String Lat, String Lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
foreach (var place in resultObject.results)
{
if((name==place.id)&&(Lat ==place.geometry.location.lat.ToString("0.#####"))&&(Lng ==place.geometry.location.lng.ToString("0.#####")))
{
getData.Instance.Id = place.id;
getData.Instance.lat = place.geometry.location.lat.ToString("0.#####");
getData.Instance.lng = place.geometry.location.lng.ToString("0.#####");
getData.Instance.marker2 = place.name;
getData.Instance.family = place.family;
getData.Instance.origin = place.Origin;
getData.Instance.date = place.Date;
getData.Instance.commonName = place.CommonName;
// getData.Instance.title = marker.Title;
}
}
}
}
}

Custom Keyboard in Xamarin forms

I've read the many posts on the forum and on StackOverflow and other places on making custom keyboards, but have not found an approach that will work for my Xamarin forms cross-platform project. It is programmatically generated.
For example, I built this keyboard that was recommended in several places:
I try to integrate this into my Xamarin forms app but not able to do this
https://github.com/Vaikesh/CustomKeyboard/blob/master/CustomKeyboard/Activity1.cs
It works fine as a standalone
I want Hebrew language keyboard in my application Like this
I would appreciate any help.
Thank you.
Custom Keyboard in Xamarin forms
You could create a PageRenderer and use native .axml layout file to create the custom Keyboard.
For example, my KeyboardPageRenderer :
[assembly: ExportRenderer(typeof(MyKeyboardPage), typeof(KeyboardPageRenderer))]
...
public class KeyboardPageRenderer : PageRenderer
{
public CustomKeyboardView mKeyboardView;
public EditText mTargetView;
public Android.InputMethodServices.Keyboard mKeyboard;
Activity activity;
global::Android.Views.View view;
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
try
{
SetupUserInterface();
SetupEventHandlers();
this.AddView(view);
}
catch (System.Exception ex)
{
System.Diagnostics.Debug.WriteLine(#" ERROR: ", ex.Message);
}
}
void SetupUserInterface()
{
activity = this.Context as Activity;
view = activity.LayoutInflater.Inflate(Resource.Layout.activity_keyboard, this, false);
mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard);
mTargetView = view.FindViewById<EditText>(Resource.Id.target);
mKeyboardView = view.FindViewById<CustomKeyboardView>(Resource.Id.keyboard_view);
mKeyboardView.Keyboard = mKeyboard;
}
void SetupEventHandlers()
{
mTargetView.Touch += (sender, e) =>
{
ShowKeyboardWithAnimation();
e.Handled = false;
mTargetView.ShowSoftInputOnFocus = false;
};
mKeyboardView.Key += async (sender, e) =>
{
long eventTime = JavaSystem.CurrentTimeMillis();
KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);
DispatchKeyEvent(ev);
await Task.Delay(1);
mTargetView.RequestFocus();
};
}
public void ShowKeyboardWithAnimation()
{
if (mKeyboardView.Visibility == ViewStates.Gone)
{
mKeyboardView.Visibility = ViewStates.Visible;
Android.Views.Animations.Animation animation = AnimationUtils.LoadAnimation(
Context,
Resource.Animation.slide_in_bottom
);
mKeyboardView.ShowWithAnimation(animation);
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);
view.Measure(msw, msh);
view.Layout(0, 0, r - l, b - t);
}
}
Effect:
.
I wrote up a simple demo about how to implement this feature, you can see it in this GitHub Repository.
I don't know Hebrew, if you need to achieve the effect like the picture you have post, you need custom the layout in keyboard.xml file.
Update :
I am done iOS portion using entry render so only try to do for android portion
I write a EntryRenderer to implement this feature, effect like this, hope this can help you.
public class MyEntry2Renderer : ViewRenderer<MyEntry, TextInputLayout>,
ITextWatcher,
TextView.IOnEditorActionListener
{
private bool _hasFocus;
public CustomKeyboardView mKeyboardView;
public Android.InputMethodServices.Keyboard mKeyboard;
ViewGroup activityRootView;
protected EditText EditText => Control.EditText;
public bool OnEditorAction(TextView v, ImeAction actionId, KeyEvent e)
{
if ((actionId == ImeAction.Done) || ((actionId == ImeAction.ImeNull) && (e.KeyCode == Keycode.Enter)))
{
Control.ClearFocus();
//HideKeyboard();
((IEntryController)Element).SendCompleted();
}
return true;
}
public virtual void AfterTextChanged(IEditable s)
{
}
public virtual void BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
}
public virtual void OnTextChanged(ICharSequence s, int start, int before, int count)
{
if (string.IsNullOrWhiteSpace(Element.Text) && (s.Length() == 0)) return;
((IElementController)Element).SetValueFromRenderer(Entry.TextProperty, s.ToString());
}
protected override TextInputLayout CreateNativeControl()
{
var textInputLayout = new TextInputLayout(Context);
var editText = new EditText(Context);
#region Add the custom Keyboard in your Page
var activity = Forms.Context as Activity;
var rootView = activity.Window.DecorView.FindViewById(Android.Resource.Id.Content);
activity.Window.SetSoftInputMode(SoftInput.StateAlwaysHidden);
activityRootView = ((ViewGroup)rootView).GetChildAt(0) as ViewGroup;
mKeyboardView = new CustomKeyboardView(Forms.Context, null);
Android.Widget.RelativeLayout.LayoutParams layoutParams =
new Android.Widget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent); // or wrap_content
layoutParams.AddRule(LayoutRules.AlignParentBottom);
activityRootView.AddView(mKeyboardView, layoutParams);
#endregion
//First open the current page, hide the Keyboard
mKeyboardView.Visibility = ViewStates.Gone;
//Use the custom Keyboard
mKeyboard = new Android.InputMethodServices.Keyboard(Context, Resource.Xml.keyboard2);
mKeyboardView.Keyboard = mKeyboard;
mKeyboardView.Key += async (sender, e) =>
{
long eventTime = JavaSystem.CurrentTimeMillis();
KeyEvent ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, e.PrimaryCode, 0, 0, 0, 0, KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);
DispatchKeyEvent(ev);
await Task.Delay(1);
};
textInputLayout.AddView(editText);
return textInputLayout;
}
protected override void OnElementChanged(ElementChangedEventArgs<MyEntry> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
if (Control != null)
EditText.FocusChange -= ControlOnFocusChange;
if (e.NewElement != null)
{
var ctrl = CreateNativeControl();
SetNativeControl(ctrl);
EditText.ShowSoftInputOnFocus = false;
EditText.FocusChange += ControlOnFocusChange;
}
}
private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
{
_hasFocus = args.HasFocus;
if (_hasFocus)
{
EditText.Post(() =>
{
EditText.RequestFocus();
ShowKeyboardWithAnimation();
});
}
else
{
//Hide the Keyboard
mKeyboardView.Visibility = ViewStates.Gone;
}
}
public void ShowKeyboardWithAnimation()
{
if (mKeyboardView.Visibility == ViewStates.Gone)
{
mKeyboardView.Visibility = ViewStates.Visible;
Android.Views.Animations.Animation animation = AnimationUtils.LoadAnimation(
Context,
Resource.Animation.slide_in_bottom
);
mKeyboardView.ShowWithAnimation(animation);
}
}
}

refresh adapter with recyclerview using D-pad holding focus

I am stuck on a complex situation, when I am refreshing my adapter of recyclerview by notifyDataSetChanged, while it having focus on particular cell (with D-PAD), is being loss. After refresh focus is not showing
private void refreshedData() {
flag1 = true;
// new MyAsycTas().execute();
focusedElement();
// select();
runnable = new Runnable() {
#Override
public void run() {
Log.e(TAG, "Data refreshed starrt.......");
// isRefreshedData = true;
fetchXmlFromUrl = new FetchDataFromUrl(Demo2Activity.this, 0, Demo2Activity.this);
handler.removeCallbacks(runnable);
select();
handler.postDelayed(runnable, 9000);
}
};
// handler.postDelayed(runnable,
// Integer.valueOf(MyStaticClass.refreshTime) * 60000);
handler.postDelayed(runnable, 9000);
}
...
public void select() {
if (verticalListView != null) {
View view = verticalListView.getChildAt(vertical_position);
if (view != null) {
view = verticalListView.getChildAt(vertical_position);
recyclerView = (RecyclerView) view.findViewById(R.id.horizontal_recyclerview);
if (recyclerView != null) {
verticalListView.scrollToPosition(vertical_position);
((View) recyclerView.getChildAt(horizontal_position)).findViewById(R.id.cat_button_thumabnail)
.requestFocus();
} else {
LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.home_fragment_menu_container);
linearLayout.getChildAt(horizontal_position).requestFocus();
}
}
}
// refreshedData();
}
..
public void focusedElement() {
if (verticalListView != null) {
View view = verticalListView.getLayoutManager().getFocusedChild();
if (view != null) {
recyclerView = (RecyclerView) view.findViewById(R.id.horizontal_recyclerview);
if (recyclerView != null) {
vertical_position = (Integer) recyclerView.getTag();
horizontal_position = recyclerView.getChildAdapterPosition(recyclerView.getFocusedChild());
} else {
LinearLayout ll = (LinearLayout) view.findViewById(R.id.home_fragment_menu_container);
horizontal_position = ll.indexOfChild(ll.getFocusedChild());
}
}
}
}

Moq VerifySet(Action) strange behaviour

I use Moq to test some behaviour. I want to verify set view's model property as new instance of Message class:
[TestFixture]
public class MessageFormPresenterTests
{
private NameValueCollection queryString;
private Mock<IDatabase> mockDatabase;
private Mock<HttpContextBase> mockHttpContext;
private Mock<HttpRequestBase> mockRequest;
private Mock<HttpResponseBase> mockResponce;
private Mock<IMessageFormView> mockView;
private MessageFormPresenter presenter;
[SetUp]
public void SetUp()
{
this.queryString = new NameValueCollection();
this.mockDatabase = new Mock<IDatabase>();
this.mockHttpContext = new Mock<HttpContextBase>();
this.mockRequest = new Mock<HttpRequestBase>();
this.mockResponce = new Mock<HttpResponseBase>();
this.mockView = new Mock<IMessageFormView>();
this.mockHttpContext.SetupGet(c => c.Request).Returns(this.mockRequest.Object);
this.mockHttpContext.SetupGet(c => c.Response).Returns(this.mockResponce.Object);
this.mockRequest.SetupGet(r => r.QueryString).Returns(this.queryString);
this.presenter = new MessageFormPresenter(this.mockView.Object) { Database = this.mockDatabase.Object, HttpContext = this.mockHttpContext.Object };
}
[Test]
public void ViewLoad_QueryStringNotHasMessageIdParameter_PopulateViewModelAsNewMessage()
{
// Act
this.mockView.Raise(v => v.Load += null, new EventArgs());
// Assert
this.mockView.VerifySet(v => v.Model = It.Is<Message>(m => m.Id == 0));
}
}
But this test pass even if i not write this functionality in my MessageFormPresenter. When i set breakpoint to action call (v.Model = It.Is(m => m.Id == 0)) and debug my test, Model property returned as "Castle.Proxies.MessageProxy" type and has all properties with default values (value of Id property is 0, of course).
Why is this happening? I don't setup anything to return and Moq should return null by default.
P.S. Excuse me for my poor english. I hope you understand what i'm talking about)
UPDATE1: MessageFormPresenter class:
public class MessageFormPresenter : Presenter<IMessageFormView>
{
private IDatabase database;
public MessageFormPresenter(IMessageFormView view)
: base(view)
{
View.Load += this.View_Load;
}
public IDatabase Database
{
get { return this.database ?? (this.database = DatabaseFactory.DatabaseInstance); }
set { this.database = value; }
}
private void View_Load(object sender, EventArgs e)
{
int messageId;
var messageParam = Request.QueryString[QueryParamNames.MessageId];
if (messageParam == null)
{
View.Model = new Message();
return;
}
if (!View.IsAdmin)
{
Response.Redirect(PageUrls.AccessDenied, true);
return;
}
if (int.TryParse(
messageParam,
NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite,
CultureInfo.InvariantCulture,
out messageId))
{
View.Model = this.Database.Single<Message>(messageId);
}
else
{
Response.Redirect(PageUrls.DefaultPage, true);
}
}
}
Base class Presenter<IMessageFormView> provided by WebFormsMvp framework.
UPDATE2: If i use strict behaviour TargetInvocationException will be thrown in base constructor of MessageFormPresenter, even if i setup all properties of Mock<IMessageFormView>.

Resources