summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/Cells
diff options
context:
space:
mode:
authorJason Smith <jason.smith@xamarin.com>2016-03-22 13:02:25 -0700
committerJason Smith <jason.smith@xamarin.com>2016-03-22 16:13:41 -0700
commit17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch)
treeb5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.Android/Cells
downloadxamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.Android/Cells')
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/BaseCellView.cs208
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/CellFactory.cs41
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/CellRenderer.cs131
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/EntryCellEditText.cs45
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/EntryCellRenderer.cs119
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/EntryCellView.cs145
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/ImageCellRenderer.cs37
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/SwitchCellRenderer.cs55
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/SwitchCellView.cs25
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/TextCellRenderer.cs78
-rw-r--r--Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs178
11 files changed, 1062 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.Android/Cells/BaseCellView.cs b/Xamarin.Forms.Platform.Android/Cells/BaseCellView.cs
new file mode 100644
index 00000000..7855b01e
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/BaseCellView.cs
@@ -0,0 +1,208 @@
+using System.IO;
+using System.Threading.Tasks;
+using Android.Content;
+using Android.Graphics;
+using Android.Text;
+using Android.Views;
+using Android.Widget;
+using AView = Android.Views.View;
+using AColor = Android.Graphics.Color;
+using AColorDraw = Android.Graphics.Drawables.ColorDrawable;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class BaseCellView : LinearLayout, INativeElementView
+ {
+ public const double DefaultMinHeight = 44;
+
+ readonly Color _androidDefaultTextColor;
+ readonly Cell _cell;
+ readonly TextView _detailText;
+ readonly ImageView _imageView;
+ readonly TextView _mainText;
+ Color _defaultDetailColor;
+ Color _defaultMainTextColor;
+ Color _detailTextColor;
+ string _detailTextText;
+ ImageSource _imageSource;
+ Color _mainTextColor;
+ string _mainTextText;
+
+ public BaseCellView(Context context, Cell cell) : base(context)
+ {
+ _cell = cell;
+ SetMinimumWidth((int)context.ToPixels(25));
+ SetMinimumHeight((int)context.ToPixels(25));
+ Orientation = Orientation.Horizontal;
+
+ var padding = (int)context.FromPixels(8);
+ SetPadding(padding, padding, padding, padding);
+
+ _imageView = new ImageView(context);
+ var imageParams = new LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.FillParent)
+ {
+ Width = (int)context.ToPixels(60),
+ Height = (int)context.ToPixels(60),
+ RightMargin = 0,
+ Gravity = GravityFlags.Center
+ };
+ using(imageParams)
+ AddView(_imageView, imageParams);
+
+ var textLayout = new LinearLayout(context) { Orientation = Orientation.Vertical };
+
+ _mainText = new TextView(context);
+ _mainText.SetSingleLine(true);
+ _mainText.Ellipsize = TextUtils.TruncateAt.End;
+ _mainText.SetPadding((int)context.ToPixels(15), padding, padding, padding);
+ _mainText.SetTextAppearance(context, global::Android.Resource.Attribute.TextAppearanceListItem);
+ using(var lp = new LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent))
+ textLayout.AddView(_mainText, lp);
+
+ _detailText = new TextView(context);
+ _detailText.SetSingleLine(true);
+ _detailText.Ellipsize = TextUtils.TruncateAt.End;
+ _detailText.SetPadding((int)context.ToPixels(15), padding, padding, padding);
+ _detailText.Visibility = ViewStates.Gone;
+ _detailText.SetTextAppearance(context, global::Android.Resource.Attribute.TextAppearanceListItemSmall);
+ using(var lp = new LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent))
+ textLayout.AddView(_detailText, lp);
+
+ var layoutParams = new LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent) { Width = 0, Weight = 1, Gravity = GravityFlags.Center };
+
+ using(layoutParams)
+ AddView(textLayout, layoutParams);
+
+ SetMinimumHeight((int)context.ToPixels(DefaultMinHeight));
+ _androidDefaultTextColor = Color.FromUint((uint)_mainText.CurrentTextColor);
+ }
+
+ public AView AccessoryView { get; private set; }
+
+ public string DetailText
+ {
+ get { return _detailTextText; }
+ set
+ {
+ if (_detailTextText == value)
+ return;
+
+ _detailTextText = value;
+ _detailText.Text = value;
+ _detailText.Visibility = string.IsNullOrEmpty(value) ? ViewStates.Gone : ViewStates.Visible;
+ }
+ }
+
+ public string MainText
+ {
+ get { return _mainTextText; }
+ set
+ {
+ if (_mainTextText == value)
+ return;
+
+ _mainTextText = value;
+ _mainText.Text = value;
+ }
+ }
+
+ Element INativeElementView.Element
+ {
+ get { return _cell; }
+ }
+
+ public void SetAccessoryView(AView view)
+ {
+ if (AccessoryView != null)
+ RemoveView(AccessoryView);
+
+ if (view != null)
+ {
+ using(var layout = new LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.FillParent))
+ AddView(view, layout);
+
+ AccessoryView = view;
+ }
+ }
+
+ public void SetDefaultMainTextColor(Color defaultColor)
+ {
+ _defaultMainTextColor = defaultColor;
+ if (_mainTextColor == Color.Default)
+ _mainText.SetTextColor(defaultColor.ToAndroid());
+ }
+
+ public void SetDetailTextColor(Color color)
+ {
+ if (_detailTextColor == color)
+ return;
+
+ if (_defaultDetailColor == Color.Default)
+ _defaultDetailColor = Color.FromUint((uint)_detailText.CurrentTextColor);
+
+ _detailTextColor = color;
+ _detailText.SetTextColor(color.ToAndroid(_defaultDetailColor));
+ }
+
+ public void SetImageSource(ImageSource source)
+ {
+ UpdateBitmap(source, _imageSource);
+ _imageSource = source;
+ }
+
+ public void SetImageVisible(bool visible)
+ {
+ _imageView.Visibility = visible ? ViewStates.Visible : ViewStates.Gone;
+ }
+
+ public void SetIsEnabled(bool isEnable)
+ {
+ _mainText.Enabled = isEnable;
+ _detailText.Enabled = isEnable;
+ }
+
+ public void SetMainTextColor(Color color)
+ {
+ Color defaultColorToSet = _defaultMainTextColor == Color.Default ? _androidDefaultTextColor : _defaultMainTextColor;
+
+ _mainTextColor = color;
+ _mainText.SetTextColor(color.ToAndroid(defaultColorToSet));
+ }
+
+ public void SetRenderHeight(double height)
+ {
+ height = Context.ToPixels(height);
+ LayoutParameters = new LayoutParams(ViewGroup.LayoutParams.MatchParent, (int)(height == -1 ? ViewGroup.LayoutParams.WrapContent : height));
+ }
+
+ async void UpdateBitmap(ImageSource source, ImageSource previousSource = null)
+ {
+ if (Equals(source, previousSource))
+ return;
+
+ _imageView.SetImageResource(global::Android.Resource.Color.Transparent);
+
+ Bitmap bitmap = null;
+
+ IImageSourceHandler handler;
+
+ if (source != null && (handler = Registrar.Registered.GetHandler<IImageSourceHandler>(source.GetType())) != null)
+ {
+ try
+ {
+ bitmap = await handler.LoadImageAsync(source, Context);
+ }
+ catch (TaskCanceledException)
+ {
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ _imageView.SetImageBitmap(bitmap);
+ if (bitmap != null)
+ bitmap.Dispose();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/CellFactory.cs b/Xamarin.Forms.Platform.Android/Cells/CellFactory.cs
new file mode 100644
index 00000000..589236c3
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/CellFactory.cs
@@ -0,0 +1,41 @@
+using Android.Content;
+using Android.Views;
+using AView = Android.Views.View;
+using AListView = Android.Widget.ListView;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public static class CellFactory
+ {
+ public static AView GetCell(Cell item, AView convertView, ViewGroup parent, Context context, View view)
+ {
+ CellRenderer renderer = CellRenderer.GetRenderer(item);
+ if (renderer == null)
+ {
+ renderer = Registrar.Registered.GetHandler<CellRenderer>(item.GetType());
+ renderer.ParentView = view;
+ }
+
+ AView result = renderer.GetCell(item, convertView, parent, context);
+
+ if (view is TableView)
+ UpdateMinimumHeightFromParent(context, result, (TableView)view);
+ else if (view is ListView)
+ UpdateMinimumHeightFromParent(context, result, (ListView)view);
+
+ return result;
+ }
+
+ static void UpdateMinimumHeightFromParent(Context context, AView view, TableView table)
+ {
+ if (!table.HasUnevenRows && table.RowHeight > 0)
+ view.SetMinimumHeight((int)context.ToPixels(table.RowHeight));
+ }
+
+ static void UpdateMinimumHeightFromParent(Context context, AView view, ListView listView)
+ {
+ if (!listView.HasUnevenRows && listView.RowHeight > 0)
+ view.SetMinimumHeight((int)context.ToPixels(listView.RowHeight));
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/CellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/CellRenderer.cs
new file mode 100644
index 00000000..d9d4eee5
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/CellRenderer.cs
@@ -0,0 +1,131 @@
+using System;
+using System.ComponentModel;
+using Android.Content;
+using Android.Views;
+using Android.Widget;
+using AView = Android.Views.View;
+using Object = Java.Lang.Object;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class CellRenderer : IRegisterable
+ {
+ static readonly PropertyChangedEventHandler PropertyChangedHandler = OnGlobalCellPropertyChanged;
+
+ static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(CellRenderer), typeof(Cell), null);
+
+ EventHandler _onForceUpdateSizeRequested;
+
+ public View ParentView { get; set; }
+
+ protected Cell Cell { get; set; }
+
+ public AView GetCell(Cell item, AView convertView, ViewGroup parent, Context context)
+ {
+ Performance.Start();
+
+ Cell = item;
+ Cell.PropertyChanged -= PropertyChangedHandler;
+
+ SetRenderer(Cell, this);
+
+ if (convertView != null)
+ {
+ Object tag = convertView.Tag;
+ var renderHolder = tag as RendererHolder;
+ if (renderHolder != null)
+ {
+ Cell oldCell = renderHolder.Renderer.Cell;
+ oldCell.SendDisappearing();
+
+ if (Cell != oldCell)
+ SetRenderer(oldCell, null);
+ }
+ }
+
+ AView view = GetCellCore(item, convertView, parent, context);
+
+ WireUpForceUpdateSizeRequested(item, view);
+
+ var holder = view.Tag as RendererHolder;
+ if (holder == null)
+ view.Tag = new RendererHolder { Renderer = this };
+ else
+ holder.Renderer = this;
+
+ Cell.PropertyChanged += PropertyChangedHandler;
+ Cell.SendAppearing();
+
+ Performance.Stop();
+
+ return view;
+ }
+
+ protected virtual AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
+ {
+ Performance.Start();
+
+ LayoutInflater inflater = LayoutInflater.FromContext(context);
+ const int type = global::Android.Resource.Layout.SimpleListItem1;
+ AView view = inflater.Inflate(type, null);
+
+ var textView = view.FindViewById<TextView>(global::Android.Resource.Id.Text1);
+ textView.Text = item.ToString();
+ textView.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
+ view.SetBackgroundColor(global::Android.Graphics.Color.Black);
+
+ Performance.Stop();
+
+ return view;
+ }
+
+ protected virtual void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ }
+
+ protected void WireUpForceUpdateSizeRequested(Cell cell, AView nativeCell)
+ {
+ cell.ForceUpdateSizeRequested -= _onForceUpdateSizeRequested;
+
+ _onForceUpdateSizeRequested = delegate
+ {
+ // RenderHeight may not be changed, but that's okay, since we
+ // don't actually use the height argument in the OnMeasure override.
+ nativeCell.Measure(nativeCell.Width, (int)cell.RenderHeight);
+ nativeCell.SetMinimumHeight(nativeCell.MeasuredHeight);
+ nativeCell.SetMinimumWidth(nativeCell.MeasuredWidth);
+ };
+
+ cell.ForceUpdateSizeRequested += _onForceUpdateSizeRequested;
+ }
+
+ internal static CellRenderer GetRenderer(BindableObject cell)
+ {
+ return (CellRenderer)cell.GetValue(RendererProperty);
+ }
+
+ internal static void SetRenderer(BindableObject cell, CellRenderer renderer)
+ {
+ cell.SetValue(RendererProperty, renderer);
+ }
+
+ static void OnGlobalCellPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ var cell = (Cell)sender;
+ CellRenderer renderer = GetRenderer(cell);
+ if (renderer == null)
+ {
+ cell.PropertyChanged -= PropertyChangedHandler;
+ return;
+ }
+
+ renderer.OnCellPropertyChanged(sender, e);
+ ;
+ }
+
+ class RendererHolder : Object
+ {
+ public CellRenderer Renderer;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/EntryCellEditText.cs b/Xamarin.Forms.Platform.Android/Cells/EntryCellEditText.cs
new file mode 100644
index 00000000..287804ba
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/EntryCellEditText.cs
@@ -0,0 +1,45 @@
+using System;
+using Android.App;
+using Android.Content;
+using Android.Graphics;
+using Android.Views;
+using Android.Widget;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public sealed class EntryCellEditText : EditText
+ {
+ SoftInput _startingMode;
+
+ public EntryCellEditText(Context context) : base(context)
+ {
+ }
+
+ public override bool OnKeyPreIme(Keycode keyCode, KeyEvent e)
+ {
+ if (keyCode == Keycode.Back && e.Action == KeyEventActions.Down)
+ {
+ EventHandler handler = BackButtonPressed;
+ if (handler != null)
+ handler(this, EventArgs.Empty);
+ }
+ return base.OnKeyPreIme(keyCode, e);
+ }
+
+ protected override void OnFocusChanged(bool gainFocus, FocusSearchDirection direction, Rect previouslyFocusedRect)
+ {
+ Window window = ((Activity)Context).Window;
+ if (gainFocus)
+ {
+ _startingMode = window.Attributes.SoftInputMode;
+ window.SetSoftInputMode(SoftInput.AdjustPan);
+ }
+ else
+ window.SetSoftInputMode(_startingMode);
+
+ base.OnFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ }
+
+ internal event EventHandler BackButtonPressed;
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/EntryCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/EntryCellRenderer.cs
new file mode 100644
index 00000000..00330928
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/EntryCellRenderer.cs
@@ -0,0 +1,119 @@
+using System.ComponentModel;
+using Android.Content;
+using Android.Views;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class EntryCellRenderer : CellRenderer
+ {
+ EntryCellView _view;
+
+ protected override global::Android.Views.View GetCellCore(Cell item, global::Android.Views.View convertView, ViewGroup parent, Context context)
+ {
+ if ((_view = convertView as EntryCellView) == null)
+ _view = new EntryCellView(context, item);
+ else
+ {
+ _view.TextChanged = null;
+ _view.FocusChanged = null;
+ _view.EditingCompleted = null;
+ }
+
+ UpdateLabel();
+ UpdateLabelColor();
+ UpdatePlaceholder();
+ UpdateKeyboard();
+ UpdateHorizontalTextAlignment();
+ UpdateText();
+ UpdateIsEnabled();
+ UpdateHeight();
+
+ _view.TextChanged = OnTextChanged;
+ _view.EditingCompleted = OnEditingCompleted;
+
+ return _view;
+ }
+
+ protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnCellPropertyChanged(sender, e);
+
+ if (e.PropertyName == EntryCell.LabelProperty.PropertyName)
+ UpdateLabel();
+ else if (e.PropertyName == EntryCell.TextProperty.PropertyName)
+ UpdateText();
+ else if (e.PropertyName == EntryCell.PlaceholderProperty.PropertyName)
+ UpdatePlaceholder();
+ else if (e.PropertyName == EntryCell.KeyboardProperty.PropertyName)
+ UpdateKeyboard();
+ else if (e.PropertyName == EntryCell.LabelColorProperty.PropertyName)
+ UpdateLabelColor();
+ else if (e.PropertyName == EntryCell.HorizontalTextAlignmentProperty.PropertyName)
+ UpdateHorizontalTextAlignment();
+ else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName)
+ UpdateIsEnabled();
+ else if (e.PropertyName == "RenderHeight")
+ UpdateHeight();
+ }
+
+ void OnEditingCompleted()
+ {
+ var entryCell = (EntryCell)Cell;
+ entryCell.SendCompleted();
+ }
+
+ void OnTextChanged(string text)
+ {
+ var entryCell = (EntryCell)Cell;
+ entryCell.Text = text;
+ }
+
+ void UpdateHeight()
+ {
+ _view.SetRenderHeight(Cell.RenderHeight);
+ }
+
+ void UpdateHorizontalTextAlignment()
+ {
+ var entryCell = (EntryCell)Cell;
+ _view.EditText.Gravity = entryCell.HorizontalTextAlignment.ToHorizontalGravityFlags();
+ }
+
+ void UpdateIsEnabled()
+ {
+ var entryCell = (EntryCell)Cell;
+ _view.EditText.Enabled = entryCell.IsEnabled;
+ }
+
+ void UpdateKeyboard()
+ {
+ var entryCell = (EntryCell)Cell;
+ _view.EditText.InputType = entryCell.Keyboard.ToInputType();
+ }
+
+ void UpdateLabel()
+ {
+ _view.LabelText = ((EntryCell)Cell).Label;
+ }
+
+ void UpdateLabelColor()
+ {
+ _view.SetLabelTextColor(((EntryCell)Cell).LabelColor, global::Android.Resource.Color.PrimaryTextDark);
+ }
+
+ void UpdatePlaceholder()
+ {
+ var entryCell = (EntryCell)Cell;
+ _view.EditText.Hint = entryCell.Placeholder;
+ }
+
+ void UpdateText()
+ {
+ var entryCell = (EntryCell)Cell;
+ if (_view.EditText.Text == entryCell.Text)
+ return;
+
+ _view.EditText.Text = entryCell.Text;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/EntryCellView.cs b/Xamarin.Forms.Platform.Android/Cells/EntryCellView.cs
new file mode 100644
index 00000000..c0206f1e
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/EntryCellView.cs
@@ -0,0 +1,145 @@
+using System;
+using Android.Content;
+using Android.Text;
+using Android.Views;
+using Android.Views.InputMethods;
+using Android.Widget;
+using Java.Lang;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public sealed class EntryCellView : LinearLayout, ITextWatcher, global::Android.Views.View.IOnFocusChangeListener, TextView.IOnEditorActionListener, INativeElementView
+ {
+ public const double DefaultMinHeight = 55;
+
+ readonly Cell _cell;
+ readonly TextView _label;
+
+ Color _labelTextColor;
+ string _labelTextText;
+
+ public EntryCellView(Context context, Cell cell) : base(context)
+ {
+ _cell = cell;
+ SetMinimumWidth((int)context.ToPixels(50));
+ SetMinimumHeight((int)context.ToPixels(85));
+ Orientation = Orientation.Horizontal;
+
+ var padding = (int)context.ToPixels(8);
+ SetPadding((int)context.ToPixels(15), padding, padding, padding);
+
+ _label = new TextView(context);
+ _label.SetTextAppearance(context, global::Android.Resource.Attribute.TextAppearanceListItem);
+
+ var layoutParams = new LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) { Gravity = GravityFlags.CenterVertical };
+ using(layoutParams)
+ AddView(_label, layoutParams);
+
+ EditText = new EntryCellEditText(context);
+ EditText.AddTextChangedListener(this);
+ EditText.OnFocusChangeListener = this;
+ EditText.SetOnEditorActionListener(this);
+ EditText.ImeOptions = ImeAction.Done;
+ EditText.BackButtonPressed += OnBackButtonPressed;
+ //editText.SetBackgroundDrawable (null);
+ layoutParams = new LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent) { Width = 0, Weight = 1, Gravity = GravityFlags.FillHorizontal | GravityFlags.Center };
+ using(layoutParams)
+ AddView(EditText, layoutParams);
+ }
+
+ public Action EditingCompleted { get; set; }
+
+ public EntryCellEditText EditText { get; }
+
+ public Action<bool> FocusChanged { get; set; }
+
+ public string LabelText
+ {
+ get { return _labelTextText; }
+ set
+ {
+ if (_labelTextText == value)
+ return;
+
+ _labelTextText = value;
+ _label.Text = value;
+ }
+ }
+
+ public Action<string> TextChanged { get; set; }
+
+ public Element Element
+ {
+ get { return _cell; }
+ }
+
+ bool TextView.IOnEditorActionListener.OnEditorAction(TextView v, ImeAction actionId, KeyEvent e)
+ {
+ if (actionId == ImeAction.Done)
+ {
+ OnKeyboardDoneButtonPressed(EditText, EventArgs.Empty);
+ EditText.ClearFocus();
+ v.HideKeyboard();
+ }
+
+ // Fire Completed and dismiss keyboard for hardware / physical keyboards
+ if (actionId == ImeAction.ImeNull && e.KeyCode == Keycode.Enter)
+ {
+ OnKeyboardDoneButtonPressed(EditText, EventArgs.Empty);
+ EditText.ClearFocus();
+ v.HideKeyboard();
+ }
+
+ return true;
+ }
+
+ void IOnFocusChangeListener.OnFocusChange(global::Android.Views.View view, bool hasFocus)
+ {
+ Action<bool> focusChanged = FocusChanged;
+ if (focusChanged != null)
+ focusChanged(hasFocus);
+ }
+
+ void ITextWatcher.AfterTextChanged(IEditable s)
+ {
+ }
+
+ void ITextWatcher.BeforeTextChanged(ICharSequence s, int start, int count, int after)
+ {
+ }
+
+ void ITextWatcher.OnTextChanged(ICharSequence s, int start, int before, int count)
+ {
+ Action<string> changed = TextChanged;
+ if (changed != null)
+ changed(s != null ? s.ToString() : null);
+ }
+
+ public void SetLabelTextColor(Color color, int defaultColorResourceId)
+ {
+ if (_labelTextColor == color)
+ return;
+
+ _labelTextColor = color;
+ _label.SetTextColor(color.ToAndroid(defaultColorResourceId));
+ }
+
+ public void SetRenderHeight(double height)
+ {
+ SetMinimumHeight((int)Context.ToPixels(height == -1 ? DefaultMinHeight : height));
+ }
+
+ void OnBackButtonPressed(object sender, EventArgs e)
+ {
+ // TODO Clear focus
+ }
+
+ void OnKeyboardDoneButtonPressed(object sender, EventArgs e)
+ {
+ // TODO Clear focus
+ Action editingCompleted = EditingCompleted;
+ if (editingCompleted != null)
+ editingCompleted();
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/ImageCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/ImageCellRenderer.cs
new file mode 100644
index 00000000..62815ed6
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/ImageCellRenderer.cs
@@ -0,0 +1,37 @@
+using System.ComponentModel;
+using Android.Content;
+using Android.Views;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class ImageCellRenderer : TextCellRenderer
+ {
+ protected override global::Android.Views.View GetCellCore(Cell item, global::Android.Views.View convertView, ViewGroup parent, Context context)
+ {
+ var result = (BaseCellView)base.GetCellCore(item, convertView, parent, context);
+
+ UpdateImage();
+
+ return result;
+ }
+
+ protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
+ {
+ base.OnCellPropertyChanged(sender, args);
+ if (args.PropertyName == ImageCell.ImageSourceProperty.PropertyName)
+ UpdateImage();
+ }
+
+ void UpdateImage()
+ {
+ var cell = (ImageCell)Cell;
+ if (cell.ImageSource != null)
+ {
+ View.SetImageVisible(true);
+ View.SetImageSource(cell.ImageSource);
+ }
+ else
+ View.SetImageVisible(false);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/SwitchCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/SwitchCellRenderer.cs
new file mode 100644
index 00000000..bba9d260
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/SwitchCellRenderer.cs
@@ -0,0 +1,55 @@
+using System.ComponentModel;
+using Android.Content;
+using Android.Views;
+using AView = Android.Views.View;
+using ASwitch = Android.Widget.Switch;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class SwitchCellRenderer : CellRenderer
+ {
+ const double DefaultHeight = 30;
+ SwitchCellView _view;
+
+ protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
+ {
+ var cell = (SwitchCell)Cell;
+
+ if ((_view = convertView as SwitchCellView) == null)
+ _view = new SwitchCellView(context, item);
+
+ _view.Cell = cell;
+
+ UpdateText();
+ UpdateChecked();
+ UpdateHeight();
+
+ return _view;
+ }
+
+ protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
+ {
+ if (args.PropertyName == SwitchCell.TextProperty.PropertyName)
+ UpdateText();
+ else if (args.PropertyName == SwitchCell.OnProperty.PropertyName)
+ UpdateChecked();
+ else if (args.PropertyName == "RenderHeight")
+ UpdateHeight();
+ }
+
+ void UpdateChecked()
+ {
+ ((ASwitch)_view.AccessoryView).Checked = ((SwitchCell)Cell).On;
+ }
+
+ void UpdateHeight()
+ {
+ _view.SetRenderHeight(Cell.RenderHeight);
+ }
+
+ void UpdateText()
+ {
+ _view.MainText = ((SwitchCell)Cell).Text;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/SwitchCellView.cs b/Xamarin.Forms.Platform.Android/Cells/SwitchCellView.cs
new file mode 100644
index 00000000..f15c41b0
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/SwitchCellView.cs
@@ -0,0 +1,25 @@
+using Android.Content;
+using Android.Widget;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class SwitchCellView : BaseCellView, CompoundButton.IOnCheckedChangeListener
+ {
+ public SwitchCellView(Context context, Cell cell) : base(context, cell)
+ {
+ var sw = new global::Android.Widget.Switch(context);
+ sw.SetOnCheckedChangeListener(this);
+
+ SetAccessoryView(sw);
+
+ SetImageVisible(false);
+ }
+
+ public SwitchCell Cell { get; set; }
+
+ public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
+ {
+ Cell.On = isChecked;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/TextCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/TextCellRenderer.cs
new file mode 100644
index 00000000..cbaaa2b7
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/TextCellRenderer.cs
@@ -0,0 +1,78 @@
+using System.ComponentModel;
+using Android.Content;
+using Android.Views;
+using AView = Android.Views.View;
+using AColor = Android.Graphics.Color;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class TextCellRenderer : CellRenderer
+ {
+ internal TextCellView View { get; private set; }
+
+ protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
+ {
+ if ((View = convertView as TextCellView) == null)
+ View = new TextCellView(context, item);
+
+ UpdateMainText();
+ UpdateDetailText();
+ UpdateHeight();
+ UpdateIsEnabled();
+ View.SetImageVisible(false);
+
+ return View;
+ }
+
+ protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
+ {
+ if (args.PropertyName == TextCell.TextProperty.PropertyName || args.PropertyName == TextCell.TextColorProperty.PropertyName)
+ UpdateMainText();
+ else if (args.PropertyName == TextCell.DetailProperty.PropertyName || args.PropertyName == TextCell.DetailColorProperty.PropertyName)
+ UpdateDetailText();
+ else if (args.PropertyName == Cell.IsEnabledProperty.PropertyName)
+ UpdateIsEnabled();
+ else if (args.PropertyName == "RenderHeight")
+ UpdateHeight();
+ }
+
+ void UpdateDetailText()
+ {
+ var cell = (TextCell)Cell;
+ View.DetailText = cell.Detail;
+ View.SetDetailTextColor(cell.DetailColor);
+ }
+
+ void UpdateHeight()
+ {
+ View.SetRenderHeight(Cell.RenderHeight);
+ }
+
+ void UpdateIsEnabled()
+ {
+ var cell = (TextCell)Cell;
+ View.SetIsEnabled(cell.IsEnabled);
+ }
+
+ void UpdateMainText()
+ {
+ var cell = (TextCell)Cell;
+ View.MainText = cell.Text;
+
+ if (!TemplatedItemsList<ItemsView<Cell>, Cell>.GetIsGroupHeader(cell))
+ View.SetDefaultMainTextColor(Color.Accent);
+ else
+ View.SetDefaultMainTextColor(Color.Default);
+
+ View.SetMainTextColor(cell.TextColor);
+ }
+
+ // ensure we don't get other people's BaseCellView's
+ internal class TextCellView : BaseCellView
+ {
+ public TextCellView(Context context, Cell cell) : base(context, cell)
+ {
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs
new file mode 100644
index 00000000..4bf83395
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs
@@ -0,0 +1,178 @@
+using Android.Content;
+using Android.Views;
+using AView = Android.Views.View;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class ViewCellRenderer : CellRenderer
+ {
+ protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
+ {
+ Performance.Start();
+ var cell = (ViewCell)item;
+
+ var container = convertView as ViewCellContainer;
+ if (container != null)
+ {
+ container.Update(cell);
+ Performance.Stop();
+ return container;
+ }
+
+ BindableProperty unevenRows = null, rowHeight = null;
+ if (ParentView is TableView)
+ {
+ unevenRows = TableView.HasUnevenRowsProperty;
+ rowHeight = TableView.RowHeightProperty;
+ }
+ else if (ParentView is ListView)
+ {
+ unevenRows = ListView.HasUnevenRowsProperty;
+ rowHeight = ListView.RowHeightProperty;
+ }
+
+ IVisualElementRenderer view = Platform.CreateRenderer(cell.View);
+ Platform.SetRenderer(cell.View, view);
+ cell.View.IsPlatformEnabled = true;
+ var c = new ViewCellContainer(context, view, cell, ParentView, unevenRows, rowHeight);
+
+ Performance.Stop();
+
+ return c;
+ }
+
+ internal class ViewCellContainer : ViewGroup, INativeElementView
+ {
+ readonly View _parent;
+ readonly BindableProperty _rowHeight;
+ readonly BindableProperty _unevenRows;
+ IVisualElementRenderer _view;
+ ViewCell _viewCell;
+
+ public ViewCellContainer(Context context, IVisualElementRenderer view, ViewCell viewCell, View parent, BindableProperty unevenRows, BindableProperty rowHeight) : base(context)
+ {
+ _view = view;
+ _parent = parent;
+ _unevenRows = unevenRows;
+ _rowHeight = rowHeight;
+ _viewCell = viewCell;
+ AddView(view.ViewGroup);
+ UpdateIsEnabled();
+ }
+
+ protected bool ParentHasUnevenRows
+ {
+ get { return (bool)_parent.GetValue(_unevenRows); }
+ }
+
+ protected int ParentRowHeight
+ {
+ get { return (int)_parent.GetValue(_rowHeight); }
+ }
+
+ public Element Element
+ {
+ get { return _viewCell; }
+ }
+
+ public override bool OnInterceptTouchEvent(MotionEvent ev)
+ {
+ if (!Enabled)
+ return true;
+ return base.OnInterceptTouchEvent(ev);
+ }
+
+ public void Update(ViewCell cell)
+ {
+ Performance.Start();
+
+ var renderer = GetChildAt(0) as IVisualElementRenderer;
+ var viewHandlerType = Registrar.Registered.GetHandlerType(cell.View.GetType()) ?? typeof(Platform.DefaultRenderer);
+ if (renderer != null && renderer.GetType() == viewHandlerType)
+ {
+ Performance.Start("Reuse");
+ _viewCell = cell;
+
+ cell.View.DisableLayout = true;
+ foreach (VisualElement c in cell.View.Descendants())
+ c.DisableLayout = true;
+
+ Performance.Start("Reuse.SetElement");
+ renderer.SetElement(cell.View);
+ Performance.Stop("Reuse.SetElement");
+
+ Platform.SetRenderer(cell.View, _view);
+
+ cell.View.DisableLayout = false;
+ foreach (VisualElement c in cell.View.Descendants())
+ c.DisableLayout = false;
+
+ var viewAsLayout = cell.View as Layout;
+ if (viewAsLayout != null)
+ viewAsLayout.ForceLayout();
+
+ Invalidate();
+
+ Performance.Stop("Reuse");
+ Performance.Stop();
+ return;
+ }
+
+ RemoveView(_view.ViewGroup);
+ Platform.SetRenderer(_viewCell.View, null);
+ _viewCell.View.IsPlatformEnabled = false;
+ _view.ViewGroup.Dispose();
+
+ _viewCell = cell;
+ _view = Platform.CreateRenderer(_viewCell.View);
+
+ Platform.SetRenderer(_viewCell.View, _view);
+ AddView(_view.ViewGroup);
+
+ UpdateIsEnabled();
+
+ Performance.Stop();
+ }
+
+ public void UpdateIsEnabled()
+ {
+ Enabled = _viewCell.IsEnabled;
+ }
+
+ protected override void OnLayout(bool changed, int l, int t, int r, int b)
+ {
+ Performance.Start();
+
+ double width = Context.FromPixels(r - l);
+ double height = Context.FromPixels(b - t);
+
+ Performance.Start("Element.Layout");
+ Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(_view.Element, new Rectangle(0, 0, width, height));
+ Performance.Stop("Element.Layout");
+
+ _view.UpdateLayout();
+ Performance.Stop();
+ }
+
+ protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
+ {
+ Performance.Start();
+
+ int width = MeasureSpec.GetSize(widthMeasureSpec);
+ int height;
+
+ if (ParentHasUnevenRows)
+ {
+ SizeRequest measure = _view.Element.Measure(Context.FromPixels(width), double.PositiveInfinity, MeasureFlags.IncludeMargins);
+ height = (int)Context.ToPixels(_viewCell.Height > 0 ? _viewCell.Height : measure.Request.Height);
+ }
+ else
+ height = (int)Context.ToPixels(ParentRowHeight == -1 ? BaseCellView.DefaultMinHeight : ParentRowHeight);
+
+ SetMeasuredDimension(width, height);
+
+ Performance.Stop();
+ }
+ }
+ }
+} \ No newline at end of file