From 2e9410846eddd8e8b661ba39d0c1a71df0e76572 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 28 Jun 2016 23:44:47 -0400 Subject: [PATCH] Optimizations for dynamic text sizes. --- .../Controls/ExtendedTextCellRenderer.cs | 28 +++++------ .../Controls/ExtendedViewCellRenderer.cs | 47 +++++++++++++++++-- src/App/App.csproj | 1 + src/App/Controls/ExtendedViewCell.cs | 28 ++++++++++- src/App/Controls/LabeledDetailCell.cs | 38 +++++++++++++++ src/App/Pages/SettingsPage.cs | 8 ++-- src/App/Pages/VaultListSitesPage.cs | 12 ++--- src/iOS/Controls/CustomButtonRenderer.cs | 40 ++++++++++++++++ src/iOS/Controls/CustomLabelRenderer.cs | 4 +- src/iOS/Controls/ExtendedEntryRenderer.cs | 3 +- src/iOS/Controls/ExtendedViewCellRenderer.cs | 26 ++++++++++ src/iOS/iOS.csproj | 1 + 12 files changed, 206 insertions(+), 30 deletions(-) create mode 100644 src/App/Controls/LabeledDetailCell.cs create mode 100644 src/iOS/Controls/CustomButtonRenderer.cs diff --git a/src/Android/Controls/ExtendedTextCellRenderer.cs b/src/Android/Controls/ExtendedTextCellRenderer.cs index 8e68fa4a5..8c204081c 100644 --- a/src/Android/Controls/ExtendedTextCellRenderer.cs +++ b/src/Android/Controls/ExtendedTextCellRenderer.cs @@ -43,6 +43,20 @@ namespace Bit.Android.Controls return View; } + protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args) + { + base.OnCellPropertyChanged(sender, args); + + var cell = (ExtendedTextCell)Cell; + + if(args.PropertyName == ExtendedTextCell.BackgroundColorProperty.PropertyName) + { + View.SetBackgroundColor(cell.BackgroundColor.ToAndroid()); + } + + // TODO: other properties + } + private class DisclosureImage : ImageView { private ExtendedTextCell _cell; @@ -66,19 +80,5 @@ namespace Bit.Android.Controls return true; } } - - protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args) - { - base.OnCellPropertyChanged(sender, args); - - var cell = (ExtendedTextCell)Cell; - - if(args.PropertyName == ExtendedTextCell.BackgroundColorProperty.PropertyName) - { - View.SetBackgroundColor(cell.BackgroundColor.ToAndroid()); - } - - // TODO: other properties - } } } diff --git a/src/Android/Controls/ExtendedViewCellRenderer.cs b/src/Android/Controls/ExtendedViewCellRenderer.cs index 0126f29e3..dcac0eb3a 100644 --- a/src/Android/Controls/ExtendedViewCellRenderer.cs +++ b/src/Android/Controls/ExtendedViewCellRenderer.cs @@ -6,6 +6,7 @@ using Bit.App.Controls; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using AView = Android.Views.View; +using Android.Widget; [assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))] namespace Bit.Android.Controls @@ -16,12 +17,28 @@ namespace Bit.Android.Controls protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context) { - var View = base.GetCellCore(item, convertView, parent, context); + var View = (BaseCellView)base.GetCellCore(item, convertView, parent, context); var extendedCell = (ExtendedViewCell)item; if(View != null) { View.SetBackgroundColor(extendedCell.BackgroundColor.ToAndroid()); + + + if(extendedCell.ShowDisclousure) + { + var resourceId = Resource.Drawable.ion_chevron_right; + if(!string.IsNullOrWhiteSpace(extendedCell.DisclousureImage)) + { + var fileName = System.IO.Path.GetFileNameWithoutExtension(extendedCell.DisclousureImage); + resourceId = context.Resources.GetIdentifier(fileName, "drawable", context.PackageName); + } + + var image = new DisclosureImage(context, extendedCell); + image.SetImageResource(resourceId); + image.SetPadding(10, 10, 30, 10); + View.SetAccessoryView(image); + } } return View; @@ -31,12 +48,36 @@ namespace Bit.Android.Controls { base.OnCellPropertyChanged(sender, args); - var cell = (ExtendedTextCell)Cell; + var cell = (ExtendedViewCell)Cell; - if(args.PropertyName == ExtendedTextCell.BackgroundColorProperty.PropertyName) + if(args.PropertyName == ExtendedViewCell.BackgroundColorProperty.PropertyName) { View.SetBackgroundColor(cell.BackgroundColor.ToAndroid()); } } + + private class DisclosureImage : ImageView + { + private ExtendedViewCell _cell; + + public DisclosureImage(Context context, ExtendedViewCell cell) : base(context) + { + _cell = cell; + } + + public override bool OnTouchEvent(MotionEvent e) + { + switch(e.Action) + { + case MotionEventActions.Up: + _cell.OnDisclousureTapped(); + break; + default: + break; + } + + return true; + } + } } } diff --git a/src/App/App.csproj b/src/App/App.csproj index cae22593c..32e81f426 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -62,6 +62,7 @@ + diff --git a/src/App/Controls/ExtendedViewCell.cs b/src/App/Controls/ExtendedViewCell.cs index bfbe43703..74eafb136 100644 --- a/src/App/Controls/ExtendedViewCell.cs +++ b/src/App/Controls/ExtendedViewCell.cs @@ -1,4 +1,5 @@ -using Xamarin.Forms; +using System; +using Xamarin.Forms; namespace Bit.App.Controls { @@ -7,10 +8,35 @@ namespace Bit.App.Controls public static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedTextCell), Color.White); + public static readonly BindableProperty ShowDisclousureProperty = + BindableProperty.Create(nameof(DisclousureImage), typeof(bool), typeof(ExtendedTextCell), false); + + public static readonly BindableProperty DisclousureImageProperty = + BindableProperty.Create(nameof(DisclousureImage), typeof(string), typeof(ExtendedTextCell), string.Empty); + public Color BackgroundColor { get { return (Color)GetValue(BackgroundColorProperty); } set { SetValue(BackgroundColorProperty, value); } } + + public bool ShowDisclousure + { + get { return (bool)GetValue(ShowDisclousureProperty); } + set { SetValue(ShowDisclousureProperty, value); } + } + + public string DisclousureImage + { + get { return (string)GetValue(DisclousureImageProperty); } + set { SetValue(DisclousureImageProperty, value); } + } + + public event EventHandler DisclousureTapped; + + public void OnDisclousureTapped() + { + DisclousureTapped?.Invoke(this, EventArgs.Empty); + } } } diff --git a/src/App/Controls/LabeledDetailCell.cs b/src/App/Controls/LabeledDetailCell.cs new file mode 100644 index 000000000..6fd7207ce --- /dev/null +++ b/src/App/Controls/LabeledDetailCell.cs @@ -0,0 +1,38 @@ +using Xamarin.Forms; + +namespace Bit.App.Controls +{ + public class LabeledDetailCell : ExtendedViewCell + { + public LabeledDetailCell() + { + Label = new Label + { + VerticalOptions = LayoutOptions.CenterAndExpand, + LineBreakMode = LineBreakMode.TailTruncation + }; + + Detail = new Label + { + FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)), + LineBreakMode = LineBreakMode.TailTruncation, + VerticalOptions = LayoutOptions.End, + Style = (Style)Application.Current.Resources["text-muted"], + }; + + var stackLayout = new StackLayout + { + Padding = new Thickness(15, 5), + HorizontalOptions = LayoutOptions.FillAndExpand, + VerticalOptions = LayoutOptions.FillAndExpand, + Children = { Label, Detail }, + Spacing = 0 + }; + + View = stackLayout; + } + + public Label Label { get; private set; } + public Label Detail { get; private set; } + } +} diff --git a/src/App/Pages/SettingsPage.cs b/src/App/Pages/SettingsPage.cs index dad582648..05f1d784d 100644 --- a/src/App/Pages/SettingsPage.cs +++ b/src/App/Pages/SettingsPage.cs @@ -87,6 +87,7 @@ namespace Bit.App.Pages { EnableScrolling = true, Intent = TableIntent.Menu, + HasUnevenRows = true, Root = new TableRoot { new TableSection("Security") @@ -108,10 +109,11 @@ namespace Bit.App.Pages } }; - var scrollView = new ScrollView + if( Device.OS == TargetPlatform.iOS ) { - Content = table - }; + table.RowHeight = -1; + table.EstimatedRowHeight = 44; + } Title = AppResources.Settings; Content = table; diff --git a/src/App/Pages/VaultListSitesPage.cs b/src/App/Pages/VaultListSitesPage.cs index e23aa6970..f3bf969fa 100644 --- a/src/App/Pages/VaultListSitesPage.cs +++ b/src/App/Pages/VaultListSitesPage.cs @@ -179,7 +179,7 @@ namespace Bit.App.Pages } } - private class VaultListViewCell : ExtendedTextCell + private class VaultListViewCell : LabeledDetailCell { private VaultListSitesPage _page; @@ -196,9 +196,9 @@ namespace Bit.App.Pages moreAction.SetBinding(MenuItem.CommandParameterProperty, new Binding(".")); moreAction.Clicked += MoreAction_Clicked; - SetBinding(CommandParameterProperty, new Binding(".")); - this.SetBinding(TextProperty, s => s.Name); - this.SetBinding(DetailProperty, s => s.Username); + //SetBinding(CommandParameterProperty, new Binding(".")); + Label.SetBinding(Label.TextProperty, s => s.Name); + Detail.SetBinding(Label.TextProperty, s => s.Username); ContextActions.Add(deleteAction); ContextActions.Add(moreAction); @@ -218,8 +218,8 @@ namespace Bit.App.Pages private void VaultListViewCell_DisclousureTapped(object sender, EventArgs e) { var cell = sender as VaultListViewCell; - var site = cell.CommandParameter as VaultListPageModel.Site; - _page.MoreClickedAsync(site); + //var site = cell.CommandParameter as VaultListPageModel.Site; + // _page.MoreClickedAsync(site); } } diff --git a/src/iOS/Controls/CustomButtonRenderer.cs b/src/iOS/Controls/CustomButtonRenderer.cs new file mode 100644 index 000000000..ce71a878c --- /dev/null +++ b/src/iOS/Controls/CustomButtonRenderer.cs @@ -0,0 +1,40 @@ +using System; +using Bit.iOS.Controls; +using UIKit; +using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; + +[assembly: ExportRenderer(typeof(Button), typeof(CustomButtonRenderer))] +namespace Bit.iOS.Controls +{ + public class CustomButtonRenderer : ButtonRenderer + { + protected override void OnElementChanged(ElementChangedEventArgs