Xamarin.Android Material Button SetMinHeight programmatically? - xamarin.android

I'm trying to create a Material Button programmatically in Xamarin.Android and attaching this to a TableRow which is in turn attached to a Table. In OnCreate, I SetContentView before calling the CreateButtons() function below. When I use SetMinHeight() inside the function, the button shows but the min height doesn't appear to work. However, when this code is added to the click event and the button is pressed, it updates the button correctly.
The function that loads with the Activity:
public void CreateButtons()
{
var tableLayout = FindViewById<TableLayout>(Resource.Id.tableLayout1);
TableRow.LayoutParams buttonParams = new TableRow.LayoutParams(
0,
TableRow.LayoutParams.WrapContent,
1.0f
);
buttonParams.SetMargins(3, 3, 3, 3);
TableRow tr = new TableRow(this);
tr.LayoutParameters = new TableRow.LayoutParams(
TableRow.LayoutParams.WrapContent,
TableRow.LayoutParams.WrapContent
);
MaterialButton button = new MaterialButton(this);
button.Text = "Test Button";
button.TextAlignment = TextAlignment.Center;
button.IconSize = 158;
button.Icon = GetDrawable(Resource.Drawable.goodsin);
button.IconGravity = 16;
button.Click += Button_Click;
button.LayoutParameters = buttonParams;
button.SetMinHeight(126);
tr.AddView(button);
tableLayout.AddView(tr);
}
The button after the function has generated it, cutting the text off:
The code inside the button click event:
private void Button_Click(object sender, EventArgs e)
{
var button = (MaterialButton)sender;
button.SetMinHeight(126);
}
The button after the click event has completed, now showing the correct size and text:

Related

UIPickerView not interactive

I have an application that from the main app "hamburger" menu, if an option is selected I want to show a PickerView for the user to select a number from.
Because it's needs to be accessible throughout the app from this menu I built the UIPickerView in the AppDelegate.cs (as that's where the UINavigationController code is and from that the menu).
Everything shows up correctly: User selected menu button -> menu displays -> User selects "Show Picker" button -> Picker displays with all items. But once the picker displays, you can't scroll the options, nor does the "Done" button I've added register clicks. In fact text fields from the ViewController behind this popup can be clicked on through the popup.
I'm not sure why this UIPickerView is non interactive, does anyone have some thoughts?
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow(UIScreen.MainScreen.Bounds);
// instantiate the navigation controller
nav = new UINavigationController(new SplashController());
vwNav = new UIView(nav.NavigationBar.Bounds);
var pickerView = new UIPickerView(new CGRect(275f, (UIScreen.MainScreen.Bounds.Size.Height / 2) - (375f / 2), 275f, 375f));
pickerView.ShowSelectionIndicator = true;
var myPickerViewModel = new PickerViewModel(itemList);
pickerView.Model = myPickerViewModel;
myPickerViewModel.PickerChanged += (sender, e) => {
var temp = myPickerViewModel.SelectedItem;
};
// Set up toolbar
var toolbar = new UIToolbar();
toolbar.SizeToFit();
toolbar.Hidden = false;
UILabel titleLabel = new UILabel();
titleLabel.Text = "Select an Item";
titleLabel.Frame = new RectangleF(75, 13, 200, 20);
UIButton doneButton = new UIButton(UIButtonType.Custom);
doneButton.Frame = new RectangleF(40, 335, (float)200, 30);
doneButton.SetTitle("Done", UIControlState.Normal);
doneButton.TouchDown += (sender, e) =>
{
pickerView.Hidden = true;
};
toolbar.AddSubview(titleLabel);
toolbar.AddSubview(doneButton);
pickerView.AddSubview(toolbar);
pickerView.Hidden = true;
btnMenu = new UIButton(UIButtonType.Custom);
btnMenu.Frame = new CGRect(vwNav.Frame.Right - 45, 0, 45, nav.NavigationBar.Bounds.Height);
btnMenu.SetImage(imgMenu, UIControlState.Normal);
btnMenu.SetImage(imgMenu, UIControlState.Selected);
btnMenu.TouchUpInside += (object sender, EventArgs e) =>
{
UIAlertView alert = new UIAlertView();
alert.Title = "Settings";
alert.AddButton("Open PickerView");
alert.AddButton("Exit");
alert.Dismissed += delegate (object alertSender, UIButtonEventArgs args)
{
if (args.ButtonIndex == 0)
{
pickerView.Hidden = false;
}
else
return;
}
}
vwNav.AddSubviews(btnMenu, pickerView);
nav.NavigationBar.Layer.BorderWidth = 2f;
nav.NavigationBar.Layer.BorderColor = (UIColor.FromPatternImage(imgNavBar)).CGColor;
nav.NavigationBar.AddSubviews(vwNav);
// If you have defined a root view controller, set it here:
this.window.RootViewController = nav;
this.window.MakeKeyAndVisible();
return true;
}
I removed some of the unrelated code (a few nav.PushViewController() for different screens and other menu options) to keep it as clear as I could.
From your code, the frame of vwNav is nav.NavigationBar.Bounds, and the frame of pickerView is new CGRect(275f, (UIScreen.MainScreen.Bounds.Size.Height / 2) - (375f / 2), 275f, 375f), if you add pickView to vwNav, the pickerView is out of bounds of vwNav.
Remember that views don't receive touch events where they're outside the bounds of their superview.
That's the cause of your issue.
Solution:
I don't think you should built the UIPickerView in the AppDelegate.cs, create it in your ViewController instead.
You can also add buttons to Navigationbar in ViewController :
UIBarButtonItem btn = new UIBarButtonItem();
btn.Image = UIImage.FromFile("Image");
btn.Clicked += (sender, e) => { System.Diagnostics.Debug.WriteLine("show picker"); };
NavigationItem.RightBarButtonItem = btn;
And remember to add picker to the View of Viewcontroller.
Refer: uinavigationitem and add-uibarbuttonitem-to-navigation-bar-in-xamarin-ios
Feel free to ask me any question:).

Shadow in UIView cannot overlay Entry or Editor or Picker in Xamarin Forms

I added an RoutingEffect in Xamarin Form project and PlatformEffect in my Xamarin.iOS project. It will add effect to Stacklayout. The Stacklayout in this demo is a custom navigation bar. The below of navigation bar is a scrollview has many cells (label, entry, picker).
I implemented in Android is OK.
But in iOS has problem: Shadow effect cannot overlays some controls, such as: Entry, Editor, Picker. Could you share me how to fix it?
This is code in Xamarin.iOS project.
public class DropShadowEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
var effect = (myDemo.UIControls.DropShadowEffect)Element.Effects.FirstOrDefault(e => e is myDemo.UIControls.DropShadowEffect);
if (effect != null)
{
Container.Layer.CornerRadius = effect.Radius;
Container.Layer.ShadowColor = UIColor.Red.CGColor;// effect.Color.ToCGColor();
Container.Layer.ShadowOffset = new CGSize(effect.DistanceX, effect.DistanceY);
Container.Layer.ShadowOpacity = 0.8f;
Container.Layer.ShadowRadius = 2f;
Container.Layer.ShouldRasterize = true;
Container.Layer.MasksToBounds = false;
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: {0}", ex.Message);
}
}
*Shadow effect overly Label is OK
*Shadow effect cannot overlay either Picker or Entry
Cause:
Actually, such as Label will still overlay the shadow.But it doesn't seem obvious.If you set the background of label (such as red ),you will see the overlay.
Solution:
You can set the BackgroundColor of the Picker and Entry in the custom renderer to let the alpha as 0.
For example in EntryRenderer
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.BackgroundColor = new UIColor(1,1,1,0);//The last parameter sets the alpha of backgound as transparent
Control.Layer.MasksToBounds = true;
Control.Layer.CornerRadius = xxx; //set the rounded corner
Control.Layer.BorderColor = UIColor.xxx.CGColor;
Control.Layer.BorderWidth = xxx;
}
}

UIButton responds slow to the continuous taps?

The button control in xamarin I am using has some very different issue that I haven't met before. The issue is that If I tap on the button very fast and continuously for many times it processing all the taps very slowly. It is visibly irritating that it keep on blinking even after I stopped.
Below is my code
UI Creation Code
QRButton = new Button
{
Text="Title",
TextColor = Color.White,
BackgroundColor = Color.FromHex("#0064A4"),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Center,
WidthRequest = 250.0,
BorderRadius = 0
};
//add event handler
QRButton.Clicked += QRButtonPressed;
Button Action
private void QRButtonPressed(object sender, EventArgs e)
{
Console.WriteLine("QR Generation Started");
// Some long running process
Console.WriteLine("QR Generation Completed");
}
The Renderer Implementation
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if(e.NewElement!=null)
{
Control.TitleEdgeInsets = new UIEdgeInsets(4, 4, 4, 4);
Control.TitleLabel.LineBreakMode = UILineBreakMode.WordWrap;
Control.TitleLabel.TextAlignment = UITextAlignment.Center;
}
}

Is there any custom date picker for iOS where year selection is optional?

I need to be able to select day and month and leave the option to the user to select the year or not. For example I was thinking a list with all the years and at the end an added option "no selection".
Any ideas how to do that?
I suppose that using the picker view is one solution but not sure.
Thanks
Using xamarin.ios what I did was create a toolbar on top of the thumbwheel with a Done and a Cancel buttons. When you click done the value is set, and you click cancel what you need to do is set the Datepicker value to a value like 1900-1-1 and change the uitextfield value to something like "Not set".
I'm using xamarin forms. This is what I have in my custom renderer:
public override void Draw (CGRect rect)
{
base.Draw (rect);
DatePicker elem = (DatePicker)Element;
UITextField textField = (UITextField)Control;
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
toolbar.Items = new[]
{
new UIBarButtonItem(UIBarButtonSystemItem.Cancel,(object sender, EventArgs e) => {
if (elem.SetValueNullAction!=null){
elem.SetValueNullAction();
textField.Text = DefaultNotSetText;
}
}),
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
new UIBarButtonItem(UIBarButtonSystemItem.Done,(object sender, EventArgs e) => {
elem.Unfocus();
})
};
textField.InputAccessoryView = toolbar;
textField.BorderStyle = UITextBorderStyle.None;
textField.TextColor = Color.FromHex ("999999").ToUIColor ();
CGRect frame = textField.Frame;
frame.Width = 100;
textField.Frame = frame;
if (elem.Date == elem.MinimumDate) {
textField.Text = ((DatePicker)this.Element).Label;
}
}
Hope this helps!
You can have a try of CKPickerView, it allows very easy customization on UIDatePicker.

Refresh view in xamarin iOS

I'm new to Xamaring and iOS, but I'm trying to create a view that when the UIBarButtonSystemItem.Add is pressed, it adds a record to the SQLite database, alerts the user and then refreshes the screen as the screen draws out a button for each of the records in the table in SQLite.
Currently the add button code is:
this.NavigationItem.SetRightBarButtonItem(new UIBarButtonItem(UIBarButtonSystemItem.Add, (sender,args) => {
conn.Query<Job>("INSERT INTO Job (Job) VALUES(0)");
UIAlertView alSQL = new UIAlertView("Jobs","New job added",null,"ok",null);AllJobsScreen(), true);
alSQL.Show ();
}), true);
At present the data is added and the alert is shown, but I'm not sure of anyway to get the screen to reflect this new record in the database and add a new button.
I've looked online for refreshing the screen and can't find anything so any help would be great. Or if I'm going about this the wrong way, please let me know.
I'm writing out buttons on the screen, but ideally I need to be able to refresh any view with anything on it. At present the buttons are written out in a loop from a SQLite query as below:
UIButton btnTest = new UIButton (UIButtonType.System);
btnTest.Frame = new RectangleF(iTopLeftx, iTopLefty, 300, 30);
btnTest.SetTitle("J00000" + s.mJobID.ToString(),UIControlState.Normal);
btnTest.BackgroundColor = UIColor.Clear;
this.View.Add (btnTest);
Try changing the TitleColor, BorderColor and BorderWidth of your newly created UIButtons. Maybe your buttons are displayed on the view but you just can't see them.
UIButton btnTest = UIButton.FromType(UIButtonType.Custom);
btnTest.Frame = new RectangleF(iTopLeftx, iTopLefty, 300, 30);
btnTest.SetTitle("J00000" + s.mJobID.ToString(), UIControlState.Normal);
btnTest.SetTitleColor(UIColor.Black, UIControlState.Normal);
btnTest.Layer.BorderColor = UIColor.Black.CGColor;
btnTest.Layer.BorderWidth = 1;
btnTest.BackgroundColor = UIColor.Clear;
this.View.Add(btnTest);
EDIT
Then the problem seems to be that you didn't remove previously added UIButtons. Try to hold your collection of UIButtons in a list or an array.
List<UIButton> buttonList;
Then populate your buttonList:
private void PopulateSubviews()
{
for (int i=0; i<count; i++)
{
UIButton btnTest = UIButton.FromType(UIButtonType.Custom);
// previous code withoud this.View.Add(...);
...
buttonList.Add(btnTest);
}
}
And have these two methods:
private void ClearView()
{
foreach (UIButton btn in buttonList)
{
btn.RemoveFromSuperview();
}
buttonList.Clear();
}
private void InitializeSubviews()
{
foreach (UIButton btn in buttonList)
{
this.View.AddSubview(btn);
}
}
And to refresh your views:
private void ReloadSubviews()
{
ClearView();
PopulateSubviews();
InitializeSubviews();
}

Resources