mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 01:48:25 +03:00
remove boxedview
This commit is contained in:
parent
68a85a2561
commit
4dd05cf10e
9 changed files with 0 additions and 1770 deletions
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue