Xamarin Forms: Keyboard didn't hide - xamarin

The keyboard hides when I create the page, but when I change the focus to another entry I call the same function but the soft keyboard didn't hide?
ConfigService.cs
public void HideKeyboard()
{
var inputMethodManager = Xamarin.Forms.Forms.Context.GetSystemService(Context.InputMethodService) as InputMethodManager;
if (inputMethodManager != null && Xamarin.Forms.Forms.Context is Activity)
{
var activity = Xamarin.Forms.Forms.Context as Activity;
var focusedView = activity.CurrentFocus;
var token = focusedView == null ? null : focusedView.WindowToken;
inputMethodManager.HideSoftInputFromWindow(token, HideSoftInputFlags.None);
}
}
VerplaatsingPage.xaml.cs
namespace SI_Foodware.View
{
public partial class VerplaatsingPage : ContentPage
{
VerplaatsingPageViewModel vm;
public VerplaatsingPage (SubMenu subMenu)
{
InitializeComponent ();
vm = new VerplaatsingPageViewModel(this, subMenu);
BindingContext = vm;
}
public void OnClickDestination(object o, EventArgs e)
{
}
public void OnClickSelect(object o, EventArgs e)
{
}
public void OnClickCancel(object o, EventArgs e)
{
}
protected override void OnAppearing()
{
base.OnAppearing();
ent_drager.Focus();
IConfigService configService = DependencyService.Get<IConfigService>();
configService.HideKeyboard();
}
}
}
VerplaatsingPageViewModel.cs
public void Keyboard()
{
IConfigService configService = DependencyService.Get<IConfigService>();
configService.HideKeyboard();
}
public void OnScan(string scanProperty)
{
var list = db.GetAllItems<ContainerLine>();
Artikel = list[0].ItemNo;
Description = list[0].Description;
LotNo = list[0].LotNo;
NumberOfContainer = list[0].Quantity;
KiloDrager = list[0].KgQuantity;
UnitOfMeasure = list[0].UnitofMeasureCode;
LocationFrom = list[0].BinCode;
cp.FindByName<Entry>("ent_destination").Focus();
Keyboard(); <-- Doesn't Work
}

I solved my problem by using
inputMethodManager.ToggleSoftInputFromWindow(token, ShowSoftInputFlags.None, HideSoftInputFlags.None);
instead of
inputMethodManager.HideSoftInputFromWindow(token, HideSoftInputFlags.None);

Related

Remove Placeholder from TextInputLayout in Xamarin Forms for Android & IOS

I am trying to create Suggestion Searchbar using Entry
i was able to create the suggestion searchbar but i am not able to change the look of this Entry, i want to remove the tooltip above (Search by Speciality..) and just want it to look like other entry in the app
could anyone help me what and where i had to make change for getting that look
here is my code
Xamarin Android :
[assembly: ExportRenderer(typeof(AutoCompleteViewv2),
typeof(AutoCompleteViewRendererv2))]
namespace App.Droid.Renderers.RevisedRenderer
{
public class AutoCompleteViewRendererv2 :
FormsAppCompat.ViewRenderer<AutoCompleteViewv2, TextInputLayout>
{
public AutoCompleteViewRendererv2(Context context) : base(context)
{
}
private AppCompatAutoCompleteTextView NativeControl => Control?.EditText
as AppCompatAutoCompleteTextView;
protected override TextInputLayout CreateNativeControl()
{
var textInputLayout = new TextInputLayout(Context);
var autoComplete = new AppCompatAutoCompleteTextView(Context)
{
BackgroundTintList = ColorStateList.ValueOf(GetPlaceholderColor()),
Text = Element?.Text,
Hint = Element?.Placeholder,
};
GradientDrawable gd = new GradientDrawable();
gd.SetColor(global::Android.Graphics.Color.Transparent);
autoComplete.SetBackground(gd);
if (Element != null)
{
autoComplete.SetHintTextColor(Element.PlaceholderColor.ToAndroid());
autoComplete.SetTextColor(Element.TextColor.ToAndroid());
}
textInputLayout.AddView(autoComplete);
return textInputLayout;
}
protected override void OnElementChanged(ElementChangedEventArgs<AutoCompleteViewv2> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// unsubscribe
NativeControl.ItemClick -= AutoCompleteOnItemSelected;
var elm = e.OldElement;
elm.CollectionChanged -= ItemsSourceCollectionChanged;
}
if (e.NewElement != null)
{
SetNativeControl(CreateNativeControl());
// subscribe
SetItemsSource();
SetThreshold();
KillPassword();
NativeControl.TextChanged += (s, args) => Element.RaiseTextChanged(NativeControl.Text);
NativeControl.ItemClick += AutoCompleteOnItemSelected;
var elm = e.NewElement;
elm.CollectionChanged += ItemsSourceCollectionChanged;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
KillPassword();
if (e.PropertyName == AutoCompleteViewv2.ItemsSourceProperty.PropertyName)
SetItemsSource();
else if (e.PropertyName == AutoCompleteViewv2.ThresholdProperty.PropertyName)
SetThreshold();
}
private void AutoCompleteOnItemSelected(object sender, AdapterView.ItemClickEventArgs args)
{
var view = (AutoCompleteTextView)sender;
var selectedItemArgs = new SelectedItemChangedEventArgs(view.Text);
var element = (AutoCompleteViewv2)Element;
element.OnItemSelectedInternal(Element, selectedItemArgs);
}
private void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
var element = (AutoCompleteViewv2)Element;
ResetAdapter(element);
}
private void KillPassword()
{
if (Element.IsPassword)
throw new NotImplementedException("Cannot set IsPassword on a AutoComplete");
}
private void ResetAdapter(AutoCompleteViewv2 element)
{
var adapter = new BoxArrayAdapter(Context,
Android.Resource.Layout.SimpleDropDownItem1Line,
element.ItemsSource.ToList(),
element.SortingAlgorithm);
NativeControl.Adapter = adapter;
adapter.NotifyDataSetChanged();
}
private void SetItemsSource()
{
var element = (AutoCompleteViewv2)Element;
if (element.ItemsSource == null) return;
ResetAdapter(element);
}
private void SetThreshold()
{
var element = (AutoCompleteViewv2)Element;
NativeControl.Threshold = element.Threshold;
}
#region Section 2
protected AColor GetPlaceholderColor() => Element.PlaceholderColor.ToAndroid(Color.FromHex("#80000000"));
#endregion
}
internal class BoxArrayAdapter : ArrayAdapter
{
private readonly IList<string> _objects;
private readonly Func<string, ICollection<string>, ICollection<string>> _sortingAlgorithm;
public BoxArrayAdapter(
Context context,
int textViewResourceId,
List<string> objects,
Func<string, ICollection<string>, ICollection<string>> sortingAlgorithm) : base(context, textViewResourceId, objects)
{
_objects = objects;
_sortingAlgorithm = sortingAlgorithm;
}
public override Filter Filter
{
get
{
return new CustomFilter(_sortingAlgorithm) { Adapter = this, Originals = _objects };
}
}
}
internal class CustomFilter : Filter
{
private readonly Func<string, ICollection<string>, ICollection<string>> _sortingAlgorithm;
public CustomFilter(Func<string, ICollection<string>, ICollection<string>> sortingAlgorithm)
{
_sortingAlgorithm = sortingAlgorithm;
}
public BoxArrayAdapter Adapter { private get; set; }
public IList<string> Originals { get; set; }
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var results = new FilterResults();
if (constraint == null || constraint.Length() == 0)
{
results.Values = new Java.Util.ArrayList(Originals.ToList());
results.Count = Originals.Count;
}
else
{
var values = new Java.Util.ArrayList();
var sorted = _sortingAlgorithm(constraint.ToString(), Originals).ToList();
for (var index = 0; index < sorted.Count; index++)
{
var item = sorted[index];
values.Add(item);
}
results.Values = values;
results.Count = sorted.Count;
}
return results;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
if (results.Count == 0)
Adapter.NotifyDataSetInvalidated();
else
{
Adapter.Clear();
var vals = (Java.Util.ArrayList)results.Values;
foreach (var val in vals.ToArray())
{
Adapter.Add(val);
}
Adapter.NotifyDataSetChanged();
}
}
}
}
how can i get rid of that tooltip or placeholder and make the text in middle

How to pass json data in xamarin forms web view android side

I am using xamarin forms webview and want to pass username and password json body with url like below.
I Implement Hybrid webview in xamarin forms
My PCL Code:
public class HybridWebView : WebView
{
Action<string> action;
public EventHandler<bool> WebNavigating;
public void RegisterAction (Action<string> callback)
{
action = callback;
}
public void Cleanup ()
{
action = null;
}
public void InvokeAction (string data)
{
if (action == null || string.IsNullOrEmpty(data)) {
return;
}
action.Invoke (data);
}
}
My Android HybridWebViewRenderer Code :
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new MyWebViewClient(webView,e,this));
SetNativeControl(webView);
}
}
}
public class MyWebViewClient : WebViewClient
{
const string JavaScriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
public Android.Webkit.WebView _webView;
public Android.Webkit.WebView WebView
{
get
{
return _webView;
}
}
public ElementChangedEventArgs<HybridWebView> _element;
public MyWebViewClient(Android.Webkit.WebView view, ElementChangedEventArgs<HybridWebView> element, HybridWebViewRenderer x)
{
_webView = view;
_element = element;
if (_element.OldElement != null)
{
_webView.RemoveJavascriptInterface("jsBridge");
var hybridWebView = _element.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (_element.NewElement != null)
{
_webView.AddJavascriptInterface(new JSBridge(x), "jsBridge");
string url = "https://Myspecific.com/Account/MobileLogin";
string postData = "{\"UserName\":\"User1\",\"Password\":\"pass123\",\"RememberMe\":false}";
_webView.PostUrl(url, Encoding.UTF8.GetBytes(postData));
}
}
output:
It shows wrong username and password
Please help...
Thanks in advance...

Xamarin.Forms Webview OnDetachedFromWindow crashed

When open renderer page many times, when back to last page, it crashed and log this exception:
System.NotSupportedException: Unable to activate instance of type
AppZPMC.Droid.Renderers.CustomVideoWebViewRenderer from native handle
0xff9919cc (key_handle 0xf2ff0de).
Here is my code:
public class CustomVideoWebViewRenderer : WebViewRenderer
{
string url;
Activity activity;
WebView webView;
View customView;
CustomVideoWebView element;
FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
FrameLayout fullscreenContainer;
WebChromeClient.ICustomViewCallback customViewCallback;
public CustomVideoWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
webView = this.Control;
activity = CrossCurrentActivity.Current.Activity;
if (e.NewElement != null)
{
element = e.NewElement as CustomVideoWebView;
url = element.VideoUrl;
}
if (webView != null)
{
InitWebView();
}
}
protected override void OnDetachedFromWindow()
{
if (Element == null)
{
return;
}
base.OnDetachedFromWindow();
if (Control != null)
{
Control.StopLoading();
Control.LoadUrl("");
Control.Reload();
Control.Destroy();
}
}
public void FullScreen(Activity pActivity)
{
element.IsFullScreen = true;
WindowManagerLayoutParams attrs = pActivity.Window.Attributes;
attrs.Flags |= WindowManagerFlags.Fullscreen;
attrs.Flags |= WindowManagerFlags.KeepScreenOn;
pActivity.Window.Attributes = attrs;
pActivity.RequestedOrientation = Android.Content.PM.ScreenOrientation.Landscape;
}
public void SmallScreen(Activity pActivity)
{
element.IsFullScreen = false;
WindowManagerLayoutParams attrs = pActivity.Window.Attributes;
attrs.Flags &= ~WindowManagerFlags.Fullscreen;
attrs.Flags &= ~WindowManagerFlags.KeepScreenOn;
pActivity.Window.Attributes = attrs;
pActivity.RequestedOrientation = Android.Content.PM.ScreenOrientation.UserPortrait;
}
private void InitWebView()
{
WebChromeClient wvcc = new WebChromeClient();
WebSettings webSettings = webView.Settings;
webSettings.JavaScriptEnabled = true;
webSettings.SetSupportZoom(false);
webSettings.CacheMode = CacheModes.NoCache;
webView.SetWebViewClient(new VideoWebViewClient());
FrameLayout frameLayout = new FrameLayout(activity.ApplicationContext);
frameLayout.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
webView.SetWebChromeClient(new VideoWebChromeClient(frameLayout, ShowCustomView, HideCustomView));
webView.LoadUrl(url);
}
private class VideoWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
view.LoadUrl(request.Url.ToString());
return base.ShouldOverrideUrlLoading(view, request);
}
}
private class VideoWebChromeClient : WebChromeClient
{
FrameLayout frameLayout;
Action HideCustomView;
Action<View, ICustomViewCallback> ShowCustomView;
public VideoWebChromeClient(FrameLayout frameLayout, Action<View, ICustomViewCallback> showCustomView, Action hideCustomView)
{
this.frameLayout = frameLayout;
ShowCustomView = showCustomView;
HideCustomView = hideCustomView;
}
public override View VideoLoadingProgressView => frameLayout;
public override void OnShowCustomView(View view, ICustomViewCallback callback)
{
ShowCustomView(view, callback);
base.OnShowCustomView(view, callback);
}
public override void OnHideCustomView()
{
HideCustomView();
base.OnHideCustomView();
}
}
private void ShowCustomView(View view, WebChromeClient.ICustomViewCallback callback)
{
if (customView != null)
{
callback.OnCustomViewHidden();
return;
}
FrameLayout decor = (FrameLayout)activity.Window.DecorView;
fullscreenContainer = new FullscreenHolder(activity.ApplicationContext);
fullscreenContainer.AddView(view, COVER_SCREEN_PARAMS);
decor.AddView(fullscreenContainer, COVER_SCREEN_PARAMS);
customView = view;
customViewCallback = callback;
FullScreen(activity);
}
private void HideCustomView()
{
if (customView == null)
{
return;
}
FrameLayout decor = (FrameLayout)activity.Window.DecorView;
decor.RemoveView(fullscreenContainer);
fullscreenContainer = null;
customView = null;
customViewCallback.OnCustomViewHidden();
webView.Visibility = ViewStates.Visible;
SmallScreen(activity);
}
private class FullscreenHolder : FrameLayout
{
public FullscreenHolder(Context ctx) : base(ctx)
{
SetBackgroundColor(Color.Black);
}
public override bool OnTouchEvent(MotionEvent e)
{
return true;
}
}
}
This is full crash log:
Java.Lang.Error: Exception of type 'Java.Lang.Error' was thrown.
java.lang.Error: Java callstack:
md5ff1c77b81adfd2c553f48967fc623ae5.CustomVideoWebViewRenderer.n_onDetachedFromWindow(Native Method)
md5ff1c77b81adfd2c553f48967fc623ae5.CustomVideoWebViewRenderer.onDetachedFromWindow(CustomVideoWebViewRenderer.java:45)
android.view.View.dispatchDetachedFromWindow(View.java:14595)
android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3074)
android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:4792)
android.view.ViewGroup.removeAllViews(ViewGroup.java:4738)
md5270abb39e60627f0f200893b490a1ade.FragmentContainer.n_onDestroyView(Native Method)
md5270abb39e60627f0f200893b490a1ade.FragmentContainer.onDestroyView(FragmentContainer.java:59)
android.support.v4.app.Fragment.performDestroyView(Fragment.java:2480)
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1569)
android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:753)
android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2415)
android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2201)
android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2155)
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2064)
android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:718)
android.os.Handler.handleCallback(Handler.java:742)
android.os.Handler.dispatchMessage(Handler.java:95)
android.os.Looper.loop(Looper.java:157)
android.app.ActivityThread.main(ActivityThread.java:5551)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:742)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632)
Its common problem (bug) in Xamarin.Forms, take a look at: https://github.com/xamarin/Xamarin.Forms/issues/1646, no fix yet :(

Xamarin.Android ButtonRenderer longclick and touch

I'm trying to implement the functionality of the android button through a ButtonRender. The problem occurs when I try to join ".LongClick" and ".touch", since it does not launch the long click event.
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
this.SetBackgroundResource(Resource.Drawable.button);
base.OnElementChanged(e);
Android.Widget.Button thisButton = Control as Android.Widget.Button;
thisButton.LongClickable = true;
thisButton.LongClick += delegate
{
string s = "";
};
thisButton.Touch += (object sender, Android.Views.View.TouchEventArgs e2) =>
{
if (e2.Event.Action == MotionEventActions.Down)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.Up)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.HoverExit || e2.Event.Action == MotionEventActions.Cancel)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.Move)
{
.
.
.
}
};
}
To invoke the event of native control, we need to create event handlers in our custom control, and together an interface which inherits from IViewController in order to set values from renderers.
Here is my demo, first of all, create a custom button:
public class MyButton : Xamarin.Forms.Button, IMyButtonController
{
public event EventHandler Touched;
void IMyButtonController.SendTouched()
{
Touched?.Invoke(this, EventArgs.Empty);
}
public event EventHandler LongClicked;
void IMyButtonController.SendLongClicked()
{
LongClicked?.Invoke(this, EventArgs.Empty);
}
public event EventHandler Released;
void IMyButtonController.SendReleased()
{
Released?.Invoke(this, EventArgs.Empty);
}
}
The IMyButtonController inherits from IViewController like this:
public interface IMyButtonController : IViewController
{
void SendTouched();
void SendLongClicked();
void SendReleased();
}
Then in android project, implement the ButtonRenderer and IMyButtonController like this:
[assembly: ExportRenderer(typeof(MyButton), typeof(MyButtonRenderer))]
namespace ProjectNameSpace.Droid
{
public class MyButtonRenderer : Xamarin.Forms.Platform.Android.ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
if (Control != null)
{
Control.SetOnTouchListener(ButtonTouchListener.Instance.Value);
Control.LongClickable = true;
Control.SetOnLongClickListener(ButtonLongClickListener.Instance.Value);
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (Control != null)
{
Control.SetOnTouchListener(null);
Control.SetOnLongClickListener(null);
}
}
base.Dispose(disposing);
}
private class ButtonTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
{
public static readonly Lazy<ButtonTouchListener> Instance = new Lazy<ButtonTouchListener>(() => new ButtonTouchListener());
public bool OnTouch(Android.Views.View v, Android.Views.MotionEvent e)
{
var renderer = v.Tag as ButtonRenderer;
if (renderer != null)
{
var buttonController = renderer.Element as IMyButtonController;
if (e.Action == Android.Views.MotionEventActions.Down)
{
buttonController?.SendTouched();
}
else if (e.Action == Android.Views.MotionEventActions.Up)
{
buttonController?.SendReleased();
}
}
return false;
}
}
private class ButtonLongClickListener : Java.Lang.Object, Android.Views.View.IOnLongClickListener
{
public static readonly Lazy<ButtonLongClickListener> Instance = new Lazy<ButtonLongClickListener>(() => new ButtonLongClickListener());
public bool OnLongClick(Android.Views.View v)
{
var renderer = v.Tag as ButtonRenderer;
((IMyButtonController)renderer?.Element)?.SendLongClicked();
return true;
}
}
}
}

Xamarin forms navigation BarBackgroundColor issue

When I click on Login for the first time than the barbackground of mainpage becomes the right color, but when I logout and than login again the color of the barbackground doesn't change??
LoginPage (View)
public partial class LoginPage : ContentPage
{
LoginPageViewModel vm;
public LoginPage ()
{
vm = new LoginPageViewModel ();
BindingContext = vm;
InitializeComponent ();
}
public void OnClickLogin(object o, EventArgs e)
{
vm.Login ();
}
public void OnClickPasswoordVergeten(object o, EventArgs e)
{
vm.PasswoordVergeten ();
}
public void OnClickContactUs(object o, EventArgs e)
{
vm.ContactUs ();
}
}
LoginPageViewModel (ViewModel)
public class LoginPageViewModel: INotifyPropertyChanged
{
public LoginPageViewModel ()
{
}
public void Login()
{
App.Current.MainPage = new Dharma.MainPage();
}
}
MainPage (View)
public partial class MainPage : MasterDetailPage
{
public MainPage ()
{
InitializeComponent ();
masterPage.ListView.ItemSelected += OnItemSelected;
var page = new NavigationPage (new ListPage());
page.BarBackgroundColor = Color.FromRgb(26,179,148);
Detail = page;
masterPage.ListView.SelectedItem = null;
IsPresented = false;
}
void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MasterPageItem;
if (item != null) {
var page = new NavigationPage ((Page)Activator.CreateInstance (item.TargetType));
page.BarBackgroundColor = Color.FromRgb(26,179,148);
Detail = page;
masterPage.ListView.SelectedItem = null;
IsPresented = false;
}
}
}
Set the color to your master page.
public void Login()
{
var mainPage = new Dharma.MainPage();
mainPage.BarBackgroundColor = Color.FromRgb(26,179,148);
App.Current.MainPage = mainPage ;
}

Resources