mirror of
https://github.com/bitwarden/mobile
synced 2026-01-05 01:53:17 +00:00
Forms update with CollectionView conversion (#1374)
* Forms update with CollectionView conversion * updates * removed unnecessary import
This commit is contained in:
@@ -77,19 +77,19 @@
|
||||
<PackageReference Include="Portable.BouncyCastle">
|
||||
<Version>1.8.10</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.3-beta01" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.6" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.5.3.2</Version>
|
||||
<Version>1.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>121.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.0.0" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.1.0" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.1.0" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Migration" Version="1.0.6" />
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.3.0.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.2.0.7" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.7" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.8" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.2.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Migration" Version="1.0.8" />
|
||||
<PackageReference Include="Xamarin.Google.Dagger" Version="2.27.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
|
||||
<Version>117.0.0</Version>
|
||||
@@ -120,18 +120,17 @@
|
||||
<Compile Include="Receivers\EventUploadReceiver.cs" />
|
||||
<Compile Include="Receivers\LockAlarmReceiver.cs" />
|
||||
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
||||
<Compile Include="Renderers\CipherViewCellRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedGridRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedDatePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStackLayoutRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedTimePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEditorRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomPickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEntryRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedListViewRenderer.cs" />
|
||||
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||
<Compile Include="Renderers\SendViewCellRenderer.cs" />
|
||||
<Compile Include="Services\AndroidPushNotificationService.cs" />
|
||||
<Compile Include="Services\AndroidLogService.cs" />
|
||||
<Compile Include="MainApplication.cs" />
|
||||
@@ -173,6 +172,9 @@
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_foreground.xml" />
|
||||
<AndroidResource Include="Resources\drawable\id.xml" />
|
||||
<AndroidResource Include="Resources\drawable\info.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg_dark.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg_nord.xml" />
|
||||
<AndroidResource Include="Resources\drawable\lock.xml" />
|
||||
<AndroidResource Include="Resources\drawable\login.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo.xml" />
|
||||
@@ -185,7 +187,6 @@
|
||||
<AndroidResource Include="Resources\drawable\shield.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
|
||||
<AndroidResource Include="Resources\layout\SendViewCell.axml" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
|
||||
@@ -262,12 +263,6 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\CipherViewCell.axml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\app_restrictions.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.Runtime;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using FFImageLoading;
|
||||
using FFImageLoading.Views;
|
||||
using FFImageLoading.Work;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(CipherViewCell), typeof(CipherViewCellRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CipherViewCellRenderer : ViewCellRenderer
|
||||
{
|
||||
private static Typeface _faTypeface;
|
||||
private static Typeface _miTypeface;
|
||||
private static Android.Graphics.Color _textColor;
|
||||
private static Android.Graphics.Color _mutedColor;
|
||||
private static Android.Graphics.Color _disabledIconColor;
|
||||
private static bool _usingLightTheme;
|
||||
|
||||
private AndroidCipherCell _cell;
|
||||
|
||||
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView,
|
||||
ViewGroup parent, Context context)
|
||||
{
|
||||
// TODO expand beyond light/dark detection once we support custom theme switching without app restart
|
||||
var themeChanged = _usingLightTheme != ThemeManager.UsingLightTheme;
|
||||
if (_faTypeface == null)
|
||||
{
|
||||
_faTypeface = Typeface.CreateFromAsset(context.Assets, "FontAwesome.ttf");
|
||||
}
|
||||
if (_miTypeface == null)
|
||||
{
|
||||
_miTypeface = Typeface.CreateFromAsset(context.Assets, "MaterialIcons_Regular.ttf");
|
||||
}
|
||||
if (_textColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_textColor = ThemeManager.GetResourceColor("TextColor").ToAndroid();
|
||||
}
|
||||
if (_mutedColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_mutedColor = ThemeManager.GetResourceColor("MutedColor").ToAndroid();
|
||||
}
|
||||
if (_disabledIconColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_disabledIconColor = ThemeManager.GetResourceColor("DisabledIconColor").ToAndroid();
|
||||
}
|
||||
_usingLightTheme = ThemeManager.UsingLightTheme;
|
||||
|
||||
var cipherCell = item as CipherViewCell;
|
||||
_cell = convertView as AndroidCipherCell;
|
||||
if (_cell == null)
|
||||
{
|
||||
_cell = new AndroidCipherCell(context, cipherCell, _faTypeface, _miTypeface);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cell.CipherViewCell.PropertyChanged -= CellPropertyChanged;
|
||||
}
|
||||
cipherCell.PropertyChanged += CellPropertyChanged;
|
||||
_cell.UpdateCell(cipherCell);
|
||||
_cell.UpdateColors(_textColor, _mutedColor, _disabledIconColor);
|
||||
return _cell;
|
||||
}
|
||||
|
||||
public void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
var cipherCell = sender as CipherViewCell;
|
||||
_cell.CipherViewCell = cipherCell;
|
||||
if (e.PropertyName == CipherViewCell.CipherProperty.PropertyName)
|
||||
{
|
||||
_cell.UpdateCell(cipherCell);
|
||||
}
|
||||
else if (e.PropertyName == CipherViewCell.WebsiteIconsEnabledProperty.PropertyName)
|
||||
{
|
||||
_cell.UpdateIconImage(cipherCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AndroidCipherCell : LinearLayout, INativeElementView
|
||||
{
|
||||
private readonly Typeface _faTypeface;
|
||||
private readonly Typeface _miTypeface;
|
||||
|
||||
private IScheduledWork _currentTask;
|
||||
|
||||
public AndroidCipherCell(Context context, CipherViewCell cipherView, Typeface faTypeface, Typeface miTypeface)
|
||||
: base(context)
|
||||
{
|
||||
CipherViewCell = cipherView;
|
||||
_faTypeface = faTypeface;
|
||||
_miTypeface = miTypeface;
|
||||
|
||||
var view = (context as Activity).LayoutInflater.Inflate(Resource.Layout.CipherViewCell, null);
|
||||
IconImage = view.FindViewById<IconImageView>(Resource.Id.CipherCellIconImage);
|
||||
Icon = view.FindViewById<TextView>(Resource.Id.CipherCellIcon);
|
||||
Name = view.FindViewById<TextView>(Resource.Id.CipherCellName);
|
||||
SubTitle = view.FindViewById<TextView>(Resource.Id.CipherCellSubTitle);
|
||||
SharedIcon = view.FindViewById<TextView>(Resource.Id.CipherCellSharedIcon);
|
||||
AttachmentsIcon = view.FindViewById<TextView>(Resource.Id.CipherCellAttachmentsIcon);
|
||||
MoreButton = view.FindViewById<Android.Widget.Button>(Resource.Id.CipherCellButton);
|
||||
MoreButton.Click += MoreButton_Click;
|
||||
|
||||
Icon.Typeface = _faTypeface;
|
||||
SharedIcon.Typeface = _faTypeface;
|
||||
AttachmentsIcon.Typeface = _faTypeface;
|
||||
MoreButton.Typeface = _miTypeface;
|
||||
|
||||
var small = (float)Device.GetNamedSize(NamedSize.Small, typeof(Label));
|
||||
Icon.SetTextSize(ComplexUnitType.Pt, 10);
|
||||
Name.SetTextSize(ComplexUnitType.Sp, (float)Device.GetNamedSize(NamedSize.Medium, typeof(Label)));
|
||||
SubTitle.SetTextSize(ComplexUnitType.Sp, small);
|
||||
SharedIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
AttachmentsIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
MoreButton.SetTextSize(ComplexUnitType.Sp, 25);
|
||||
|
||||
AddView(view);
|
||||
}
|
||||
|
||||
public CipherViewCell CipherViewCell { get; set; }
|
||||
public Element Element => CipherViewCell;
|
||||
|
||||
public IconImageView IconImage { get; set; }
|
||||
public TextView Icon { get; set; }
|
||||
public TextView Name { get; set; }
|
||||
public TextView SubTitle { get; set; }
|
||||
public TextView SharedIcon { get; set; }
|
||||
public TextView AttachmentsIcon { get; set; }
|
||||
public Android.Widget.Button MoreButton { get; set; }
|
||||
|
||||
public void UpdateCell(CipherViewCell cipherCell)
|
||||
{
|
||||
UpdateIconImage(cipherCell);
|
||||
|
||||
var cipher = cipherCell.Cipher;
|
||||
Name.Text = cipher.Name;
|
||||
if (!string.IsNullOrWhiteSpace(cipher.SubTitle))
|
||||
{
|
||||
SubTitle.Text = cipher.SubTitle;
|
||||
SubTitle.Visibility = ViewStates.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubTitle.Visibility = ViewStates.Invisible;
|
||||
}
|
||||
SharedIcon.Visibility = cipher.Shared ? ViewStates.Visible : ViewStates.Gone;
|
||||
AttachmentsIcon.Visibility = cipher.HasAttachments ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
public void UpdateIconImage(CipherViewCell cipherCell)
|
||||
{
|
||||
if (_currentTask != null && !_currentTask.IsCancelled && !_currentTask.IsCompleted)
|
||||
{
|
||||
_currentTask.Cancel();
|
||||
}
|
||||
|
||||
var cipher = cipherCell.Cipher;
|
||||
|
||||
var iconImage = cipherCell.GetIconImage(cipher);
|
||||
if (iconImage.Item2 != null)
|
||||
{
|
||||
IconImage.SetImageResource(Resource.Drawable.login);
|
||||
IconImage.Visibility = ViewStates.Visible;
|
||||
Icon.Visibility = ViewStates.Gone;
|
||||
_currentTask = ImageService.Instance.LoadUrl(iconImage.Item2).DownSample(64).Into(IconImage);
|
||||
IconImage.Key = iconImage.Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
IconImage.Visibility = ViewStates.Gone;
|
||||
Icon.Visibility = ViewStates.Visible;
|
||||
Icon.Text = iconImage.Item1;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateColors(Android.Graphics.Color textColor, Android.Graphics.Color mutedColor,
|
||||
Android.Graphics.Color iconDisabledColor)
|
||||
{
|
||||
Name.SetTextColor(textColor);
|
||||
SubTitle.SetTextColor(mutedColor);
|
||||
Icon.SetTextColor(mutedColor);
|
||||
SharedIcon.SetTextColor(mutedColor);
|
||||
AttachmentsIcon.SetTextColor(mutedColor);
|
||||
MoreButton.SetTextColor(iconDisabledColor);
|
||||
}
|
||||
|
||||
private void MoreButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CipherViewCell.ButtonCommand?.CanExecute(CipherViewCell.Cipher) ?? false)
|
||||
{
|
||||
CipherViewCell.ButtonCommand.Execute(CipherViewCell.Cipher);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
MoreButton.Click -= MoreButton_Click;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
[Android.Runtime.Preserve(AllMembers = true)]
|
||||
[Register("bit.droid.renderers.IconImageView")]
|
||||
public class IconImageView : ImageViewAsync
|
||||
{
|
||||
public IconImageView(Context context) : base(context)
|
||||
{ }
|
||||
|
||||
public IconImageView(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{ }
|
||||
|
||||
public IconImageView(Context context, IAttributeSet attrs)
|
||||
: base(context, attrs)
|
||||
{ }
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
protected override void JavaFinalize()
|
||||
{
|
||||
SetImageDrawable(null);
|
||||
SetImageBitmap(null);
|
||||
ImageService.Instance.InvalidateCacheEntryAsync(Key, FFImageLoading.Cache.CacheType.Memory);
|
||||
base.JavaFinalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/Android/Renderers/ExtendedGridRenderer.cs
Normal file
43
src/Android/Renderers/ExtendedGridRenderer.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedGrid), typeof(ExtendedGridRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedGridRenderer : ViewRenderer
|
||||
{
|
||||
private static int? _bgResId;
|
||||
|
||||
public ExtendedGridRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
{
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(GetBgResId());
|
||||
}
|
||||
}
|
||||
|
||||
private int GetBgResId()
|
||||
{
|
||||
if (_bgResId == null)
|
||||
{
|
||||
if (ThemeManager.GetTheme(true) == "nord")
|
||||
{
|
||||
_bgResId = Resource.Drawable.list_item_bg_nord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgResId ??= ThemeManager.UsingLightTheme ? Resource.Drawable.list_item_bg :
|
||||
Resource.Drawable.list_item_bg_dark;
|
||||
}
|
||||
}
|
||||
return _bgResId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedListView), typeof(ExtendedListViewRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedListViewRenderer : ListViewRenderer
|
||||
{
|
||||
public ExtendedListViewRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && e.NewElement != null && e.NewElement is ExtendedListView listView)
|
||||
{
|
||||
// Pad for FAB
|
||||
Control.SetPadding(0, 0, 0, 170);
|
||||
Control.SetClipToPadding(false);
|
||||
Control.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/Android/Renderers/ExtendedStackLayoutRenderer.cs
Normal file
43
src/Android/Renderers/ExtendedStackLayoutRenderer.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedStackLayout), typeof(ExtendedStackLayoutRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedStackLayoutRenderer : ViewRenderer
|
||||
{
|
||||
private static int? _bgResId;
|
||||
|
||||
public ExtendedStackLayoutRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
{
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(GetBgResId());
|
||||
}
|
||||
}
|
||||
|
||||
private int GetBgResId()
|
||||
{
|
||||
if (_bgResId == null)
|
||||
{
|
||||
if (ThemeManager.GetTheme(true) == "nord")
|
||||
{
|
||||
_bgResId = Resource.Drawable.list_item_bg_nord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgResId ??= ThemeManager.UsingLightTheme ? Resource.Drawable.list_item_bg :
|
||||
Resource.Drawable.list_item_bg_dark;
|
||||
}
|
||||
}
|
||||
return _bgResId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using FFImageLoading.Work;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
using Button = Android.Widget.Button;
|
||||
using Color = Android.Graphics.Color;
|
||||
using View = Android.Views.View;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SendViewCell), typeof(SendViewCellRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class SendViewCellRenderer : ViewCellRenderer
|
||||
{
|
||||
private static Typeface _faTypeface;
|
||||
private static Typeface _miTypeface;
|
||||
private static Color _textColor;
|
||||
private static Color _mutedColor;
|
||||
private static Color _disabledIconColor;
|
||||
private static bool _usingLightTheme;
|
||||
|
||||
private AndroidSendCell _cell;
|
||||
|
||||
protected override View GetCellCore(Cell item, View convertView,
|
||||
ViewGroup parent, Context context)
|
||||
{
|
||||
// TODO expand beyond light/dark detection once we support custom theme switching without app restart
|
||||
var themeChanged = _usingLightTheme != ThemeManager.UsingLightTheme;
|
||||
if (_faTypeface == null)
|
||||
{
|
||||
_faTypeface = Typeface.CreateFromAsset(context.Assets, "FontAwesome.ttf");
|
||||
}
|
||||
if (_miTypeface == null)
|
||||
{
|
||||
_miTypeface = Typeface.CreateFromAsset(context.Assets, "MaterialIcons_Regular.ttf");
|
||||
}
|
||||
if (_textColor == default(Color) || themeChanged)
|
||||
{
|
||||
_textColor = ThemeManager.GetResourceColor("TextColor").ToAndroid();
|
||||
}
|
||||
if (_mutedColor == default(Color) || themeChanged)
|
||||
{
|
||||
_mutedColor = ThemeManager.GetResourceColor("MutedColor").ToAndroid();
|
||||
}
|
||||
if (_disabledIconColor == default(Color) || themeChanged)
|
||||
{
|
||||
_disabledIconColor = ThemeManager.GetResourceColor("DisabledIconColor").ToAndroid();
|
||||
}
|
||||
_usingLightTheme = ThemeManager.UsingLightTheme;
|
||||
|
||||
var sendCell = item as SendViewCell;
|
||||
_cell = convertView as AndroidSendCell;
|
||||
if (_cell == null)
|
||||
{
|
||||
_cell = new AndroidSendCell(context, sendCell, _faTypeface, _miTypeface);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cell.SendViewCell.PropertyChanged -= CellPropertyChanged;
|
||||
}
|
||||
sendCell.PropertyChanged += CellPropertyChanged;
|
||||
_cell.UpdateCell(sendCell);
|
||||
_cell.UpdateColors(_textColor, _mutedColor, _disabledIconColor);
|
||||
return _cell;
|
||||
}
|
||||
|
||||
public void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
var sendCell = sender as SendViewCell;
|
||||
_cell.SendViewCell = sendCell;
|
||||
if (e.PropertyName == SendViewCell.SendProperty.PropertyName)
|
||||
{
|
||||
_cell.UpdateCell(sendCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AndroidSendCell : LinearLayout, INativeElementView
|
||||
{
|
||||
private readonly Typeface _faTypeface;
|
||||
private readonly Typeface _miTypeface;
|
||||
|
||||
private IScheduledWork _currentTask;
|
||||
|
||||
public AndroidSendCell(Context context, SendViewCell sendView, Typeface faTypeface, Typeface miTypeface)
|
||||
: base(context)
|
||||
{
|
||||
SendViewCell = sendView;
|
||||
_faTypeface = faTypeface;
|
||||
_miTypeface = miTypeface;
|
||||
|
||||
var view = (context as Activity).LayoutInflater.Inflate(Resource.Layout.SendViewCell, null);
|
||||
Icon = view.FindViewById<TextView>(Resource.Id.SendCellIcon);
|
||||
Name = view.FindViewById<TextView>(Resource.Id.SendCellName);
|
||||
SubTitle = view.FindViewById<TextView>(Resource.Id.SendCellSubTitle);
|
||||
DisabledIcon = view.FindViewById<TextView>(Resource.Id.SendCellDisabledIcon);
|
||||
HasPasswordIcon = view.FindViewById<TextView>(Resource.Id.SendCellHasPasswordIcon);
|
||||
MaxAccessCountReachedIcon = view.FindViewById<TextView>(Resource.Id.SendCellMaxAccessCountReachedIcon);
|
||||
ExpiredIcon = view.FindViewById<TextView>(Resource.Id.SendCellExpiredIcon);
|
||||
PendingDeleteIcon = view.FindViewById<TextView>(Resource.Id.SendCellPendingDeleteIcon);
|
||||
MoreButton = view.FindViewById<Button>(Resource.Id.SendCellButton);
|
||||
MoreButton.Click += MoreButton_Click;
|
||||
|
||||
Icon.Typeface = _faTypeface;
|
||||
DisabledIcon.Typeface = _faTypeface;
|
||||
HasPasswordIcon.Typeface = _faTypeface;
|
||||
MaxAccessCountReachedIcon.Typeface = _faTypeface;
|
||||
ExpiredIcon.Typeface = _faTypeface;
|
||||
PendingDeleteIcon.Typeface = _faTypeface;
|
||||
MoreButton.Typeface = _miTypeface;
|
||||
|
||||
var small = (float)Device.GetNamedSize(NamedSize.Small, typeof(Label));
|
||||
Icon.SetTextSize(ComplexUnitType.Pt, 10);
|
||||
Name.SetTextSize(ComplexUnitType.Sp, (float)Device.GetNamedSize(NamedSize.Medium, typeof(Label)));
|
||||
SubTitle.SetTextSize(ComplexUnitType.Sp, small);
|
||||
DisabledIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
HasPasswordIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
MaxAccessCountReachedIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
ExpiredIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
PendingDeleteIcon.SetTextSize(ComplexUnitType.Sp, small);
|
||||
MoreButton.SetTextSize(ComplexUnitType.Sp, 25);
|
||||
|
||||
if (!SendViewCell.ShowOptions)
|
||||
{
|
||||
MoreButton.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
AddView(view);
|
||||
}
|
||||
|
||||
public SendViewCell SendViewCell { get; set; }
|
||||
public Element Element => SendViewCell;
|
||||
|
||||
public TextView Icon { get; set; }
|
||||
public TextView Name { get; set; }
|
||||
public TextView SubTitle { get; set; }
|
||||
public TextView DisabledIcon { get; set; }
|
||||
public TextView HasPasswordIcon { get; set; }
|
||||
public TextView MaxAccessCountReachedIcon { get; set; }
|
||||
public TextView ExpiredIcon { get; set; }
|
||||
public TextView PendingDeleteIcon { get; set; }
|
||||
public Button MoreButton { get; set; }
|
||||
|
||||
public void UpdateCell(SendViewCell sendCell)
|
||||
{
|
||||
UpdateIconImage(sendCell);
|
||||
|
||||
var send = sendCell.Send;
|
||||
Name.Text = send.Name;
|
||||
SubTitle.Text = send.DisplayDate;
|
||||
DisabledIcon.Visibility = send.Disabled ? ViewStates.Visible : ViewStates.Gone;
|
||||
HasPasswordIcon.Visibility = send.HasPassword ? ViewStates.Visible : ViewStates.Gone;
|
||||
MaxAccessCountReachedIcon.Visibility = send.MaxAccessCountReached ? ViewStates.Visible : ViewStates.Gone;
|
||||
ExpiredIcon.Visibility = send.Expired ? ViewStates.Visible : ViewStates.Gone;
|
||||
PendingDeleteIcon.Visibility = send.PendingDelete ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
public void UpdateIconImage(SendViewCell sendCell)
|
||||
{
|
||||
if (_currentTask != null && !_currentTask.IsCancelled && !_currentTask.IsCompleted)
|
||||
{
|
||||
_currentTask.Cancel();
|
||||
}
|
||||
|
||||
var send = sendCell.Send;
|
||||
var iconImage = sendCell.GetIconImage(send);
|
||||
Icon.Text = iconImage;
|
||||
}
|
||||
|
||||
public void UpdateColors(Color textColor, Color mutedColor,
|
||||
Color iconDisabledColor)
|
||||
{
|
||||
Name.SetTextColor(textColor);
|
||||
SubTitle.SetTextColor(mutedColor);
|
||||
Icon.SetTextColor(mutedColor);
|
||||
DisabledIcon.SetTextColor(mutedColor);
|
||||
HasPasswordIcon.SetTextColor(mutedColor);
|
||||
MaxAccessCountReachedIcon.SetTextColor(mutedColor);
|
||||
ExpiredIcon.SetTextColor(mutedColor);
|
||||
PendingDeleteIcon.SetTextColor(mutedColor);
|
||||
MoreButton.SetTextColor(iconDisabledColor);
|
||||
}
|
||||
|
||||
private void MoreButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (SendViewCell.ButtonCommand?.CanExecute(SendViewCell.Send) ?? false)
|
||||
{
|
||||
SendViewCell.ButtonCommand.Execute(SendViewCell.Send);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
MoreButton.Click -= MoreButton_Click;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/Android/Resources/drawable/list_item_bg.xml
Normal file
7
src/Android/Resources/drawable/list_item_bg.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/itemPressed">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
</ripple>
|
||||
7
src/Android/Resources/drawable/list_item_bg_dark.xml
Normal file
7
src/Android/Resources/drawable/list_item_bg_dark.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/dark_primary">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
</ripple>
|
||||
7
src/Android/Resources/drawable/list_item_bg_nord.xml
Normal file
7
src/Android/Resources/drawable/list_item_bg_nord.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/nord_primary">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
</ripple>
|
||||
@@ -1,86 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:minHeight="44dp"
|
||||
android:gravity="center_vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="2.2dp">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="39.8dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center">
|
||||
<bit.droid.renderers.IconImageView
|
||||
android:id="@+id/CipherCellIconImage"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center" />
|
||||
<TextView
|
||||
android:id="@+id/CipherCellIcon"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="[X]" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/CipherCellContent"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="7.65dp">
|
||||
<LinearLayout
|
||||
android:id="@+id/CipherCellContentTop"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/CipherCellName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="Name" />
|
||||
<TextView
|
||||
android:id="@+id/CipherCellSharedIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
<TextView
|
||||
android:id="@+id/CipherCellAttachmentsIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/CipherCellSubTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="SubTitle" />
|
||||
</LinearLayout>
|
||||
<Button
|
||||
android:id="@+id/CipherCellButton"
|
||||
android:layout_width="37dp"
|
||||
android:layout_height="match_parent"
|
||||
android:text=""
|
||||
android:gravity="center"
|
||||
android:padding="0dp"
|
||||
android:background="@android:color/transparent" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
@@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:minHeight="44dp"
|
||||
android:gravity="center_vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="2.2dp">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="39.8dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/SendCellIcon"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="[X]" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/SendCellContent"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="7.65dp">
|
||||
<LinearLayout
|
||||
android:id="@+id/SendCellContentTop"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/SendCellName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="Name" />
|
||||
<TextView
|
||||
android:id="@+id/SendCellDisabledIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
<TextView
|
||||
android:id="@+id/SendCellHasPasswordIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
<TextView
|
||||
android:id="@+id/SendCellMaxAccessCountReachedIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
<TextView
|
||||
android:id="@+id/SendCellExpiredIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
<TextView
|
||||
android:id="@+id/SendCellPendingDeleteIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="5dp"
|
||||
android:singleLine="true"
|
||||
android:text="" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/SendCellSubTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="SubTitle" />
|
||||
</LinearLayout>
|
||||
<Button
|
||||
android:id="@+id/SendCellButton"
|
||||
android:layout_width="37dp"
|
||||
android:layout_height="match_parent"
|
||||
android:text=""
|
||||
android:gravity="center"
|
||||
android:padding="0dp"
|
||||
android:background="@android:color/transparent" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
@@ -6,6 +6,7 @@
|
||||
<color name="primary">#175DDC</color>
|
||||
<color name="notificationBar">#1452BC</color>
|
||||
<color name="border">#dddddd</color>
|
||||
<color name="itemPressed">#bbbbbb</color>
|
||||
|
||||
<!-- Dark theme -->
|
||||
<color name="dark_primary">#52bdfb</color>
|
||||
|
||||
Reference in New Issue
Block a user