Secondary Toolbar items not fitting the screen - xamarin.forms

I have a Xamarin.Forms app with FreshMvvm, and I use secondary ToolbarItems. To do it in iOS, I had to make a custom renderer (unlike in Android). I was given a solution on how to implement it here:
ToolbarItems do not look right in iOS
This solution works perfectly for me. But by now, the toolbar menu grew longer, and some of its elements do not fit the iPhone's screen. I can slide the menu and see all the elements, but as soon as I release the screen, the view jumps back up, and while it is held by a finger, the elements are not clickable. How can this be solved? Can the menu made to wrap, or something else?
On Android, the menu stays where I scroll and I can click every item. Can it made stay where scrolled on iOS, too?
Here is my renderer's code:
using CoreGraphics;
using MobileApp.iOS.Renderers;
using MobileApp.iOS.Services;
using MobileApp.Pages;
using MobileApp.Services;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CustomToolbarContentPage),
typeof(RightToolbarMenuCustomRenderer))]
namespace MobileApp.iOS.Renderers
{
class RightToolbarMenuCustomRenderer : PageRenderer
{
private List<ToolbarItem> _primaryItems;
private List<ToolbarItem> _secondaryItems;
private UITableView _table;
private UITapGestureRecognizer _tapGestureRecognizer;
private UIView _transparentView;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
if (e.NewElement is IAddToolbarItem item)
{
item.ToolbarItemAdded += Item_ToolbarItemAdded;
}
base.OnElementChanged(e);
}
private void Item_ToolbarItemAdded(object sender, System.EventArgs e)
{
if (Element is ContentPage page)
{
_primaryItems = page.ToolbarItems.Where(i => i.Order == ToolbarItemOrder.Primary).ToList();
_secondaryItems = page.ToolbarItems.Where(i => i.Order == ToolbarItemOrder.Secondary).ToList();
_secondaryItems.ForEach(t => page.ToolbarItems.Remove(t));
}
var element = (ContentPage)Element;
if (_secondaryItems?.Count == 0 && element.ToolbarItems.Any(a => (a.IconImageSource as FileImageSource)?.File == "more.png"))
{
element.ToolbarItems.Clear();
}
else if (_secondaryItems?.Count >= 1 && !element.ToolbarItems.Any(a => (a.IconImageSource as FileImageSource)?.File == "more.png"))
{
element.ToolbarItems.Add(new ToolbarItem()
{
Order = ToolbarItemOrder.Primary,
IconImageSource = "more.png",
Priority = 1,
Command = new Command(ToggleDropDownMenuVisibility)
});
}
}
private void ToggleDropDownMenuVisibility()
{
if (!DoesTableExist())
{
if ((View?.Subviews != null)
&& (View.Subviews.Length > 0)
&& (View.Bounds != null)
&& (_secondaryItems != null)
&& (_secondaryItems.Count > 0))
{
_table = OpenDropDownMenu(Element as IAddToolbarItem);
Add(_table);
}
}
else
CloseDropDownMenu();
}
private bool DoesTableExist()
{
if (View?.Subviews != null)
{
foreach (var subview in View.Subviews)
{
if (_table != null && subview == _table)
{
return true;
}
}
}
if (_tapGestureRecognizer != null)
{
_transparentView?.RemoveGestureRecognizer(_tapGestureRecognizer);
_tapGestureRecognizer = null;
}
_table = null;
_tapGestureRecognizer = null;
return false;
}
private UITableView OpenDropDownMenu(IAddToolbarItem secondaryMenuSupport)
{
_transparentView = _transparentView = new UIView(new CGRect(0, 0, View.Bounds.Width, View.Bounds.Height))
{
BackgroundColor = UIColor.FromRGBA(0, 0, 0, 0)
};
_tapGestureRecognizer = new UITapGestureRecognizer(CloseDropDownMenu);
_transparentView.AddGestureRecognizer(_tapGestureRecognizer);
Add(_transparentView);
UITableView table = null;
if (_secondaryItems != null && _secondaryItems.Count > 0)
{
table = new UITableView(GetPositionForDropDownMenu(secondaryMenuSupport.RowHeight, secondaryMenuSupport.TableWidth))
{
Source = new TableSource(_secondaryItems, _transparentView),
ClipsToBounds = false
};
table.ScrollEnabled = true;
table.Layer.ShadowColor = secondaryMenuSupport.ShadowColor.ToCGColor();
table.Layer.ShadowOpacity = secondaryMenuSupport.ShadowOpacity;
table.Layer.ShadowRadius = secondaryMenuSupport.ShadowRadius;
table.Layer.ShadowOffset = new SizeF(secondaryMenuSupport.ShadowOffsetDimension, secondaryMenuSupport.ShadowOffsetDimension);
table.BackgroundColor = secondaryMenuSupport.MenuBackgroundColor.ToUIColor();
}
return table;
}
public override void ViewWillDisappear(bool animated)
{
CloseDropDownMenu();
base.ViewWillDisappear(animated);
}
private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
{
if ((View?.Bounds != null)
&& (_secondaryItems != null)
&& (_secondaryItems.Count > 0))
{
return new RectangleF(
(float)View.Bounds.Width - tableWidth,
0,
tableWidth,
_secondaryItems.Count() * rowHeight);
}
else
{
return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
}
}
private void CloseDropDownMenu()
{
if (_table != null)
{
if (_tapGestureRecognizer != null)
{
_transparentView?.RemoveGestureRecognizer(_tapGestureRecognizer);
_tapGestureRecognizer = null;
}
if (View?.Subviews != null)
{
foreach (var subview in View.Subviews)
{
if (subview == _table)
{
_table.RemoveFromSuperview();
break;
}
}
if (_transparentView != null)
{
foreach (var subview in View.Subviews)
{
if (subview == _transparentView)
{
_transparentView.RemoveFromSuperview();
break;
}
}
}
}
_table = null;
_transparentView = null;
}
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
if (_table != null)
{
if (Element is IAddToolbarItem secondaryMenuSupport)
PositionExistingDropDownMenu(secondaryMenuSupport.RowHeight, secondaryMenuSupport.TableWidth);
}
}
private void PositionExistingDropDownMenu(float rowHeight, float tableWidth)
{
if ((View?.Bounds != null)
&& (_secondaryItems != null)
&& (_secondaryItems.Count > 0)
&& (_table != null))
{
_table.Frame = GetPositionForDropDownMenu(rowHeight, tableWidth);
}
}
}
}
ADDITION:
public class TableSource : UITableViewSource
{
List<ToolbarItem> _tableItems;
string[] _tableItemTexts;
string CellIdentifier = "TableCell";
UIView _tableSuperView = null;
public TableSource(List<ToolbarItem> items, UIView tableSuperView)
{
_tableItems = items;
_tableSuperView = tableSuperView;
_tableItemTexts = items.Select(a => a.Text).ToArray();
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return _tableItemTexts?.Length ?? 0;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
string item = _tableItemTexts[indexPath.Row];
if (cell == null)
{ cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); }
cell.TextLabel.Text = item;
return cell;
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 56;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
var command = _tableItems[indexPath.Row].Command;
command.Execute(_tableItems[indexPath.Row].CommandParameter);
tableView.DeselectRow(indexPath, true);
tableView.RemoveFromSuperview();
if (_tableSuperView != null)
{
_tableSuperView.RemoveFromSuperview();
}
}
}
public interface IAddToolbarItem
{
event EventHandler ToolbarItemAdded;
Color CellBackgroundColor { get; }
Color CellTextColor { get; }
Color MenuBackgroundColor { get; }
float RowHeight { get; }
Color ShadowColor { get; }
float ShadowOpacity { get; }
float ShadowRadius { get; }
float ShadowOffsetDimension { get; }
float TableWidth { get; }
}
Here you can download the project that reproduces the issue:
https://github.com/DavidShochet/Public

Well, I still can't reproduce the problem with your updated code. I don't if it is a solution and I just want to clarify my comment here.
In your code, you add the _table to the View:
_table = OpenDropDownMenu(Element as IAddToolbarItem);
Add(_table);
What I want you to have a try is add the _table to _transparentView :
_table = OpenDropDownMenu(Element as IAddToolbarItem);
//Add(_table);
_transparentView.Add(_table);
It would be better if you can provide us a Minimal, Reproducible Example so that I can debug it on my side.
Update:
I found the problem is here, you set the height of table _secondaryItems.Count() * rowHeight) which is longer then the view when the toolbar menu grew longer:
private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
{
if ((View?.Bounds != null)
&& (_secondaryItems != null)
&& (_secondaryItems.Count > 0))
{
return new RectangleF(
(float)View.Bounds.Width - tableWidth,
0,
tableWidth,
//here is the cause
_secondaryItems.Count() * rowHeight);
}
else
{
return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
}
}
Solution: change the height of tablview to (float)View.Bounds.Height:
private RectangleF GetPositionForDropDownMenu(float rowHeight, float tableWidth)
{
if ((View?.Bounds != null)
&& (_secondaryItems != null)
&& (_secondaryItems.Count > 0))
{
return new RectangleF(
(float)View.Bounds.Width - tableWidth,
0,
tableWidth,
(float)View.Bounds.Height);
}
else
{
return new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
}
}

Related

Using pinch to zoomin and zoomout some unwanted background should copied color appeared and pixel quality low android below 9 version Xamarin android

Whenever i using wo fingers pinch to zoomin and zoomout some unwanted background should copied color appeared my camerapagerenderer if i single touch or touch it not seems to be apppear when i pinch to zoomin using two fingers it appears on my screen
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
oldDist = getFingerSpacing(e);
break;
case MotionEventActions.Move:
float newDist = getFingerSpacing(e);
if (newDist > oldDist)
{
//mCamera is your Camera which used to take picture, it should already exit in your custom Camera
handleZoom(true, camera);
}
else if (newDist < oldDist)
{
handleZoom(false, camera);
}
oldDist = newDist;
break;
}
return true;
}
private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
{
global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
if (parameters.IsZoomSupported)
{
int maxZoom = parameters.MaxZoom;
int zoom = parameters.Zoom;
if (isZoomIn && zoom < maxZoom)
{
zoom++;
}
else if(zoom > 0)
{
zoom--;
}
parameters.Zoom = zoom;
camera.SetParameters(parameters);
}
else
{
Android.Util.Log.Error("lv", "zoom not supported");
}
}
private static float getFingerSpacing(MotionEvent e)
{
if(e.PointerCount==2)
{
int pointerIndex = e.FindPointerIndex(_activePointerId);
float x = e.GetX(pointerIndex);
float y = e.GetY(pointerIndex);
return (float)Math.Sqrt(x * x + y * y);
}
}
You could check the code below. It works on Android 10.0 with no color shades.
class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
{
global::Android.Hardware.Camera camera;
global::Android.Widget.Button takePhotoButton;
global::Android.Widget.Button toggleFlashButton;
global::Android.Widget.Button switchCameraButton;
global::Android.Views.View view;
Activity activity;
CameraFacing cameraType;
TextureView textureView;
SurfaceTexture surfaceTexture;
bool flashOn;
public CameraPageRenderer(Context context) : base(context)
{
}
float oldDist = 1f;
public override bool OnTouchEvent(MotionEvent e)
{
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
oldDist = getFingerSpacing(e);
break;
case MotionEventActions.Move:
float newDist = getFingerSpacing(e);
if (newDist > oldDist)
{
//mCamera is your Camera which used to take picture, it should already exit in your custom Camera
handleZoom(true, camera);
}
else if (newDist < oldDist)
{
handleZoom(false, camera);
}
oldDist = newDist;
break;
}
return true;
}
private static float getFingerSpacing(MotionEvent e)
{
if (e.PointerCount == 2)
{
float x = e.GetX(0) - e.GetX(1);
float y = e.GetY(0) - e.GetY(1);
return (float)Math.Sqrt(x*x + y*y);
}
return 0;
}
private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
{
//camera.StopPreview();
// camera.Release();
// camera = global::Android.Hardware.Camera.Open((int)cameraType);
global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
if (parameters.IsZoomSupported)
{
int maxZoom = parameters.MaxZoom;
int zoom = parameters.Zoom;
if (isZoomIn && zoom < maxZoom)
{
zoom++;
}
else if (zoom > 0)
{
zoom--;
}
parameters.Zoom = zoom;
camera.SetParameters(parameters);
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}
else
{
Android.Util.Log.Error("lv", "zoom not supported");
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
try
{
SetupUserInterface();
//SetupEventHandlers();
AddView(view);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(#" ERROR: ", ex.Message);
}
}
void SetupUserInterface()
{
activity = this.Context as Activity;
view = activity.LayoutInflater.Inflate(Resource.Layout.CameraLayout, this, false);
cameraType = CameraFacing.Back;
textureView = view.FindViewById<TextureView>(Resource.Id.textureView);
textureView.SurfaceTextureListener = this;
}
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);
}
public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
camera = global::Android.Hardware.Camera.Open((int)cameraType);
textureView.LayoutParameters = new FrameLayout.LayoutParams(width, height);
surfaceTexture = surface;
camera.SetPreviewTexture(surface);
PrepareAndStartCamera();
}
public bool OnSurfaceTextureDestroyed(SurfaceTexture surface)
{
camera.StopPreview();
camera.Release();
return true;
}
public void OnSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
{
PrepareAndStartCamera();
}
public void OnSurfaceTextureUpdated(SurfaceTexture surface)
{
}
void PrepareAndStartCamera()
{
camera.StopPreview();
var display = activity.WindowManager.DefaultDisplay;
if (display.Rotation == SurfaceOrientation.Rotation0)
{
camera.SetDisplayOrientation(90);
}
if (display.Rotation == SurfaceOrientation.Rotation270)
{
camera.SetDisplayOrientation(180);
}
camera.StartPreview();
}
}
Update: The result on Android 6.0

AutoComplete javaFx ComboBox items not showing after "clearing selection"

I'm trying to make an autocomplete combobox in javafx and im almost done but every time i try to submit and clear selection so the user can choose another choice , all the items get hidden except the one he chose last time
// this the class that i used turn a normal combobox to an autocomplete one
public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {
private ComboBox<T> comboBox;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
public AutoCompleteComboBoxListener(final ComboBox<T> comboBox) {
this.comboBox = comboBox;
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
this.showOnFocus();
}
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.UP) {
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if(event.getCode() == KeyCode.DOWN) {
if(!comboBox.isShowing())
comboBox.show();
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
}
if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
System.out.println(caretPos);
comboBox.hide();
if(event.getCode() == KeyCode.BACK_SPACE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if(event.getCode() == KeyCode.DELETE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
}
ObservableList<T> list = FXCollections.observableArrayList();
for (int i=0; i<data.size(); i++) {
if(data.get(i).toString().toLowerCase().startsWith(
AutoCompleteComboBoxListener.this.comboBox
.getEditor().getText().toLowerCase())) {
list.add(data.get(i));
}
}
String t = comboBox.getEditor().getText();
comboBox.setItems(list);
comboBox.getEditor().setText(t);
if(!moveCaretToPos) {
caretPos = -1;
}
moveCaret(t.length());
if(!list.isEmpty()) {
comboBox.show();
String editorText;
editorText=comboBox.getEditor().getText();
list.sort((a, b) -> Integer.compare(a.toString().length(), b.toString().length()));
comboBox.getSelectionModel().selectFirst();
comboBox.getEditor().setText(editorText);
moveCaret(comboBox.getSelectionModel().getSelectedItem().toString().length());
}
if (event.getCode()==KeyCode.ENTER){
comboBox.hide();
comboBox.getEditor().setText(comboBox.getSelectionModel().getSelectedItem().toString());
}
}
private void moveCaret(int textLength) {
if(caretPos == -1)
comboBox.getEditor().positionCaret(textLength);
else
comboBox.getEditor().positionCaret(caretPos);
moveCaretToPos = false;
}
public void showOnFocus(){
this.comboBox.focusedProperty().addListener((obs, oldVal, newVal) ->
this.comboBox.show());
}
}
// and this is what the submit button does the the comboboxes
button.setOnAction(e-> {
combo1.getSelectionModel().clearSelection();
combo1.getSelectionModel().clearSelection();
});

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

Unity Interactable = False suddenly not working

now i encountered a very very weird issue. below is the code. pardon the length. This class has multiple function that were working when there only 3 (upt to button C)buttons being reference, in fact the one installed on my phone has the already pressed button disabled after i go back to the initial scene.
So me thinking all is good decided to do this for all the buttons that I have on my initial Screen. But for some reason it is not working, it is not disabling the buttons anymore. I have the GameLogic.cs where i have my variables declared and this script as well. 16 buttons = 16 Alphabets. So basically it just increments a value once button is pressed then once we go back to the initial screen On update, if the value is >= 1 then that particular button must be disabled.
Again it is working when i first built it for the phone. it is there. this is so weird. Maybe you can see some issue with the code here perhaps?
Thanks.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class forButtonDisabler : MonoBehaviour {
public Button buttonA;
public Button buttonB;
public Button buttonC;
public Button buttonD;
public Button buttonE;
public Button buttonF;
public Button buttonG;
public Button buttonH;
public Button buttonI;
public Button buttonJ;
public Button buttonK;
public Button buttonL;
public Button buttonM;
public Button buttonN;
public Button buttonO;
public Button buttonP;
void OnEnable()
{
//Register Button Events
buttonA = GameObject.Find("btn5ptsPP").GetComponent<Button>();
buttonB = GameObject.Find("btn5ptsDP").GetComponent<Button>();
buttonC = GameObject.Find("btn5ptsTE").GetComponent<Button>();
buttonD = GameObject.Find("btn5ptsTA").GetComponent<Button>();
buttonE= GameObject.Find("btn10ptsPP").GetComponent<Button>();
buttonF = GameObject.Find("btn10ptsDP").GetComponent<Button>();
buttonG = GameObject.Find("btn10ptsTE").GetComponent<Button>();
buttonH = GameObject.Find("btn10ptsTA").GetComponent<Button>();
buttonI = GameObject.Find("btn15ptsPP").GetComponent<Button>();
buttonJ = GameObject.Find("btn15ptsDP").GetComponent<Button>();
buttonK = GameObject.Find("btn15ptsTE").GetComponent<Button>();
buttonL = GameObject.Find("btn15ptsTA").GetComponent<Button>();
buttonM = GameObject.Find("btn20ptsPP").GetComponent<Button>();
buttonN = GameObject.Find("btn20ptsDP").GetComponent<Button>();
buttonO = GameObject.Find("btn20ptsTE").GetComponent<Button>();
buttonP = GameObject.Find("btn20ptsTA").GetComponent<Button>();
buttonA.onClick.AddListener(() => buttonCallBack(buttonA));
buttonB.onClick.AddListener(() => buttonCallBack(buttonB));
buttonC.onClick.AddListener(() => buttonCallBack(buttonC));
buttonD.onClick.AddListener(() => buttonCallBack(buttonD));
buttonE.onClick.AddListener(() => buttonCallBack(buttonE));
buttonF.onClick.AddListener(() => buttonCallBack(buttonF));
buttonG.onClick.AddListener(() => buttonCallBack(buttonG));
buttonH.onClick.AddListener(() => buttonCallBack(buttonH));
buttonI.onClick.AddListener(() => buttonCallBack(buttonI));
buttonJ.onClick.AddListener(() => buttonCallBack(buttonJ));
buttonK.onClick.AddListener(() => buttonCallBack(buttonK));
buttonL.onClick.AddListener(() => buttonCallBack(buttonL));
buttonM.onClick.AddListener(() => buttonCallBack(buttonM));
buttonN.onClick.AddListener(() => buttonCallBack(buttonN));
buttonO.onClick.AddListener(() => buttonCallBack(buttonO));
buttonP.onClick.AddListener(() => buttonCallBack(buttonP));
}
private void buttonCallBack(Button buttonPressed)
{
if (buttonPressed == buttonA)
{
GameLogic.Cbtn1++;
}
if (buttonPressed == buttonB)
{
GameLogic.Cbtn2++;
}
if (buttonPressed == buttonC)
{
GameLogic.Cbtn3++;
}
if (buttonPressed == buttonD)
{
GameLogic.Cbtn4++;
}
if (buttonPressed == buttonE)
{
GameLogic.Cbtn5++;
}
if (buttonPressed == buttonF)
{
GameLogic.Cbtn6++;
}
if (buttonPressed == buttonG)
{
GameLogic.Cbtn7++;
}
if (buttonPressed == buttonH)
{
GameLogic.Cbtn8++;
}
if (buttonPressed == buttonI)
{
GameLogic.Cbtn9++;
}
if (buttonPressed == buttonJ)
{
GameLogic.Cbtn10++;
}
if (buttonPressed == buttonK)
{
GameLogic.Cbtn11++;
}
if (buttonPressed == buttonL)
{
GameLogic.Cbtn12++;
}
if (buttonPressed == buttonM)
{
GameLogic.Cbtn13++;
}
if (buttonPressed == buttonN)
{
GameLogic.Cbtn14++;
}
if (buttonPressed == buttonO)
{
GameLogic.Cbtn15++;
}
if (buttonPressed == buttonP)
{
GameLogic.Cbtn16++;
}
}
void OnDisable()
{
//Un-Register Button Events
buttonA.onClick.RemoveAllListeners();
buttonB.onClick.RemoveAllListeners();
buttonC.onClick.RemoveAllListeners();
buttonD.onClick.RemoveAllListeners();
buttonE.onClick.RemoveAllListeners();
buttonF.onClick.RemoveAllListeners();
buttonG.onClick.RemoveAllListeners();
buttonH.onClick.RemoveAllListeners();
buttonI.onClick.RemoveAllListeners();
buttonJ.onClick.RemoveAllListeners();
buttonK.onClick.RemoveAllListeners();
buttonL.onClick.RemoveAllListeners();
buttonM.onClick.RemoveAllListeners();
buttonN.onClick.RemoveAllListeners();
buttonO.onClick.RemoveAllListeners();
buttonP.onClick.RemoveAllListeners();
}
// Update is called once per frame
void Update()
{
if (GameLogic.Cbtn1 >= 1)
{
buttonA.interactable = false;
}
if (GameLogic.Cbtn2 >= 1)
{
buttonB.interactable = false;
}
if (GameLogic.Cbtn3 >= 1)
{
buttonC.interactable = false;
}
if (GameLogic.Cbtn4 >= 1)
{
buttonD.interactable = false;
}
if (GameLogic.Cbtn5 >= 1)
{
buttonE.interactable = false;
}
if (GameLogic.Cbtn6 >= 1)
{
buttonF.interactable = false;
}
if (GameLogic.Cbtn7 >= 1)
{
buttonG.interactable = false;
}
if (GameLogic.Cbtn8 >= 1)
{
buttonH.interactable = false;
}
if (GameLogic.Cbtn9 >= 1)
{
buttonI.interactable = false;
}
if (GameLogic.Cbtn10 >= 1)
{
buttonJ.interactable = false;
}
if (GameLogic.Cbtn11 >= 1)
{
buttonK.interactable = false;
}
if (GameLogic.Cbtn12 >= 1)
{
buttonL.interactable = false;
}
if (GameLogic.Cbtn13 >= 1)
{
buttonM.interactable = false;
}
if (GameLogic.Cbtn14 >= 1)
{
buttonN.interactable = false;
}
if (GameLogic.Cbtn15 >= 1)
{
buttonO.interactable = false;
}
if (GameLogic.Cbtn16 >= 1)
{
buttonP.interactable = false;
}
}
}

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

Resources