Instantly share code, notes, and snippets.
Last active
January 3, 2019 12:13
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save linhdh/9c4234d4dbcdc8791bb329499e865f25 to your computer and use it in GitHub Desktop.
[Xamarin form] Dropdown control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ShowSubviewAt(CGRect rect, UIView subView, Action didFinishAnimation) | |
{ | |
UIView cover = new UIView(); | |
cover.Frame = new CGRect(0, 0, AppWindow.Bounds.Width, AppWindow.Bounds.Height); | |
//cover.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; | |
//cover.Opaque = true; | |
cover.BackgroundColor = UIColor.Clear; | |
cover.AddGestureRecognizer(new UITapGestureRecognizer(() => | |
{ | |
cover.RemoveFromSuperview(); | |
if (subView != null) | |
subView.RemoveFromSuperview(); | |
})); | |
AppWindow.AddSubview(cover); | |
subView.Frame = new CGRect(rect.X, rect.Y, rect.Width, 0); | |
UIView.Animate(0.2, () => | |
{ | |
subView.Frame = new CGRect(rect.X, rect.Y, rect.Width, rect.Height); | |
AppWindow.AddSubview(subView); | |
}, didFinishAnimation); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Android.App; | |
using Android.Content; | |
using Android.OS; | |
using Android.Runtime; | |
using Android.Views; | |
using Android.Widget; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
using App3.Droid.Views.Customs; | |
using App3.Views.Customs; | |
using App3.ViewModels; | |
using Android.Support.V4.View; | |
using System.ComponentModel; | |
using Java.Lang; | |
[assembly: ExportRenderer(typeof(DropDownMenuView), typeof(DropDownMenuRender_Android))] | |
namespace App3.Droid.Views.Customs | |
{ | |
public class DropDownMenuRender_Android : ViewRenderer<DropDownMenuView, Android.Views.View>, Spinner.IOnItemSelectedListener | |
{ | |
Spinner _nativeView; | |
Spinner.IOnItemSelectedListener _itemSelected; | |
DropDownMenuView _dropDownView; | |
SpinnerAdapter _adapter; | |
protected override void OnElementChanged(ElementChangedEventArgs<DropDownMenuView> e) | |
{ | |
base.OnElementChanged(e); | |
if (e.NewElement != null) | |
{ | |
_dropDownView = (DropDownMenuView)e.NewElement; | |
if (Control == null) | |
{ | |
Android.Widget.RelativeLayout wraper = new Android.Widget.RelativeLayout(Android.App.Application.Context); | |
ContextThemeWrapper theme = new ContextThemeWrapper(Android.App.Application.Context, App3.Droid.Resource.Style.SpinnerAsEditText); | |
_nativeView = new Spinner(theme); | |
_nativeView.OnItemSelectedListener = this; | |
if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M) | |
_nativeView.SetBackgroundResource(App3.Droid.Resource.Drawable.border); | |
else | |
wraper.SetBackgroundResource(App3.Droid.Resource.Drawable.border); | |
_nativeView.LayoutParameters = new Android.Widget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent); | |
_dropDownView.SetItemSelection = (i) => { | |
_nativeView.SetSelection(i); | |
}; | |
ImageView downIcon = new ImageView(Android.App.Application.Context); | |
var param = new Android.Widget.RelativeLayout.LayoutParams(20, 20); | |
param.AddRule(LayoutRules.AlignParentRight); | |
param.AddRule(LayoutRules.CenterInParent); | |
param.SetMargins(0, 0, 14, 0); | |
downIcon.LayoutParameters = param; | |
downIcon.SetImageResource(App3.Droid.Resource.Drawable.ic_arrow_drop_down_black); | |
wraper.AddView(_nativeView); | |
wraper.AddView(downIcon); | |
SetNativeControl(wraper); | |
} | |
if (_dropDownView.ItemsSource != null) | |
SetApdater(); | |
} | |
} | |
private void SetApdater() | |
{ | |
if(_dropDownView.ItemsSource!=null) | |
{ | |
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(Android.App.Application.Context, | |
// Android.Resource.Layout.SimpleSpinnerItem, _dropDownView.ItemsSource); | |
//adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleListItemSingleChoice); | |
if (_adapter == null) | |
{ | |
_adapter = new SpinnerAdapter(_dropDownView.ItemsSource); | |
_nativeView.Adapter = _adapter; | |
} | |
else | |
_adapter.SetData(_dropDownView.ItemsSource); | |
} | |
} | |
class SpinnerAdapter : BaseAdapter | |
{ | |
private List<string> _datas; | |
public SpinnerAdapter(List<string> datas) | |
{ | |
_datas = datas; | |
} | |
public override int Count | |
{ | |
get | |
{ | |
return _datas != null ? _datas.Count : 0; | |
} | |
} | |
public void SetData(List<string> datas) | |
{ | |
_datas = datas; | |
NotifyDataSetChanged(); | |
} | |
public override Java.Lang.Object GetItem(int position) | |
{ | |
return _datas[position]; | |
} | |
public override long GetItemId(int position) | |
{ | |
return 0; | |
} | |
public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent) | |
{ | |
var item = (Android.Views.View)Android.Views.View.Inflate(Android.App.Application.Context, Resource.Layout.spinner_item, null); | |
TextView text = item.FindViewById<TextView>(App3.Droid.Resource.Id.txtSpinnerText1); | |
text.Text = _datas[position]; | |
if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M) | |
{ | |
item.SetBackgroundResource(App3.Droid.Resource.Drawable.border); | |
item.FindViewById(App3.Droid.Resource.Id.line).Visibility = ViewStates.Gone; | |
} | |
return item; | |
} | |
} | |
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) | |
{ | |
base.OnElementPropertyChanged(sender, e); | |
SetApdater(); | |
} | |
public void OnItemSelected(AdapterView parent, Android.Views.View view, int position, long id) | |
{ | |
if(_dropDownView.ItemSelecetedEvent!=null) | |
{ | |
_dropDownView.ItemSelecetedEvent.Invoke(position); | |
} | |
} | |
public void OnNothingSelected(AdapterView parent) | |
{ | |
if (_dropDownView.ItemSelecetedEvent != null) | |
{ | |
_dropDownView.ItemSelecetedEvent.Invoke(-1); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.iOS; | |
using App3.iOS.Views.Custom; | |
using App3.Views.Customs; | |
using System; | |
using UIKit; | |
using Foundation; | |
using CoreGraphics; | |
[assembly: ExportRenderer(typeof(DropDownMenuView), typeof(DropDownMenuRender_iOS))] | |
namespace App3.iOS.Views.Custom | |
{ | |
public class DropDownMenuRender_iOS : ViewRenderer<DropDownMenuView, UIView> | |
{ | |
DropDownMenuView _dropDownView; | |
UITableView tableView; | |
UIView wrapper; | |
UILabel label; | |
UIImageView arrow; | |
int selectedIndex = 0; | |
protected override void OnElementChanged(ElementChangedEventArgs<DropDownMenuView> e) | |
{ | |
base.OnElementChanged(e); | |
if (e.NewElement != null) | |
{ | |
_dropDownView = (DropDownMenuView)e.NewElement; | |
if (Control == null) | |
{ | |
wrapper = new UIView(); | |
wrapper.Layer.BorderColor = ColorExtensions.ToCGColor(Color.FromHex(Define.DISABLE_CONTENT_COLOR)); | |
wrapper.Layer.BorderWidth = 1; | |
wrapper.Frame = this.Frame; | |
//wrapper.BackgroundColor = UIColor.Red; | |
wrapper.AddGestureRecognizer( new UITapGestureRecognizer(() =>{ | |
ButtonClickHanlde(); | |
})); | |
arrow = new UIImageView(); | |
arrow.Image = new UIImage("ic_arrow_drop_down_black.png"); | |
arrow.Frame = new CGRect(10, 10, 50, 30); | |
wrapper.AddSubview(arrow); | |
label = new UILabel(); | |
label.TextColor = UIColor.Black; | |
label.Frame = new CGRect(10, 10, 50, 30); | |
if (_dropDownView != null && _dropDownView.ItemsSource != null) | |
label.Text = _dropDownView.ItemsSource[0]; | |
wrapper.AddSubview(label); | |
tableView = new UITableView(); | |
//tableView | |
tableView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; | |
tableView.Frame = wrapper.Frame; | |
tableView.Layer.BorderWidth = 1; | |
tableView.Layer.BorderColor = ColorExtensions.ToCGColor(Color.FromHex(Define.DISABLE_CONTENT_COLOR)); | |
tableView.WeakDelegate = this; | |
tableView.WeakDataSource = this; | |
_dropDownView.SetItemSelection += (obj) => { | |
//if(label!=null) | |
selectedIndex = obj; | |
label.Text = _dropDownView.ItemsSource[obj]; | |
if (_dropDownView.ItemSelecetedEvent != null) | |
_dropDownView.ItemSelecetedEvent.Invoke(obj); | |
}; | |
SetNativeControl(wrapper); | |
} | |
} | |
} | |
protected override void Dispose(bool disposing) | |
{ | |
if (disposing && tableView != null) | |
tableView.RemoveFromSuperview(); | |
base.Dispose(disposing); | |
} | |
public override CGRect Frame | |
{ | |
get | |
{ | |
return base.Frame; | |
} | |
set | |
{ | |
base.Frame = value; | |
if ( label!=null&& wrapper != null && value != CGRect.Empty) | |
{ | |
//label.BackgroundColor = UIColor.Green; | |
label.Frame = new CGRect(8, 2, value.Size.Width - 10, value.Size.Height - 4); | |
this.LayoutSubviews(); | |
} | |
if (arrow != null && wrapper != null && value != CGRect.Empty) | |
{ | |
//arrow.BackgroundColor = UIColor.Green; | |
arrow.Frame = new CGRect(value.Size.Width-20, (value.Size.Height-10)/2, 10, 10); | |
this.LayoutSubviews(); | |
} | |
} | |
} | |
public void UpdateButton(string name) | |
{ | |
} | |
bool isShowDialog = false; | |
private void ButtonClickHanlde() | |
{ | |
if (wrapper == null) | |
return; | |
isShowDialog = !isShowDialog; | |
if(isShowDialog) | |
{ | |
var rect = wrapper.ConvertRectToView(wrapper.Frame, AppDelegate.AppWindow); | |
nfloat height = AppDelegate.AppWindow.Bounds.Height - rect.Y - 10; | |
CGRect r = new CGRect(rect.X, rect.Y, rect.Width, height); | |
int listCount= _dropDownView == null ? 0 : _dropDownView.ItemsSource.Count; | |
AppDelegate.Instance.ShowSubviewAt(r, tableView,()=>{ | |
if (selectedIndex < listCount) | |
tableView.ScrollToRow(NSIndexPath.FromRowSection(selectedIndex, 0), UITableViewScrollPosition.Top, false); | |
}); | |
}else | |
{ | |
tableView.RemoveFromSuperview(); | |
} | |
} | |
[Export("tableView:numberOfRowsInSection:")] | |
public nint RowsInSection(UITableView tableView, nint section) | |
{ | |
return _dropDownView == null ? 0 : _dropDownView.ItemsSource.Count; | |
} | |
[Export("tableView:cellForRowAtIndexPath:")] | |
public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) | |
{ | |
var simpleTableIdentifier = @"SimpleTableItem"; | |
var cell = tableView.DequeueReusableCell(simpleTableIdentifier); | |
if (cell == null) | |
{ | |
cell = new UITableViewCell(UITableViewCellStyle.Default, simpleTableIdentifier); | |
} | |
cell.TextLabel.Text = _dropDownView.ItemsSource[indexPath.Row]; | |
return cell; | |
} | |
[Export("numberOfSectionsInTableView:")] | |
public virtual nint NumberOfSections(UITableView tableView) | |
{ | |
return 1; | |
} | |
[Export("tableView:didSelectRowAtIndexPath:")] | |
public void RowSelected(UITableView tableView, NSIndexPath indexPath) | |
{ | |
selectedIndex = indexPath.Row; | |
ButtonClickHanlde(); | |
tableView.DeselectRow(indexPath,true); | |
label.Text = _dropDownView.ItemsSource[indexPath.Row]; | |
if (_dropDownView.ItemSelecetedEvent != null) | |
_dropDownView.ItemSelecetedEvent.Invoke(indexPath.Row); | |
} | |
[Export("tableView:heightForRowAtIndexPath:")] | |
public virtual nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath) | |
{ | |
return 50; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms; | |
using System.Collections.Generic; | |
namespace Demo.Views.Customs | |
{ | |
public class DropDownMenuView : View | |
{ | |
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(List<string>), typeof(DropDownMenuView)); | |
public static readonly BindableProperty ItemSelecetedEventProperty = BindableProperty.Create("ItemSelecetedEvent", typeof(Action<int>), typeof(DropDownMenuView)); | |
public static readonly BindableProperty SetItemSelectionProperty = BindableProperty.Create("SetItemSelection", typeof(Action<int>), typeof(DropDownMenuView)); | |
public List<string> ItemsSource | |
{ | |
get { return (List<string>)GetValue(ItemsSourceProperty); } | |
set { SetValue(ItemsSourceProperty, value); } | |
} | |
public Action<int> ItemSelecetedEvent | |
{ | |
get { return (Action<int>)GetValue(ItemSelecetedEventProperty); } | |
set { SetValue(ItemSelecetedEventProperty, value); } | |
} | |
public Action<int> SetItemSelection | |
{ | |
get { return (Action<int>)GetValue(SetItemSelectionProperty); } | |
set { SetValue(SetItemSelectionProperty, value); } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment