remove boxedview

This commit is contained in:
Kyle Spearrin 2019-05-30 22:09:28 -04:00
parent 68a85a2561
commit 4dd05cf10e
9 changed files with 0 additions and 1770 deletions

View file

@ -126,16 +126,8 @@
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
<Compile Include="Services\AndroidPushNotificationService.cs" />
<Compile Include="SplashActivity.cs" />
<Compile Include="Renderers\BoxedView\BoxedViewRecyclerAdapter.cs" />
<Compile Include="Renderers\BoxedView\BoxedViewRenderer.cs" />
<Compile Include="Renderers\BoxedView\BoxedViewSimpleCallback.cs" />
<Compile Include="Renderers\BoxedView\Cells\BaseCellRenderer.cs" />
<Compile Include="Renderers\BoxedView\Cells\BaseCellView.cs" />
<Compile Include="Renderers\BoxedView\Cells\EntryCellRenderer.cs" />
<Compile Include="Renderers\BoxedView\Cells\LabelCellRenderer.cs" />
<Compile Include="MainApplication.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="Renderers\RendererUtils.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\CryptoPrimitiveService.cs" />

View file

@ -1,526 +0,0 @@
using Android.Content;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Text;
using Android.Views;
using Android.Widget;
using Bit.App.Controls.BoxedView;
using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View;
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class BoxedViewRecyclerAdapter : RecyclerView.Adapter, AView.IOnClickListener
{
private const int ViewTypeHeader = 0;
private const int ViewTypeFooter = 1;
private Dictionary<Type, int> _viewTypes;
private List<CellCache> _cellCaches;
internal List<CellCache> CellCaches
{
get
{
if(_cellCaches == null)
{
FillCache();
}
return _cellCaches;
}
}
// Item click. correspond to AdapterView.IOnItemClickListener
private int _selectedIndex = -1;
private AView _preSelectedCell = null;
Context _context;
App.Controls.BoxedView.BoxedView _boxedView;
RecyclerView _recyclerView;
List<ViewHolder> _viewHolders = new List<ViewHolder>();
public BoxedViewRecyclerAdapter(Context context, App.Controls.BoxedView.BoxedView boxedView,
RecyclerView recyclerView)
{
_context = context;
_boxedView = boxedView;
_recyclerView = recyclerView;
_boxedView.ModelChanged += BoxedView_ModelChanged;
}
private float MinRowHeight => _context.ToPixels(44);
public override int ItemCount => CellCaches.Count;
public override long GetItemId(int position)
{
return position;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
ViewHolder viewHolder;
switch(viewType)
{
case ViewTypeHeader:
viewHolder = new HeaderViewHolder(
LayoutInflater.FromContext(_context).Inflate(Resource.Layout.HeaderCell, parent, false),
_boxedView);
break;
case ViewTypeFooter:
viewHolder = new FooterViewHolder(
LayoutInflater.FromContext(_context).Inflate(Resource.Layout.FooterCell, parent, false),
_boxedView);
break;
default:
viewHolder = new ContentViewHolder(
LayoutInflater.FromContext(_context).Inflate(Resource.Layout.ContentCell, parent, false));
viewHolder.ItemView.SetOnClickListener(this);
break;
}
_viewHolders.Add(viewHolder);
return viewHolder;
}
public void OnClick(AView view)
{
var position = _recyclerView.GetChildAdapterPosition(view);
// TODO: It is desirable that the forms side has Selected property and reflects it.
// But do it at a later as iOS side doesn't have that process.
DeselectRow();
var cell = view.FindViewById<LinearLayout>(Resource.Id.ContentCellBody).GetChildAt(0) as BaseCellView;
if(cell == null || !CellCaches[position].Cell.IsEnabled)
{
// If FormsCell IsEnable is false, does nothing.
return;
}
_boxedView.Model.RowSelected(CellCaches[position].Cell);
cell.RowSelected(this, position);
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var cellInfo = CellCaches[position];
switch(holder.ItemViewType)
{
case ViewTypeHeader:
BindHeaderView((HeaderViewHolder)holder, (TextCell)cellInfo.Cell);
break;
case ViewTypeFooter:
BindFooterView((FooterViewHolder)holder, (TextCell)cellInfo.Cell);
break;
default:
BindContentView((ContentViewHolder)holder, cellInfo.Cell, position);
break;
}
}
public override int GetItemViewType(int position)
{
var cellInfo = CellCaches[position];
if(cellInfo.IsHeader)
{
return ViewTypeHeader;
}
else if(cellInfo.IsFooter)
{
return ViewTypeFooter;
}
else
{
return _viewTypes[cellInfo.Cell.GetType()];
}
}
public void DeselectRow()
{
if(_preSelectedCell != null)
{
_preSelectedCell.Selected = false;
_preSelectedCell = null;
}
_selectedIndex = -1;
}
public void SelectedRow(AView cell, int position)
{
_preSelectedCell = cell;
_selectedIndex = position;
cell.Selected = true;
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
_boxedView.ModelChanged -= BoxedView_ModelChanged;
_cellCaches?.Clear();
_cellCaches = null;
_boxedView = null;
_viewTypes = null;
foreach(var holder in _viewHolders)
{
holder.Dispose();
}
_viewHolders.Clear();
_viewHolders = null;
}
base.Dispose(disposing);
}
private void BoxedView_ModelChanged(object sender, EventArgs e)
{
if(_recyclerView != null)
{
_cellCaches = null;
NotifyDataSetChanged();
}
}
private void BindHeaderView(HeaderViewHolder holder, TextCell formsCell)
{
var view = holder.ItemView;
// Judging cell height
int cellHeight = (int)_context.ToPixels(44);
var individualHeight = formsCell.Height;
if(individualHeight > 0d)
{
cellHeight = (int)_context.ToPixels(individualHeight);
}
else if(_boxedView.HeaderHeight > -1)
{
cellHeight = (int)_context.ToPixels(_boxedView.HeaderHeight);
}
view.SetMinimumHeight(cellHeight);
view.LayoutParameters.Height = cellHeight;
holder.TextView.SetPadding(
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Left),
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Top),
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Right),
(int)view.Context.ToPixels(_boxedView.HeaderPadding.Bottom));
holder.TextView.Gravity = _boxedView.HeaderTextVerticalAlign.ToAndroidVertical() | GravityFlags.Left;
holder.TextView.TextAlignment = Android.Views.TextAlignment.Gravity;
holder.TextView.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)_boxedView.HeaderFontSize);
holder.TextView.SetBackgroundColor(_boxedView.HeaderBackgroundColor.ToAndroid());
holder.TextView.SetMaxLines(1);
holder.TextView.SetMinLines(1);
holder.TextView.SetTypeface(null, Android.Graphics.TypefaceStyle.Bold);
holder.TextView.Ellipsize = TextUtils.TruncateAt.End;
if(_boxedView.HeaderTextColor != Color.Default)
{
holder.TextView.SetTextColor(_boxedView.HeaderTextColor.ToAndroid());
}
// Border setting
if(_boxedView.ShowSectionTopBottomBorder)
{
holder.Border.SetBackgroundColor(_boxedView.SeparatorColor.ToAndroid());
}
else
{
holder.Border.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
// Update text
holder.TextView.Text = formsCell.Text;
}
private void BindFooterView(FooterViewHolder holder, TextCell formsCell)
{
var view = holder.ItemView;
// Footer visible setting
if(string.IsNullOrEmpty(formsCell.Text))
{
//if text is empty, hidden (height 0)
holder.TextView.Visibility = ViewStates.Gone;
view.Visibility = ViewStates.Gone;
}
else
{
holder.TextView.Visibility = ViewStates.Visible;
view.Visibility = ViewStates.Visible;
}
holder.TextView.SetPadding(
(int)view.Context.ToPixels(_boxedView.FooterPadding.Left),
(int)view.Context.ToPixels(_boxedView.FooterPadding.Top),
(int)view.Context.ToPixels(_boxedView.FooterPadding.Right),
(int)view.Context.ToPixels(_boxedView.FooterPadding.Bottom));
holder.TextView.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)_boxedView.FooterFontSize);
holder.TextView.SetBackgroundColor(_boxedView.FooterBackgroundColor.ToAndroid());
if(_boxedView.FooterTextColor != Color.Default)
{
holder.TextView.SetTextColor(_boxedView.FooterTextColor.ToAndroid());
}
// Update text
holder.TextView.Text = formsCell.Text;
}
private void BindContentView(ContentViewHolder holder, Cell formsCell, int position)
{
AView nativeCell = null;
AView layout = holder.ItemView;
holder.SectionIndex = CellCaches[position].SectionIndex;
holder.RowIndex = CellCaches[position].RowIndex;
nativeCell = holder.Body.GetChildAt(0);
if(nativeCell != null)
{
holder.Body.RemoveViewAt(0);
}
nativeCell = CellFactory.GetCell(formsCell, nativeCell, _recyclerView, _context, _boxedView);
if(position == _selectedIndex)
{
DeselectRow();
nativeCell.Selected = true;
_preSelectedCell = nativeCell;
}
var minHeight = (int)Math.Max(_context.ToPixels(_boxedView.RowHeight), MinRowHeight);
// It is necessary to set both
layout.SetMinimumHeight(minHeight);
nativeCell.SetMinimumHeight(minHeight);
if(!_boxedView.HasUnevenRows)
{
// If not Uneven, set the larger one of RowHeight and MinRowHeight.
layout.LayoutParameters.Height = minHeight;
}
else if(formsCell.Height > -1)
{
// If the cell itself was specified height, set it.
layout.SetMinimumHeight((int)_context.ToPixels(formsCell.Height));
layout.LayoutParameters.Height = (int)_context.ToPixels(formsCell.Height);
}
else if(formsCell is ViewCell viewCell)
{
// If used a viewcell, calculate the size and layout it.
var size = viewCell.View.Measure(_boxedView.Width, double.PositiveInfinity);
viewCell.View.Layout(new Rectangle(0, 0, size.Request.Width, size.Request.Height));
layout.LayoutParameters.Height = (int)_context.ToPixels(size.Request.Height);
}
else
{
layout.LayoutParameters.Height = -2; // wrap_content
}
if(!CellCaches[position].IsLastCell || _boxedView.ShowSectionTopBottomBorder)
{
holder.Border.SetBackgroundColor(_boxedView.SeparatorColor.ToAndroid());
}
else
{
holder.Border.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
holder.Body.AddView(nativeCell, 0);
}
private void FillCache()
{
var model = _boxedView.Model;
int sectionCount = model.GetSectionCount();
var newCellCaches = new List<CellCache>();
for(var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++)
{
var sectionTitle = model.GetSectionTitle(sectionIndex);
var sectionRowCount = model.GetRowCount(sectionIndex);
Cell headerCell = new TextCell { Text = sectionTitle, Height = model.GetHeaderHeight(sectionIndex) };
headerCell.Parent = _boxedView;
newCellCaches.Add(new CellCache
{
Cell = headerCell,
IsHeader = true,
SectionIndex = sectionIndex,
});
for(int i = 0; i < sectionRowCount; i++)
{
newCellCaches.Add(new CellCache
{
Cell = model.GetCell(sectionIndex, i),
IsLastCell = i == sectionRowCount - 1,
SectionIndex = sectionIndex,
RowIndex = i
});
}
var footerCell = new TextCell { Text = model.GetFooterText(sectionIndex) };
footerCell.Parent = _boxedView;
newCellCaches.Add(new CellCache
{
Cell = footerCell,
IsFooter = true,
SectionIndex = sectionIndex,
});
}
_cellCaches = newCellCaches;
if(_viewTypes == null)
{
_viewTypes = _cellCaches
.Select(x => x.Cell.GetType())
.Distinct()
.Select((x, idx) => new { x, index = idx })
.ToDictionary(key => key.x, val => val.index + 2);
}
else
{
var idx = _viewTypes.Values.Max() + 1;
foreach(var t in _cellCaches.Select(x => x.Cell.GetType()).Distinct().Except(_viewTypes.Keys).ToList())
{
_viewTypes.Add(t, idx++);
}
}
}
public void CellMoved(int fromPos, int toPos)
{
var tmp = CellCaches[fromPos];
CellCaches.RemoveAt(fromPos);
CellCaches.Insert(toPos, tmp);
}
[Preserve(AllMembers = true)]
internal class CellCache
{
public Cell Cell { get; set; }
public bool IsHeader { get; set; } = false;
public bool IsFooter { get; set; } = false;
public bool IsLastCell { get; set; } = false;
public int SectionIndex { get; set; }
public int RowIndex { get; set; }
}
}
[Preserve(AllMembers = true)]
internal class ViewHolder : RecyclerView.ViewHolder
{
public ViewHolder(AView view)
: base(view) { }
protected override void Dispose(bool disposing)
{
if(disposing)
{
ItemView?.Dispose();
ItemView = null;
}
base.Dispose(disposing);
}
}
[Preserve(AllMembers = true)]
internal class HeaderViewHolder : ViewHolder
{
public HeaderViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView)
: base(view)
{
TextView = view.FindViewById<TextView>(Resource.Id.HeaderCellText);
Border = view.FindViewById<LinearLayout>(Resource.Id.HeaderCellBorder);
}
public TextView TextView { get; private set; }
public LinearLayout Border { get; private set; }
protected override void Dispose(bool disposing)
{
if(disposing)
{
TextView?.Dispose();
TextView = null;
Border?.Dispose();
Border = null;
}
base.Dispose(disposing);
}
}
[Preserve(AllMembers = true)]
internal class FooterViewHolder : ViewHolder
{
public TextView TextView { get; private set; }
public FooterViewHolder(AView view, App.Controls.BoxedView.BoxedView boxedView)
: base(view)
{
TextView = view.FindViewById<TextView>(Resource.Id.FooterCellText);
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
TextView?.Dispose();
TextView = null;
}
base.Dispose(disposing);
}
}
[Preserve(AllMembers = true)]
internal class ContentViewHolder : ViewHolder
{
public LinearLayout Body { get; private set; }
public AView Border { get; private set; }
public int SectionIndex { get; set; }
public int RowIndex { get; set; }
public ContentViewHolder(AView view)
: base(view)
{
Body = view.FindViewById<LinearLayout>(Resource.Id.ContentCellBody);
Border = view.FindViewById(Resource.Id.ContentCellBorder);
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
var nativeCell = Body.GetChildAt(0);
if(nativeCell is INativeElementView nativeElementView)
{
// If a ViewCell is used, it stops the ViewCellContainer from executing the dispose method.
// Because if the AiForms.Effects is used and a ViewCellContainer is disposed, it crashes.
if(!(nativeElementView.Element is ViewCell))
{
nativeCell?.Dispose();
}
}
Border?.Dispose();
Border = null;
Body?.Dispose();
Body = null;
ItemView.SetOnClickListener(null);
}
base.Dispose(disposing);
}
}
}

View file

@ -1,196 +0,0 @@
using Android.Content;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Support.V7.Widget.Helper;
using Android.Views;
using Bit.App.Controls.BoxedView;
using Bit.Droid.Renderers.BoxedView;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(BoxedView), typeof(BoxedViewRenderer))]
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class BoxedViewRenderer : ViewRenderer<App.Controls.BoxedView.BoxedView, RecyclerView>
{
private Page _parentPage;
private LinearLayoutManager _layoutManager;
private ItemTouchHelper _itemTouchhelper;
private BoxedViewRecyclerAdapter _adapter;
private BoxedViewSimpleCallback _simpleCallback;
public BoxedViewRenderer(Context context)
: base(context)
{
AutoPackage = false;
}
protected override void OnElementChanged(ElementChangedEventArgs<App.Controls.BoxedView.BoxedView> e)
{
base.OnElementChanged(e);
if(e.NewElement != null)
{
var recyclerView = new RecyclerView(Context);
_layoutManager = new LinearLayoutManager(Context);
recyclerView.SetLayoutManager(_layoutManager);
SetNativeControl(recyclerView);
Control.Focusable = false;
Control.DescendantFocusability = DescendantFocusability.AfterDescendants;
UpdateBackgroundColor();
UpdateRowHeight();
_adapter = new BoxedViewRecyclerAdapter(Context, e.NewElement, recyclerView);
Control.SetAdapter(_adapter);
_simpleCallback = new BoxedViewSimpleCallback(
e.NewElement, ItemTouchHelper.Up | ItemTouchHelper.Down, 0);
_itemTouchhelper = new ItemTouchHelper(_simpleCallback);
_itemTouchhelper.AttachToRecyclerView(Control);
Element elm = Element;
while(elm != null)
{
elm = elm.Parent;
if(elm is Page)
{
break;
}
}
_parentPage = elm as Page;
_parentPage.Appearing += ParentPageAppearing;
}
}
private void ParentPageAppearing(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(() => _adapter.DeselectRow());
}
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
{
base.OnLayout(changed, left, top, right, bottom);
if(!changed)
{
return;
}
var startPos = _layoutManager.FindFirstCompletelyVisibleItemPosition();
var endPos = _layoutManager.FindLastCompletelyVisibleItemPosition();
var totalH = 0;
for(var i = startPos; i <= endPos; i++)
{
var child = _layoutManager.GetChildAt(i);
if(child == null)
{
return;
}
totalH += _layoutManager.GetChildAt(i).Height;
}
Element.VisibleContentHeight = Context.FromPixels(Math.Min(totalH, Control.Height));
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == App.Controls.BoxedView.BoxedView.SeparatorColorProperty.PropertyName)
{
_adapter.NotifyDataSetChanged();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.BackgroundColorProperty.PropertyName)
{
UpdateBackgroundColor();
}
else if(e.PropertyName == TableView.RowHeightProperty.PropertyName)
{
UpdateRowHeight();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName)
{
//_adapter.NotifyDataSetChanged();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ShowSectionTopBottomBorderProperty.PropertyName)
{
_adapter.NotifyDataSetChanged();
}
else if(e.PropertyName == TableView.HasUnevenRowsProperty.PropertyName)
{
_adapter.NotifyDataSetChanged();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToTopProperty.PropertyName)
{
UpdateScrollToTop();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.ScrollToBottomProperty.PropertyName)
{
UpdateScrollToBottom();
}
}
private void UpdateRowHeight()
{
if(Element.RowHeight == -1)
{
Element.RowHeight = 60;
}
else
{
_adapter?.NotifyDataSetChanged();
}
}
private void UpdateScrollToTop()
{
if(Element.ScrollToTop)
{
_layoutManager.ScrollToPosition(0);
Element.ScrollToTop = false;
}
}
private void UpdateScrollToBottom()
{
if(Element.ScrollToBottom)
{
if(_adapter != null)
{
_layoutManager.ScrollToPosition(_adapter.ItemCount - 1);
}
Element.ScrollToBottom = false;
}
}
protected new void UpdateBackgroundColor()
{
if(Element.BackgroundColor != Color.Default)
{
Control.SetBackgroundColor(Element.BackgroundColor.ToAndroid());
}
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
_parentPage.Appearing -= ParentPageAppearing;
_adapter?.Dispose();
_adapter = null;
_layoutManager?.Dispose();
_layoutManager = null;
_simpleCallback?.Dispose();
_simpleCallback = null;
_itemTouchhelper?.Dispose();
_itemTouchhelper = null;
}
base.Dispose(disposing);
}
}
}

View file

@ -1,104 +0,0 @@
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Support.V7.Widget.Helper;
using System;
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class BoxedViewSimpleCallback : ItemTouchHelper.SimpleCallback
{
private App.Controls.BoxedView.BoxedView _boxedView;
private int _offset = 0;
public BoxedViewSimpleCallback(App.Controls.BoxedView.BoxedView boxedView, int dragDirs, int swipeDirs)
: base(dragDirs, swipeDirs)
{
_boxedView = boxedView;
}
public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target)
{
if(!(viewHolder is ContentViewHolder fromContentHolder))
{
return false;
}
if(!(target is ContentViewHolder toContentHolder))
{
return false;
}
if(fromContentHolder.SectionIndex != toContentHolder.SectionIndex)
{
return false;
}
var section = _boxedView.Model.GetSection(fromContentHolder.SectionIndex);
if(section == null || !section.UseDragSort)
{
return false;
}
var fromPos = viewHolder.AdapterPosition;
var toPos = target.AdapterPosition;
_offset += toPos - fromPos;
var settingsAdapter = recyclerView.GetAdapter() as BoxedViewRecyclerAdapter;
settingsAdapter.NotifyItemMoved(fromPos, toPos); // rows update
settingsAdapter.CellMoved(fromPos, toPos); // caches update
return true;
}
public override void ClearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
{
base.ClearView(recyclerView, viewHolder);
if(!(viewHolder is ContentViewHolder contentHolder))
{
return;
}
var section = _boxedView.Model.GetSection(contentHolder.SectionIndex);
var pos = contentHolder.RowIndex;
if(section.ItemsSource == null)
{
var tmp = section[pos];
section.RemoveAt(pos);
section.Insert(pos + _offset, tmp);
}
else if(section.ItemsSource != null)
{
// must update DataSource at this timing.
var tmp = section.ItemsSource[pos];
section.ItemsSource.RemoveAt(pos);
section.ItemsSource.Insert(pos + _offset, tmp);
}
_offset = 0;
}
public override int GetDragDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
{
if(!(viewHolder is ContentViewHolder contentHolder))
{
return 0;
}
var section = _boxedView.Model.GetSection(contentHolder.SectionIndex);
if(section == null || !section.UseDragSort)
{
return 0;
}
return base.GetDragDirs(recyclerView, viewHolder);
}
public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
{
throw new NotImplementedException();
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
_boxedView = null;
}
base.Dispose(disposing);
}
}
}

View file

@ -1,75 +0,0 @@
using Android.Content;
using Android.Runtime;
using Android.Views;
using Bit.App.Controls.BoxedView;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Xamarin.Forms.Platform.Android;
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class BaseCellRenderer<TNativeCell> : CellRenderer where TNativeCell : BaseCellView
{
protected override View GetCellCore(Xamarin.Forms.Cell item, View convertView, ViewGroup parent,
Context context)
{
if(!(convertView is TNativeCell nativeCell))
{
nativeCell = InstanceCreator<Context, Xamarin.Forms.Cell, TNativeCell>.Create(context, item);
}
ClearPropertyChanged(nativeCell);
nativeCell.Cell = item;
SetUpPropertyChanged(nativeCell);
nativeCell.UpdateCell();
return nativeCell;
}
protected void SetUpPropertyChanged(BaseCellView nativeCell)
{
var formsCell = nativeCell.Cell as BaseCell;
formsCell.PropertyChanged += nativeCell.CellPropertyChanged;
if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement)
{
parentElement.PropertyChanged += nativeCell.ParentPropertyChanged;
var section = parentElement.Model.GetSection(BoxedModel.GetPath(formsCell).Item1);
if(section != null)
{
formsCell.Section = section;
formsCell.Section.PropertyChanged += nativeCell.SectionPropertyChanged;
}
}
}
private void ClearPropertyChanged(BaseCellView nativeCell)
{
var formsCell = nativeCell.Cell as BaseCell;
formsCell.PropertyChanged -= nativeCell.CellPropertyChanged;
if(formsCell.Parent is App.Controls.BoxedView.BoxedView parentElement)
{
parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged;
if(formsCell.Section != null)
{
formsCell.Section.PropertyChanged -= nativeCell.SectionPropertyChanged;
}
}
}
internal static class InstanceCreator<T1, T2, TInstance>
{
public static Func<T1, T2, TInstance> Create { get; } = CreateInstance();
private static Func<T1, T2, TInstance> CreateInstance()
{
var argsTypes = new[] { typeof(T1), typeof(T2) };
var constructor = typeof(TInstance).GetConstructor(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder, argsTypes, null);
var args = argsTypes.Select(Expression.Parameter).ToArray();
return Expression.Lambda<Func<T1, T2, TInstance>>(Expression.New(constructor, args), args).Compile();
}
}
}
}

View file

@ -1,373 +0,0 @@
using Android.Content;
using Android.Graphics.Drawables;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Bit.App.Controls.BoxedView;
using System;
using System.ComponentModel;
using System.Threading;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using ARelativeLayout = Android.Widget.RelativeLayout;
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class BaseCellView : ARelativeLayout, INativeElementView
{
private bool _debugWithColors = false;
private CancellationTokenSource _iconTokenSource;
private Android.Graphics.Color _defaultTextColor;
private ColorDrawable _backgroundColor;
private ColorDrawable _selectedColor;
private RippleDrawable _ripple;
private float _defaultFontSize;
protected Context _Context;
public BaseCellView(Context context, Cell cell)
: base(context)
{
_Context = context;
Cell = cell;
CreateContentView();
}
public Cell Cell { get; set; }
public Element Element => Cell;
protected BaseCell CellBase => Cell as BaseCell;
public App.Controls.BoxedView.BoxedView CellParent => Cell.Parent as App.Controls.BoxedView.BoxedView;
public TextView CellTitle { get; set; }
public LinearLayout CellTitleContent { get; set; }
public LinearLayout CellContent { get; set; }
public LinearLayout CellButtonContent { get; set; }
public Android.Widget.ImageButton CellButton1 { get; set; }
public Android.Widget.ImageButton CellButton2 { get; set; }
public Android.Widget.ImageButton CellButton3 { get; set; }
public LinearLayout CellAccessory { get; set; }
private void CreateContentView()
{
var contentView = (_Context as FormsAppCompatActivity)
.LayoutInflater
.Inflate(Resource.Layout.CellBaseView, this, true);
contentView.LayoutParameters = new ViewGroup.LayoutParams(-1, -1);
CellTitle = contentView.FindViewById<TextView>(Resource.Id.CellTitle);
CellContent = contentView.FindViewById<LinearLayout>(Resource.Id.CellContent);
CellTitleContent = contentView.FindViewById<LinearLayout>(Resource.Id.CellTitleContent);
CellButtonContent = contentView.FindViewById<LinearLayout>(Resource.Id.CellButtonContent);
CellButton1 = contentView.FindViewById<Android.Widget.ImageButton>(Resource.Id.CellButton1);
CellButton1.Click += CellButton1_Click;
CellButton2 = contentView.FindViewById<Android.Widget.ImageButton>(Resource.Id.CellButton2);
CellButton2.Click += CellButton2_Click;
CellButton3 = contentView.FindViewById<Android.Widget.ImageButton>(Resource.Id.CellButton3);
CellButton3.Click += CellButton3_Click;
CellAccessory = contentView.FindViewById<LinearLayout>(Resource.Id.CellAccessory);
_backgroundColor = new ColorDrawable();
_selectedColor = new ColorDrawable(Android.Graphics.Color.Argb(125, 180, 180, 180));
var sel = new StateListDrawable();
sel.AddState(new int[] { Android.Resource.Attribute.StateSelected }, _selectedColor);
sel.AddState(new int[] { -Android.Resource.Attribute.StateSelected }, _backgroundColor);
sel.SetExitFadeDuration(250);
sel.SetEnterFadeDuration(250);
var rippleColor = Android.Graphics.Color.Rgb(180, 180, 180);
if(CellParent.SelectedColor != Color.Default)
{
rippleColor = CellParent.SelectedColor.ToAndroid();
}
_ripple = RendererUtils.CreateRipple(rippleColor, sel);
Background = _ripple;
_defaultTextColor = new Android.Graphics.Color(CellTitle.CurrentTextColor);
_defaultFontSize = CellTitle.TextSize;
if(_debugWithColors)
{
contentView.Background = _Context.GetDrawable(Android.Resource.Color.HoloGreenLight);
CellContent.Background = _Context.GetDrawable(Android.Resource.Color.HoloOrangeLight);
CellButtonContent.Background = _Context.GetDrawable(Android.Resource.Color.HoloOrangeDark);
CellTitle.Background = _Context.GetDrawable(Android.Resource.Color.HoloBlueLight);
}
}
public virtual void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == BaseCell.TitleProperty.PropertyName)
{
UpdateTitleText();
}
else if(e.PropertyName == BaseCell.TitleColorProperty.PropertyName)
{
UpdateTitleColor();
}
else if(e.PropertyName == BaseCell.TitleFontSizeProperty.PropertyName)
{
UpdateTitleFontSize();
}
else if(e.PropertyName == BaseCell.BackgroundColorProperty.PropertyName)
{
UpdateBackgroundColor();
}
else if(e.PropertyName == Cell.IsEnabledProperty.PropertyName)
{
UpdateIsEnabled();
}
else if(e.PropertyName == BaseCell.Button1IconProperty.PropertyName)
{
UpdateButtonIcon(CellButton1, CellBase.Button1Icon);
}
else if(e.PropertyName == BaseCell.Button2IconProperty.PropertyName)
{
UpdateButtonIcon(CellButton2, CellBase.Button2Icon);
}
else if(e.PropertyName == BaseCell.Button3IconProperty.PropertyName)
{
UpdateButtonIcon(CellButton3, CellBase.Button3Icon);
}
}
public virtual void ParentPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Avoid running the vain process when popping a page.
if((sender as BindableObject)?.BindingContext == null)
{
return;
}
if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleColorProperty.PropertyName)
{
UpdateTitleColor();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellTitleFontSizeProperty.PropertyName)
{
UpdateWithForceLayout(UpdateTitleFontSize);
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellBackgroundColorProperty.PropertyName)
{
UpdateBackgroundColor();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.SelectedColorProperty.PropertyName)
{
UpdateWithForceLayout(UpdateSelectedColor);
}
}
public virtual void SectionPropertyChanged(object sender, PropertyChangedEventArgs e)
{ }
public virtual void RowSelected(BoxedViewRecyclerAdapter adapter, int position)
{ }
protected void UpdateWithForceLayout(Action updateAction)
{
updateAction();
Invalidate();
}
public virtual void UpdateCell()
{
UpdateButtonIcon(CellButton1, CellBase.Button1Icon);
UpdateButtonIcon(CellButton2, CellBase.Button2Icon);
UpdateButtonIcon(CellButton3, CellBase.Button3Icon);
UpdateBackgroundColor();
UpdateSelectedColor();
UpdateTitleText();
UpdateTitleColor();
UpdateTitleFontSize();
UpdateIsEnabled();
Invalidate();
}
private void UpdateButtonIcon(Android.Widget.ImageButton cellButton, string icon)
{
if(string.IsNullOrWhiteSpace(icon))
{
cellButton.Visibility = ViewStates.Gone;
}
else
{
cellButton.SetImageDrawable(_Context.GetDrawable(icon));
cellButton.SetImageDrawable(_Context.GetDrawable(icon));
cellButton.Visibility = ViewStates.Visible;
}
}
private void CellButton1_Click(object sender, EventArgs e)
{
if(CellBase.Button1Command?.CanExecute(CellBase.Button1CommandParameter) ?? false)
{
CellBase.Button1Command.Execute(CellBase.Button1CommandParameter);
}
}
private void CellButton2_Click(object sender, EventArgs e)
{
if(CellBase.Button2Command?.CanExecute(CellBase.Button2CommandParameter) ?? false)
{
CellBase.Button2Command.Execute(CellBase.Button2CommandParameter);
}
}
private void CellButton3_Click(object sender, EventArgs e)
{
if(CellBase.Button3Command?.CanExecute(CellBase.Button3CommandParameter) ?? false)
{
CellBase.Button3Command.Execute(CellBase.Button3CommandParameter);
}
}
private void UpdateBackgroundColor()
{
Selected = false;
if(CellBase.BackgroundColor != Color.Default)
{
_backgroundColor.Color = CellBase.BackgroundColor.ToAndroid();
}
else if(CellParent != null && CellParent.CellBackgroundColor != Color.Default)
{
_backgroundColor.Color = CellParent.CellBackgroundColor.ToAndroid();
}
else
{
_backgroundColor.Color = Android.Graphics.Color.Transparent;
}
}
private void UpdateSelectedColor()
{
if(CellParent != null && CellParent.SelectedColor != Color.Default)
{
_selectedColor.Color = CellParent.SelectedColor.MultiplyAlpha(0.5).ToAndroid();
_ripple.SetColor(RendererUtils.GetPressedColorSelector(CellParent.SelectedColor.ToAndroid()));
}
else
{
_selectedColor.Color = Android.Graphics.Color.Argb(125, 180, 180, 180);
_ripple.SetColor(RendererUtils.GetPressedColorSelector(Android.Graphics.Color.Rgb(180, 180, 180)));
}
}
private void UpdateTitleText()
{
CellTitle.Text = CellBase.Title;
// Hide TextView right padding when TextView.Text empty.
CellTitle.Visibility = string.IsNullOrEmpty(CellTitle.Text) ? ViewStates.Gone : ViewStates.Visible;
}
private void UpdateTitleColor()
{
if(CellBase.TitleColor != Color.Default)
{
CellTitle.SetTextColor(CellBase.TitleColor.ToAndroid());
}
else if(CellParent != null && CellParent.CellTitleColor != Color.Default)
{
CellTitle.SetTextColor(CellParent.CellTitleColor.ToAndroid());
}
else
{
CellTitle.SetTextColor(_defaultTextColor);
}
}
private void UpdateTitleFontSize()
{
if(CellBase.TitleFontSize > 0)
{
CellTitle.SetTextSize(ComplexUnitType.Sp, (float)CellBase.TitleFontSize);
}
else if(CellParent != null)
{
CellTitle.SetTextSize(ComplexUnitType.Sp, (float)CellParent.CellTitleFontSize);
}
else
{
CellTitle.SetTextSize(ComplexUnitType.Sp, _defaultFontSize);
}
}
protected virtual void UpdateIsEnabled()
{
SetEnabledAppearance(CellBase.IsEnabled);
}
protected virtual void SetEnabledAppearance(bool isEnabled)
{
if(isEnabled)
{
Focusable = false;
DescendantFocusability = DescendantFocusability.AfterDescendants;
CellTitle.Alpha = 1f;
}
else
{
// not to invoke a ripple effect and not to selected
Focusable = true;
DescendantFocusability = DescendantFocusability.BlockDescendants;
// to turn like disabled
CellTitle.Alpha = 0.3f;
}
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
CellBase.PropertyChanged -= CellPropertyChanged;
CellParent.PropertyChanged -= ParentPropertyChanged;
CellButton1.Click -= CellButton1_Click;
CellButton2.Click -= CellButton2_Click;
CellButton3.Click -= CellButton3_Click;
if(CellBase.Section != null)
{
CellBase.Section.PropertyChanged -= SectionPropertyChanged;
CellBase.Section = null;
}
CellTitle?.Dispose();
CellTitle = null;
CellTitleContent?.Dispose();
CellTitleContent = null;
CellAccessory?.Dispose();
CellAccessory = null;
CellButton1?.Dispose();
CellButton1 = null;
CellButton2?.Dispose();
CellButton2 = null;
CellButton3?.Dispose();
CellButton3 = null;
CellButtonContent?.Dispose();
CellButtonContent = null;
CellContent?.Dispose();
CellContent = null;
Cell = null;
_iconTokenSource?.Dispose();
_iconTokenSource = null;
_Context = null;
_backgroundColor?.Dispose();
_backgroundColor = null;
_selectedColor?.Dispose();
_selectedColor = null;
_ripple?.Dispose();
_ripple = null;
Background?.Dispose();
Background = null;
}
base.Dispose(disposing);
}
}
}

View file

@ -1,282 +0,0 @@
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Text;
using Android.Text.Method;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Java.Lang;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Bit.App.Controls.BoxedView.EntryCell),
typeof(Bit.Droid.Renderers.BoxedView.EntryCellRenderer))]
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class EntryCellRenderer : BaseCellRenderer<EntryCellView>
{ }
[Preserve(AllMembers = true)]
public class EntryCellView : BaseCellView, ITextWatcher, Android.Views.View.IOnFocusChangeListener,
TextView.IOnEditorActionListener
{
private bool _debugWithColors = false;
private CustomEditText _editText;
public EntryCellView(Context context, Cell cell)
: base(context, cell)
{
_editText = new CustomEditText(context)
{
Focusable = true,
ImeOptions = ImeAction.Done,
OnFocusChangeListener = this,
Ellipsize = TextUtils.TruncateAt.End,
ClearFocusAction = DoneEdit,
Background = _Context.GetDrawable(Android.Resource.Color.Transparent)
};
_editText.SetPadding(0, 0, 0, 0);
_editText.SetOnEditorActionListener(this);
_editText.SetSingleLine(true);
_editText.InputType |= InputTypes.TextFlagNoSuggestions; // Disabled spell check
Click += EntryCellView_Click;
using(var lParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent,
ViewGroup.LayoutParams.WrapContent))
{
CellContent.AddView(_editText, lParams);
}
if(_debugWithColors)
{
_editText.Background = _Context.GetDrawable(Android.Resource.Color.HoloRedLight);
}
}
App.Controls.BoxedView.EntryCell _EntryCell => Cell as App.Controls.BoxedView.EntryCell;
public override void UpdateCell()
{
UpdateValueText();
UpdateValueTextColor();
UpdateValueTextFontSize();
UpdateKeyboard();
UpdatePlaceholder();
UpdateTextAlignment();
UpdateIsPassword();
base.UpdateCell();
}
public override void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.CellPropertyChanged(sender, e);
if(e.PropertyName == App.Controls.BoxedView.EntryCell.ValueTextProperty.PropertyName)
{
UpdateValueText();
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.ValueTextFontSizeProperty.PropertyName)
{
UpdateWithForceLayout(UpdateValueTextFontSize);
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.ValueTextColorProperty.PropertyName)
{
UpdateWithForceLayout(UpdateValueTextColor);
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.KeyboardProperty.PropertyName)
{
UpdateKeyboard();
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.PlaceholderProperty.PropertyName)
{
UpdatePlaceholder();
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.TextAlignmentProperty.PropertyName)
{
UpdateTextAlignment();
}
else if(e.PropertyName == App.Controls.BoxedView.EntryCell.IsPasswordProperty.PropertyName)
{
UpdateIsPassword();
}
}
public override void ParentPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.ParentPropertyChanged(sender, e);
if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextColorProperty.PropertyName)
{
UpdateValueTextColor();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextFontSizeProperty.PropertyName)
{
UpdateWithForceLayout(UpdateValueTextFontSize);
}
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
Click -= EntryCellView_Click;
_editText.RemoveFromParent();
_editText.SetOnEditorActionListener(null);
_editText.RemoveTextChangedListener(this);
_editText.OnFocusChangeListener = null;
_editText.ClearFocusAction = null;
_editText.Dispose();
_editText = null;
}
base.Dispose(disposing);
}
private void EntryCellView_Click(object sender, EventArgs e)
{
_editText.RequestFocus();
ShowKeyboard(_editText);
}
private void UpdateValueText()
{
_editText.RemoveTextChangedListener(this);
if(_editText.Text != _EntryCell.ValueText)
{
_editText.Text = _EntryCell.ValueText;
}
_editText.AddTextChangedListener(this);
}
private void UpdateValueTextFontSize()
{
if(_EntryCell.ValueTextFontSize > 0)
{
_editText.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)_EntryCell.ValueTextFontSize);
}
else if(CellParent != null)
{
_editText.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)CellParent.CellValueTextFontSize);
}
}
private void UpdateValueTextColor()
{
if(_EntryCell.ValueTextColor != Color.Default)
{
_editText.SetTextColor(_EntryCell.ValueTextColor.ToAndroid());
}
else if(CellParent != null && CellParent.CellValueTextColor != Color.Default)
{
_editText.SetTextColor(CellParent.CellValueTextColor.ToAndroid());
}
}
private void UpdateKeyboard()
{
_editText.InputType = _EntryCell.Keyboard.ToInputType() | InputTypes.TextFlagNoSuggestions;
}
private void UpdateIsPassword()
{
_editText.TransformationMethod = _EntryCell.IsPassword ? new PasswordTransformationMethod() : null;
}
private void UpdatePlaceholder()
{
_editText.Hint = _EntryCell.Placeholder;
_editText.SetHintTextColor(Android.Graphics.Color.Rgb(210, 210, 210));
}
private void UpdateTextAlignment()
{
_editText.Gravity = _EntryCell.TextAlignment.ToAndroidHorizontal();
}
private void DoneEdit()
{
var entryCell = (IEntryCellController)Cell;
entryCell.SendCompleted();
_editText.ClearFocus();
ClearFocus();
}
private void HideKeyboard(Android.Views.View inputView)
{
using(var inputMethodManager = (InputMethodManager)_Context.GetSystemService(Context.InputMethodService))
{
IBinder windowToken = inputView.WindowToken;
if(windowToken != null)
{
inputMethodManager.HideSoftInputFromWindow(windowToken, HideSoftInputFlags.None);
}
}
}
private void ShowKeyboard(Android.Views.View inputView)
{
using(var inputMethodManager = (InputMethodManager)_Context.GetSystemService(Context.InputMethodService))
{
inputMethodManager.ShowSoftInput(inputView, ShowFlags.Forced);
inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
}
}
bool TextView.IOnEditorActionListener.OnEditorAction(TextView v, ImeAction actionId, KeyEvent e)
{
if(actionId == ImeAction.Done || (actionId == ImeAction.ImeNull && e.KeyCode == Keycode.Enter))
{
HideKeyboard(v);
DoneEdit();
}
return true;
}
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)
{
_EntryCell.ValueText = s?.ToString();
}
void IOnFocusChangeListener.OnFocusChange(Android.Views.View v, bool hasFocus)
{
if(hasFocus)
{
// Show underline when on focus.
_editText.Background.Alpha = 100;
}
else
{
// Hide underline
_editText.Background.Alpha = 0;
}
}
}
[Preserve(AllMembers = true)]
internal class CustomEditText : EditText
{
public CustomEditText(Context context)
: base(context)
{ }
public Action ClearFocusAction { get; set; }
public override bool OnKeyPreIme(Keycode keyCode, KeyEvent e)
{
if(keyCode == Keycode.Back && e.Action == KeyEventActions.Up)
{
ClearFocus();
ClearFocusAction?.Invoke();
}
return base.OnKeyPreIme(keyCode, e);
}
}
}

View file

@ -1,127 +0,0 @@
using Android.Content;
using Android.Runtime;
using Android.Text;
using Android.Views;
using Android.Widget;
using Bit.App.Controls.BoxedView;
using Bit.Droid.Renderers.BoxedView;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(LabelCell), typeof(LabelCellRenderer))]
namespace Bit.Droid.Renderers.BoxedView
{
[Preserve(AllMembers = true)]
public class LabelCellRenderer : BaseCellRenderer<LabelCellView>
{ }
[Preserve(AllMembers = true)]
public class LabelCellView : BaseCellView
{
private bool _debugWithColors = false;
private TextView _valueLabel;
public LabelCellView(Context context, Cell cell)
: base(context, cell)
{
_valueLabel = new TextView(context)
{
Ellipsize = TextUtils.TruncateAt.End,
Gravity = GravityFlags.Left,
};
_valueLabel.SetSingleLine(true);
using(var lParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent,
ViewGroup.LayoutParams.WrapContent))
{
CellContent.AddView(_valueLabel, lParams);
}
if(_debugWithColors)
{
_valueLabel.Background = _Context.GetDrawable(Android.Resource.Color.HoloRedLight);
}
}
private LabelCell LabelCell => Cell as LabelCell;
public override void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.CellPropertyChanged(sender, e);
if(e.PropertyName == LabelCell.ValueTextProperty.PropertyName)
{
UpdateValueText();
}
else if(e.PropertyName == LabelCell.ValueTextFontSizeProperty.PropertyName)
{
UpdateValueTextFontSize();
}
else if(e.PropertyName == LabelCell.ValueTextColorProperty.PropertyName)
{
UpdateValueTextColor();
}
}
public override void ParentPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.ParentPropertyChanged(sender, e);
if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextColorProperty.PropertyName)
{
UpdateValueTextColor();
}
else if(e.PropertyName == App.Controls.BoxedView.BoxedView.CellValueTextFontSizeProperty.PropertyName)
{
UpdateValueTextFontSize();
}
}
public override void UpdateCell()
{
base.UpdateCell();
UpdateValueText();
UpdateValueTextColor();
UpdateValueTextFontSize();
}
protected void UpdateValueText()
{
_valueLabel.Text = LabelCell.ValueText;
}
private void UpdateValueTextFontSize()
{
if(LabelCell.ValueTextFontSize > 0)
{
_valueLabel.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)LabelCell.ValueTextFontSize);
}
else if(CellParent != null)
{
_valueLabel.SetTextSize(Android.Util.ComplexUnitType.Sp, (float)CellParent.CellValueTextFontSize);
}
Invalidate();
}
private void UpdateValueTextColor()
{
if(LabelCell.ValueTextColor != Color.Default)
{
_valueLabel.SetTextColor(LabelCell.ValueTextColor.ToAndroid());
}
else if(CellParent != null && CellParent.CellValueTextColor != Color.Default)
{
_valueLabel.SetTextColor(CellParent.CellValueTextColor.ToAndroid());
}
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
_valueLabel?.Dispose();
_valueLabel = null;
}
base.Dispose(disposing);
}
}
}

View file

@ -1,79 +0,0 @@
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.Views;
using Xamarin.Forms;
namespace Bit.Droid.Renderers
{
[Android.Runtime.Preserve(AllMembers = true)]
public static class RendererUtils
{
public static GravityFlags ToAndroidVertical(this LayoutAlignment formsAlignment)
{
switch(formsAlignment)
{
case LayoutAlignment.Start:
return GravityFlags.Top;
case LayoutAlignment.Center:
return GravityFlags.CenterVertical;
case LayoutAlignment.End:
return GravityFlags.Bottom;
default:
return GravityFlags.FillHorizontal;
}
}
public static GravityFlags ToAndroidHorizontal(this LayoutAlignment formsAlignment)
{
switch(formsAlignment)
{
case LayoutAlignment.Start:
return GravityFlags.Start;
case LayoutAlignment.Center:
return GravityFlags.CenterHorizontal;
case LayoutAlignment.End:
return GravityFlags.End;
default:
return GravityFlags.FillVertical;
}
}
public static GravityFlags ToAndroidHorizontal(this Xamarin.Forms.TextAlignment formsAlignment)
{
switch(formsAlignment)
{
case Xamarin.Forms.TextAlignment.Start:
return GravityFlags.Left | GravityFlags.CenterVertical;
case Xamarin.Forms.TextAlignment.Center:
return GravityFlags.Center | GravityFlags.CenterVertical;
case Xamarin.Forms.TextAlignment.End:
return GravityFlags.Right | GravityFlags.CenterVertical;
default:
return GravityFlags.Left | GravityFlags.CenterVertical;
}
}
public static RippleDrawable CreateRipple(Android.Graphics.Color color, Drawable background = null)
{
if(background == null)
{
var mask = new ColorDrawable(Android.Graphics.Color.White);
return new RippleDrawable(GetPressedColorSelector(color), null, mask);
}
return new RippleDrawable(GetPressedColorSelector(color), background, null);
}
public static ColorStateList GetPressedColorSelector(int pressedColor)
{
return new ColorStateList(
new int[][]
{
new int[]{}
},
new int[]
{
pressedColor,
});
}
}
}