I have designed a Custom Numerical Keyboard but It hides When I activate or use it on Popup Screen(used Rg.Plugin Popup). eg. Like thisImage describing when popup is above on the Keyboard / Popup hides the Keyboard
If I make this screen as the First Screen or If I make this into a Page/View, not the Popup. It looks like this eg., Image above the Page
This is the code I have written -
1- Custom Keyboard (Xamarin forms Custom Renderer)
public class EntryWithCustomKeyboard : Entry
{
public static readonly BindableProperty EnterCommandProperty = BindableProperty.Create(
nameof(EnterCommand),
typeof(ICommand),
typeof(EntryWithCustomKeyboard),
default(ICommand),
BindingMode.OneWay
);
public ICommand EnterCommand
{
get => (ICommand)GetValue(EnterCommandProperty);
set => SetValue(EnterCommandProperty, value);
}
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create(nameof(BorderColor),
typeof(Color), typeof(CustomEntry), Color.Gray);
// Gets or sets BorderColor value
public Color BorderColor
{
get => (Color)GetValue(BorderColorProperty);
set => SetValue(BorderColorProperty, value);
}
public static readonly BindableProperty BorderWidthProperty =
BindableProperty.Create(nameof(BorderWidth), typeof(int),
typeof(CustomEntry), Device.OnPlatform<int>(1, 2, 2));
// Gets or sets BorderWidth value
public int BorderWidth
{
get => (int)GetValue(BorderWidthProperty);
set => SetValue(BorderWidthProperty, value);
}
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create(nameof(CornerRadius),
typeof(double), typeof(CustomEntry), Device.OnPlatform<double>(6, 7, 7));
// Gets or sets CornerRadius value
public double CornerRadius
{
get => (double)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
public static readonly BindableProperty IsCurvedCornersEnabledProperty =
BindableProperty.Create(nameof(IsCurvedCornersEnabled),
typeof(bool), typeof(CustomEntry), true);
// Gets or sets IsCurvedCornersEnabled value
public bool IsCurvedCornersEnabled
{
get => (bool)GetValue(IsCurvedCornersEnabledProperty);
set => SetValue(IsCurvedCornersEnabledProperty, value);
}
}
2- Android Renderer for Custom Keyboard
public class EntryWithCustomKeyboardRenderer : EntryRenderer, IOnKeyboardActionListener
{
PopupWindow popup;
private Context context;
private EntryWithCustomKeyboard entryWithCustomKeyboard;
private Android.InputMethodServices.KeyboardView mKeyboardView;
private Android.InputMethodServices.Keyboard mKeyboard;
private InputTypes inputTypeToUse;
private bool keyPressed;
public EntryWithCustomKeyboardRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var newCustomEntryKeyboard = e.NewElement as EntryWithCustomKeyboard;
var oldCustomEntryKeyboard = e.OldElement as EntryWithCustomKeyboard;
if (newCustomEntryKeyboard == null && oldCustomEntryKeyboard == null)
return;
if (e.NewElement != null)
{
this.entryWithCustomKeyboard = newCustomEntryKeyboard;
this.CreateCustomKeyboard();
this.inputTypeToUse = this.entryWithCustomKeyboard.Keyboard.ToInputType() | InputTypes.TextFlagNoSuggestions;
// Here we set the EditText event handlers
this.EditText.FocusChange += Control_FocusChange;
this.EditText.TextChanged += EditText_TextChanged;
this.EditText.Click += EditText_Click;
this.EditText.Touch += EditText_Touch;
#region BorderEntry
var view = (EntryWithCustomKeyboard)Element;
if (view.IsCurvedCornersEnabled)
{
// creating gradient drawable for the curved background
var _gradientBackground = new GradientDrawable();
_gradientBackground.SetShape(ShapeType.Rectangle);
_gradientBackground.SetColor(view.BackgroundColor.ToAndroid());
// Thickness of the stroke line
_gradientBackground.SetStroke(view.BorderWidth, view.BorderColor.ToAndroid());
// Radius for the curves
_gradientBackground.SetCornerRadius(
DpToPixels(this.Context, Convert.ToSingle(view.CornerRadius)));
// set the background of the
Control.SetBackground(_gradientBackground);
}
// Set padding for the internal text from border
Control.SetPadding(
(int)DpToPixels(this.Context, Convert.ToSingle(12)), Control.PaddingTop,
(int)DpToPixels(this.Context, Convert.ToSingle(12)), Control.PaddingBottom);
#endregion
}
// Dispose control
if (e.OldElement != null)
{
this.EditText.FocusChange -= Control_FocusChange;
this.EditText.TextChanged -= EditText_TextChanged;
this.EditText.Click -= EditText_Click;
this.EditText.Touch -= EditText_Touch;
}
}
public static float DpToPixels(Context context, float valueInDp)
{
DisplayMetrics metrics = context.Resources.DisplayMetrics;
return TypedValue.ApplyDimension(ComplexUnitType.Dip, valueInDp, metrics);
}
protected override void OnFocusChangeRequested(object sender, VisualElement.FocusRequestArgs e)
{
e.Result = true;
if (e.Focus)
this.Control.RequestFocus();
else
this.Control.ClearFocus();
}
#region EditText event handlers
private void Control_FocusChange(object sender, FocusChangeEventArgs e)
{
// Workaround to avoid null reference exceptions in runtime
if (this.EditText.Text == null)
this.EditText.Text = string.Empty;
if (e.HasFocus)
{
this.mKeyboardView.OnKeyboardActionListener = this;
if (this.Element.Keyboard == Keyboard.Numeric)
this.CreateCustomKeyboard();
this.ShowKeyboardWithAnimation();
}
else
{
// When the control looses focus, we set an empty listener to avoid crashes
this.mKeyboardView.OnKeyboardActionListener = new NullListener();
this.HideKeyboardView();
}
}
private void EditText_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
// Ensure no key is pressed to clear focus
if (this.EditText.Text.Length != 0 && !this.keyPressed)
{
this.EditText.ClearFocus();
return;
}
}
private void EditText_Click(object sender, System.EventArgs e)
{
ShowKeyboardWithAnimation();
}
private void EditText_Touch(object sender, TouchEventArgs e)
{
this.EditText.InputType = InputTypes.Null;
this.EditText.OnTouchEvent(e.Event);
this.EditText.InputType = this.inputTypeToUse;
e.Handled = true;
}
#endregion
#region keyboard related
private void CreateCustomKeyboard()
{
var context = CrossCurrentActivity.Current.Activity;
var activity = context;
var rootView = activity.Window.DecorView.FindViewById(Android.Resource.Id.Content);
activity.Window.SetSoftInputMode(SoftInput.StateVisible);
var activityRootView = (ViewGroup)((ViewGroup)rootView).GetChildAt(0);
this.mKeyboardView = activityRootView.FindViewById<Android.InputMethodServices.KeyboardView>(Resource.Id.customKeyboard);
// If the previous line fails, it means the keyboard needs to be created and added
if (this.mKeyboardView == null)
{
this.mKeyboardView = (Android.InputMethodServices.KeyboardView)activity.LayoutInflater.Inflate(Resource.Layout.CustomKeyboard, null);
this.mKeyboardView.Id = Resource.Id.customKeyboard;
this.mKeyboardView.Focusable = true;
this.mKeyboardView.FocusableInTouchMode = true;
this.mKeyboardView.Release += (sender, e) => { };
var layoutParams = new Android.Widget.RelativeLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
layoutParams.AddRule(LayoutRules.AlignParentBottom);
activityRootView.AddView(this.mKeyboardView, layoutParams);
}
this.HideKeyboardView();
this.mKeyboard = new Android.InputMethodServices.Keyboard(this.context, Resource.Xml.special_keyboard);
this.SetCurrentKeyboard();
}
private void SetCurrentKeyboard()
{
this.mKeyboardView.Keyboard = this.mKeyboard;
}
// Method to show our custom keyboard
private void ShowKeyboardWithAnimation()
{
// First we must ensure that custom keyboard is hidden to
// prevent showing it multiple times
if (this.mKeyboardView.Visibility == ViewStates.Gone)
{
// Ensure native keyboard is hidden
var imm = (InputMethodManager)this.context.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(this.EditText.WindowToken, 0);
this.EditText.InputType = InputTypes.Null;
var animation = AnimationUtils.LoadAnimation(this.context, Resource.Animation.slide_in_bottom);
this.mKeyboardView.Animation = animation;
this.mKeyboardView.Enabled = true;
// Show custom keyboard with animation
this.mKeyboardView.Visibility = ViewStates.Visible;
}
}
// Method to hide our custom keyboard
private void HideKeyboardView()
{
this.mKeyboardView.Visibility = ViewStates.Gone;
this.mKeyboardView.Enabled = false;
this.EditText.InputType = InputTypes.Null;
}
#endregion
#region IOnKeyboardActionListener
// Implementing IOnKeyboardActionListener interface
public void OnKey([GeneratedEnum] Keycode primaryCode, [GeneratedEnum] Keycode[] keyCodes)
{
if (!this.EditText.IsFocused)
return;
// Ensure key is pressed to avoid removing focus
this.keyPressed = true;
// Create event for key press
long eventTime = JavaSystem.CurrentTimeMillis();
var ev = new KeyEvent(eventTime, eventTime, KeyEventActions.Down, primaryCode, 0, 0, 0, 0,
KeyEventFlags.SoftKeyboard | KeyEventFlags.KeepTouchMode);
// Ensure native keyboard is hidden
var imm = (InputMethodManager)this.context.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(this.EditText.WindowToken, HideSoftInputFlags.None);
this.EditText.InputType = this.inputTypeToUse;
const Keycode na = (Keycode)1000;
const Keycode done = (Keycode)400;
switch (ev.KeyCode)
{
case Keycode.Enter:
// Sometimes EditText takes long to update the HasFocus status
if (this.EditText.HasFocus)
{
// Close the keyboard, remove focus and launch command asociated action
this.HideKeyboardView();
this.ClearFocus();
this.entryWithCustomKeyboard.EnterCommand?.Execute(null);
}
break;
case Keycode.NumpadDot:
if (!string.IsNullOrEmpty(EditText.Text))
EditText.Text += ".";
else
EditText.Text = ".";
break;
case na:
EditText.Text = "N/A";
break;
case done:
this.HideKeyboardView();
this.ClearFocus();
break;
case Keycode.Del:
this.OnKeyLongPress(Keycode.Del, ev);
break;
}
// Set the cursor at the end of the text
this.EditText.SetSelection(this.EditText.Text.Length);
if (this.EditText.HasFocus)
{
this.DispatchKeyEvent(ev);
this.keyPressed = false;
}
}
public void OnPress([GeneratedEnum] Keycode primaryCode)
{
}
public void OnRelease([GeneratedEnum] Keycode primaryCode)
{
}
public void OnText(ICharSequence text)
{
}
public void SwipeDown()
{
}
public void SwipeLeft()
{
}
public void SwipeRight()
{
}
public void SwipeUp()
{
}
#endregion
private class NullListener : Java.Lang.Object, IOnKeyboardActionListener
{
public void OnKey([GeneratedEnum] Keycode primaryCode, [GeneratedEnum] Keycode[] keyCodes)
{
}
public void OnPress([GeneratedEnum] Keycode primaryCode)
{
}
public void OnRelease([GeneratedEnum] Keycode primaryCode)
{
}
public void OnText(ICharSequence text)
{
}
public void SwipeDown()
{
}
public void SwipeLeft()
{
}
public void SwipeRight()
{
}
public void SwipeUp()
{
}
}
}
3- Layout For Keyboard-
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard"
android:foregroundGravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:keyPreviewLayout="@null"
android:keyBackground="@drawable/keyboard_background"
android:textColor="@android:color/white"
android:background="#E0E0E0" />
4- On XML folder for Designing Keys -
<?xml version="1.0" encoding="utf-8" ?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="8%p"
android:keyHeight="50dp"
android:horizontalGap="1%p"
android:verticalGap="1%p">
<Row android:keyHeight="4dp" android:rowEdgeFlags="top" android:verticalGap="1%p">
<Key android:codes="0" android:keyWidth="100%p" android:keyIcon="@drawable/kb_separator_line" />
</Row>
<Row >
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="left" />
<Key android:codes="8" android:keyLabel="1" android:keyWidth="18%p" />
<Key android:codes="9" android:keyLabel="2" android:keyWidth="18%p" />
<Key android:codes="10" android:keyLabel="3" android:keyWidth="18%p" />
<Key android:codes="11" android:keyLabel="4" android:keyWidth="18%p" />
<Key android:codes="12" android:keyLabel="5" android:keyWidth="18%p" />
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="right" />
</Row>
<Row>
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="left" />
<Key android:codes="13" android:keyLabel="6" android:keyWidth="18%p" />
<Key android:codes="14" android:keyLabel="7" android:keyWidth="18%p" />
<Key android:codes="15" android:keyLabel="8" android:keyWidth="18%p" />
<Key android:codes="16" android:keyLabel="9" android:keyWidth="18%p" />
<Key android:codes="7" android:keyLabel="0" android:keyWidth="18%p" />
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="right" />
</Row>
<Row>
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="left" />
<Key android:codes="1000" android:keyLabel="N/A" android:keyWidth="18%p" />
<Key android:codes="67" android:keyWidth="18%p" android:isRepeatable="true"
android:iconPreview="@drawable/sym_keyboard_delete" android:keyIcon="@drawable/sym_keyboard_delete"/>
<Key android:codes="400" android:keyLabel="DONE" android:keyWidth="18%p" android:keyEdgeFlags="right"/>
<Key android:codes="69" android:keyLabel="-" android:keyWidth="18%p" />
<Key android:codes="158" android:keyLabel="." android:keyWidth="18%p" />
<Key android:codes="0" android:keyWidth="0dp" android:horizontalGap="2%p" android:keyEdgeFlags="right" />
</Row>
</Keyboard>
5- Drawable Folder for Backgrounds -
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="false"
android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/normal" />
<item
android:state_pressed="true"
android:drawable="@drawable/pressed" />
</selector>
a) For Normal State -
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="2dp" android:right="2dp">
<shape android:shape="rectangle">
<solid android:color="#E0E0E0" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#383838" />
</shape>
</item>
</layer-list>
b) For Pressed -
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FAFAFA" />
</shape>
6- Animation -
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="150%p" android:toYDelta="0" android:duration="200"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="200" />
</set>
So, this is the whole code I have done for Custom Keyboard but it's not working as qit should be. Any help will be Ok. I am stuck in this for a long time please help.