From 6d8951027221504119eb40f6d9df0735e13142ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:43:24 +0200 Subject: [PATCH 01/13] Added AppBuilder and Initialize --- .../Avalonia.Android/AndroidPlatform.cs | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 1840e90886..bbb6c904dc 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -1,17 +1,27 @@ +using System; +using System.IO; using Avalonia.Android.CanvasRendering; using Avalonia.Android.Platform; using Avalonia.Android.Platform.Input; -using Avalonia.Android.Platform.Specific; +using Avalonia.Android.Platform.SkiaPlatform; +using Avalonia.Controls; using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Platform; using Avalonia.Shared.PlatformSupport; -using Avalonia.Skia; -using System; -using System.Collections.Generic; -using Avalonia.Android.Platform.SkiaPlatform; -using System.IO; + +namespace Avalonia +{ + public static class AndroidApplicationExtensions + { + public static AppBuilder UseAndroid(this AppBuilder builder) + { + builder.WindowingSubsystem = Avalonia.Android.AndroidPlatform.Initialize; + return builder; + } + } +} namespace Avalonia.Android { @@ -25,26 +35,23 @@ namespace Avalonia.Android private readonly double _scalingFactor = 1; - AndroidPlatform() + public AndroidPlatform() + { + _scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity; + } + + public static void Initialize() { AvaloniaLocator.CurrentMutable .Bind().ToTransient() .Bind().ToTransient() .Bind().ToSingleton() .Bind().ToSingleton() - .Bind().ToConstant(this) + .Bind().ToConstant(Instance) .Bind().ToConstant(new AndroidThreadingInterface()) .Bind().ToTransient() .Bind().ToTransient() - .Bind().ToConstant(this); - - SkiaPlatform.Initialize(); - - _scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity; - - - //we have custom Assetloader so no need to overwrite it - + .Bind().ToConstant(Instance); } public void Init(Type applicationType) From a5837a9683ce481a282c298916c76a7a726a42b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:43:32 +0200 Subject: [PATCH 02/13] Fixed AssemblyName --- .../Avalonia.AndroidTestApplication.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj index a90acabed0..2d6fbb289d 100644 --- a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj +++ b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj @@ -10,7 +10,7 @@ Library Properties Avalonia.AndroidTestApplication - Avalonia Test Application + Avalonia.AndroidTestApplication 512 true Resources\Resource.Designer.cs From 3cce058c39762412c95bf4c44f7fb67a95b7fc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:47:53 +0200 Subject: [PATCH 03/13] Render simple rectangle using SkiaSharp --- src/Skia/Avalonia.Skia/RenderTarget.cs | 68 ++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/src/Skia/Avalonia.Skia/RenderTarget.cs b/src/Skia/Avalonia.Skia/RenderTarget.cs index 1e1a5ff29d..6e6f5df0e0 100644 --- a/src/Skia/Avalonia.Skia/RenderTarget.cs +++ b/src/Skia/Avalonia.Skia/RenderTarget.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; + using Avalonia.Media; using Avalonia.Platform; using SkiaSharp; @@ -13,6 +11,9 @@ using CoreGraphics; using UIKit; #elif WIN32 using Avalonia.Win32.Interop; +#elif __ANDROID__ +using Android.Graphics; +using Android.Views; #endif namespace Avalonia.Skia @@ -36,13 +37,13 @@ namespace Avalonia.Skia internal class WindowRenderTarget : RenderTarget { - private readonly IntPtr _hwnd; + private readonly IPlatformHandle _hwnd; SKBitmap _bitmap; int Width { get; set; } int Height { get; set; } - public WindowRenderTarget(IntPtr hwnd) + public WindowRenderTarget(IPlatformHandle hwnd) { _hwnd = hwnd; FixSize(); @@ -70,7 +71,7 @@ namespace Avalonia.Skia private void FixSize() { int width, height; - GetPlatformWindowSize(_hwnd, out width, out height); + GetPlatformWindowSize(out width, out height); if (Width == width && Height == height) return; @@ -96,7 +97,7 @@ namespace Avalonia.Skia Surface = SKSurface.Create(_bitmap.Info, pixels, _bitmap.RowBytes); } - private void GetPlatformWindowSize(IntPtr hwnd, out int w, out int h) + private void GetPlatformWindowSize(out int w, out int h) { #if __IOS__ var bounds = GetApplicationFrame(); @@ -105,9 +106,13 @@ namespace Avalonia.Skia #elif WIN32 UnmanagedMethods.RECT rc; - UnmanagedMethods.GetClientRect(_hwnd, out rc); + UnmanagedMethods.GetClientRect(_hwnd.Handle, out rc); w = rc.right - rc.left; h = rc.bottom - rc.top; +#elif __ANDROID__ + var surfaceView = _hwnd as SurfaceView; + w = surfaceView.Width; + h = surfaceView.Height; #else throw new NotImplementedException(); #endif @@ -134,6 +139,9 @@ namespace Avalonia.Skia new WindowDrawingContextImpl(this)); } +#if __ANDROID__ + private Bitmap bitmap; +#endif public void Present() { _bitmap.LockPixels(); @@ -166,7 +174,7 @@ namespace Avalonia.Skia bmi.biCompression = (uint)UnmanagedMethods.BitmapCompressionMode.BI_RGB; bmi.biSizeImage = 0; - IntPtr hdc = UnmanagedMethods.GetDC(_hwnd); + IntPtr hdc = UnmanagedMethods.GetDC(_hwnd.Handle); int ret = UnmanagedMethods.SetDIBitsToDevice(hdc, 0, 0, @@ -177,7 +185,47 @@ namespace Avalonia.Skia ref bmi, (uint)UnmanagedMethods.DIBColorTable.DIB_RGB_COLORS); - UnmanagedMethods.ReleaseDC(_hwnd, hdc); + UnmanagedMethods.ReleaseDC(_hwnd.Handle, hdc); +#elif __ANDROID__ + var surfaceView = _hwnd as SurfaceView; + Canvas canvas = null; + try + { + canvas = surfaceView.Holder.LockCanvas(null); + + if (bitmap == null || bitmap.Width != canvas.Width || bitmap.Height != canvas.Height) + { + if (bitmap != null) + bitmap.Dispose(); + + bitmap = Bitmap.CreateBitmap(canvas.Width, canvas.Height, Bitmap.Config.Argb8888); + } + + try + { + using (var surface = SKSurface.Create(canvas.Width, canvas.Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, bitmap.LockPixels(), canvas.Width * 4)) + { + var skCanvas = surface.Canvas; + skCanvas.Scale(((float)canvas.Width) / (float)surfaceView.Width, ((float)canvas.Height) / (float)surfaceView.Height); + + skCanvas.DrawRect(SKRect.Create(100, 100, 300, 300), new SKPaint() { Color = SKColors.Red }); + } + } + finally + { + bitmap.UnlockPixels(); + } + + canvas.DrawBitmap(bitmap, 0, 0, null); + } + catch (Exception) + { + } + finally + { + if (canvas != null) + surfaceView.Holder.UnlockCanvasAndPost(canvas); + } #endif _bitmap.UnlockPixels(); From 07a7bd033f25c5fcff478b2c91a9648929dec0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:48:16 +0200 Subject: [PATCH 04/13] Do not Initialize Skia --- src/Skia/Avalonia.Skia.Android/SkiaView.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Skia/Avalonia.Skia.Android/SkiaView.cs b/src/Skia/Avalonia.Skia.Android/SkiaView.cs index f045ddbbf5..a45a80cf18 100644 --- a/src/Skia/Avalonia.Skia.Android/SkiaView.cs +++ b/src/Skia/Avalonia.Skia.Android/SkiaView.cs @@ -26,7 +26,6 @@ namespace Avalonia.Skia.Android public SkiaView(Activity context) : base(context) { _context = context; - SkiaPlatform.Initialize(); Holder.AddCallback(this); _handler = new Handler(context.MainLooper); } From 4c9540eed77661a39a819bba79899ee4dad50e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:48:35 +0200 Subject: [PATCH 05/13] Use platform handle --- src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index cb6d0547e9..91de9bf2c9 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -71,7 +71,7 @@ namespace Avalonia.Skia public IRenderTarget CreateRenderer(IPlatformHandle handle) { - return new WindowRenderTarget(handle.Handle); + return new WindowRenderTarget(handle); } } } From efe76e59c46de55c41ec213a15145c64a7fb5f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 21:48:52 +0200 Subject: [PATCH 06/13] Add SetContentView to draw view --- .../MainActivity.cs | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs index 514513bf35..f8979dcd71 100644 --- a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs +++ b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs @@ -1,11 +1,15 @@ using Android.App; using Android.Content.PM; using Android.OS; +using Android.Views; using Avalonia.Android; using Avalonia.Android.Platform.Specific; using Avalonia.Android.Platform.Specific.Helpers; +using Avalonia.Controls; using Avalonia.Controls.Platform; +using Avalonia.Media; using Avalonia.Platform; +using Avalonia.Skia.Android; using TestApplication; namespace Avalonia.AndroidTestApplication @@ -26,6 +30,7 @@ namespace Avalonia.AndroidTestApplication { base.OnCreate(savedInstanceState); + /* App app; if (Avalonia.Application.Current != null) app = (App)Avalonia.Application.Current; @@ -38,7 +43,83 @@ namespace Avalonia.AndroidTestApplication window.Show(); app.Run(window); + */ + + + + App app; + if (Avalonia.Application.Current != null) + app = (App)Avalonia.Application.Current; + else + { + app = new App(); + AppBuilder.Configure(app) + .UseAndroid() + .UseSkia() + .SetupWithoutStarting(); + } + + SetContentView(new MainView(this)); + + } - + + + + + + class MainView : SkiaRenderView + { + float _radians = 0; + public MainView(Activity context) : base(context) + { + } + + protected override void OnRender(DrawingContext ctx) + { + ctx.FillRectangle(Brushes.Green, new Rect(0, 0, Width, Height)); + + var rc = new Rect(0, 0, Width / 3, Height / 3); + using (ctx.PushPostTransform( + Avalonia.Matrix.CreateTranslation(-Width / 6, -Width / 6) * + Avalonia.Matrix.CreateRotation(_radians) * + Avalonia.Matrix.CreateTranslation(Width / 2, Height / 2))) + { + ctx.FillRectangle(new LinearGradientBrush() + { + GradientStops = + { + new GradientStop() {Color = Colors.Blue}, + new GradientStop(Colors.Red, 1) + } + }, rc, 5); + } + + + } + + public override bool OnTouchEvent(MotionEvent e) + { + if (e.Action == MotionEventActions.Down) + return true; + if (e.Action == MotionEventActions.Move) + { + _radians = (e.RawY + e.RawY) / 100; + Invalidate(); + return true; + } + return base.OnTouchEvent(e); + } + } + + + + + + + + + + } } \ No newline at end of file From 704d6ae421e6fe08cffd760ae49a856abb8cdfe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 22:03:20 +0200 Subject: [PATCH 07/13] Draw current drawing context --- src/Skia/Avalonia.Skia/RenderTarget.cs | 42 ++++++++------------------ 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/src/Skia/Avalonia.Skia/RenderTarget.cs b/src/Skia/Avalonia.Skia/RenderTarget.cs index 6e6f5df0e0..38a3626f54 100644 --- a/src/Skia/Avalonia.Skia/RenderTarget.cs +++ b/src/Skia/Avalonia.Skia/RenderTarget.cs @@ -38,8 +38,11 @@ namespace Avalonia.Skia internal class WindowRenderTarget : RenderTarget { private readonly IPlatformHandle _hwnd; +#if __ANDROID__ + Bitmap _bitmap; +#else SKBitmap _bitmap; - +#endif int Width { get; set; } int Height { get; set; } @@ -88,6 +91,10 @@ namespace Avalonia.Skia _bitmap.Dispose(); } +#if __ANDROID__ + _bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); + Surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, _bitmap.LockPixels(), width * 4); +#else _bitmap = new SKBitmap(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul); IntPtr length; @@ -95,6 +102,7 @@ namespace Avalonia.Skia // Wrap the bitmap in a Surface and keep it cached Surface = SKSurface.Create(_bitmap.Info, pixels, _bitmap.RowBytes); +#endif } private void GetPlatformWindowSize(out int w, out int h) @@ -139,14 +147,13 @@ namespace Avalonia.Skia new WindowDrawingContextImpl(this)); } -#if __ANDROID__ - private Bitmap bitmap; -#endif public void Present() { +#if !__ANDROID__ _bitmap.LockPixels(); IntPtr length; var pixels = _bitmap.GetPixels(out length); +#endif #if __IOS__ const int bitmapInfo = ((int)CGBitmapFlags.ByteOrder32Big) | ((int)CGImageAlphaInfo.PremultipliedLast); @@ -192,31 +199,8 @@ namespace Avalonia.Skia try { canvas = surfaceView.Holder.LockCanvas(null); - - if (bitmap == null || bitmap.Width != canvas.Width || bitmap.Height != canvas.Height) - { - if (bitmap != null) - bitmap.Dispose(); - - bitmap = Bitmap.CreateBitmap(canvas.Width, canvas.Height, Bitmap.Config.Argb8888); - } - - try - { - using (var surface = SKSurface.Create(canvas.Width, canvas.Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, bitmap.LockPixels(), canvas.Width * 4)) - { - var skCanvas = surface.Canvas; - skCanvas.Scale(((float)canvas.Width) / (float)surfaceView.Width, ((float)canvas.Height) / (float)surfaceView.Height); - - skCanvas.DrawRect(SKRect.Create(100, 100, 300, 300), new SKPaint() { Color = SKColors.Red }); - } - } - finally - { - bitmap.UnlockPixels(); - } - - canvas.DrawBitmap(bitmap, 0, 0, null); + _bitmap.UnlockPixels(); + canvas.DrawBitmap(_bitmap, 0, 0, null); } catch (Exception) { From 69e05384ca9b9d76f607dd50ef84ff3db67043d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 22:14:48 +0200 Subject: [PATCH 08/13] Code cleanup --- src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 4 ---- src/Skia/Avalonia.Skia/RenderTarget.cs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index 91de9bf2c9..05edcdd9ee 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Avalonia.Media; using Avalonia.Platform; using SkiaSharp; diff --git a/src/Skia/Avalonia.Skia/RenderTarget.cs b/src/Skia/Avalonia.Skia/RenderTarget.cs index 38a3626f54..f57ac2168f 100644 --- a/src/Skia/Avalonia.Skia/RenderTarget.cs +++ b/src/Skia/Avalonia.Skia/RenderTarget.cs @@ -1,11 +1,10 @@ using System; - using Avalonia.Media; using Avalonia.Platform; using SkiaSharp; // TODO: I'm not sure the best way to bring in the platform specific rendering -// + #if __IOS__ using CoreGraphics; using UIKit; From e24ed497842ceadcc8be991bb1ee14f5478e238b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 22:15:20 +0200 Subject: [PATCH 09/13] Fixed Avalonia.Skia.Android.TestApp --- src/Skia/Avalonia.Skia.Android.TestApp/App.cs | 7 +++++ .../Avalonia.Skia.Android.TestApp.csproj | 28 +++++++++++++------ .../MainActivity.cs | 25 +++++++++++------ .../Resources/Resource.Designer.cs | 2 ++ 4 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 src/Skia/Avalonia.Skia.Android.TestApp/App.cs diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/App.cs b/src/Skia/Avalonia.Skia.Android.TestApp/App.cs new file mode 100644 index 0000000000..ca4d36b820 --- /dev/null +++ b/src/Skia/Avalonia.Skia.Android.TestApp/App.cs @@ -0,0 +1,7 @@ + +namespace Avalonia.Skia.Android.TestApp +{ + public class App : Application + { + } +} diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj b/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj index 6f3b8e0add..e229881a8d 100644 --- a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj +++ b/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj @@ -20,22 +20,19 @@ Properties\AndroidManifest.xml - true + True full false bin\Debug\ DEBUG;TRACE prompt 4 - False + True None - - True + False False False - armeabi-v7a,x86 - - + armeabi;armeabi-v7a;x86 Xamarin False True @@ -48,7 +45,17 @@ prompt 4 False - SdkOnly + Full + True + False + False + Xamarin + False + False + False + False + False + armeabi;armeabi-v7a;x86 @@ -61,6 +68,7 @@ + @@ -70,6 +78,10 @@ + + {7b92af71-6287-4693-9dcb-bd5b6e927e23} + Avalonia.Android + {d211e587-d8bc-45b9-95a4-f297c8fa5200} Avalonia.Animation diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs b/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs index 6a681c80e3..9ac833a559 100644 --- a/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs +++ b/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs @@ -1,15 +1,9 @@ -using System; using Android.App; -using Android.Content; -using Android.Graphics; -using Android.Runtime; -using Android.Views; -using Android.Widget; using Android.OS; -using Android.Util; -using Avalonia.Media; -using Avalonia.Platform; +using Android.Views; using Avalonia; +using Avalonia.Controls; +using Avalonia.Media; namespace Avalonia.Skia.Android.TestApp { @@ -20,6 +14,19 @@ namespace Avalonia.Skia.Android.TestApp protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); + + App app; + if (Avalonia.Application.Current != null) + app = (App)Avalonia.Application.Current; + else + { + app = new App(); + AppBuilder.Configure(app) + .UseAndroid() + .UseSkia() + .SetupWithoutStarting(); + } + SetContentView(new MainView(this)); } diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs index aafbf9f315..7d9036603f 100644 --- a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs +++ b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs @@ -26,6 +26,8 @@ namespace Avalonia.Skia.Android.TestApp public static void UpdateIdValues() { + global::Avalonia.Android.Resource.String.ApplicationName = global::Avalonia.Skia.Android.TestApp.Resource.String.ApplicationName; + global::Avalonia.Android.Resource.String.Hello = global::Avalonia.Skia.Android.TestApp.Resource.String.Hello; } public partial class Attribute From 9be6a6ea592c6645a959b7404c555effeaec5414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 8 Aug 2016 22:54:28 +0200 Subject: [PATCH 10/13] Simplify test app --- Avalonia.sln | 1 - .../Avalonia.AndroidTestApplication.csproj | 1 - .../MainActivity.cs | 121 +++++++----------- 3 files changed, 49 insertions(+), 74 deletions(-) diff --git a/Avalonia.sln b/Avalonia.sln index a67f75991a..b24894e310 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -190,7 +190,6 @@ Global samples\TestApplicationShared\TestApplicationShared.projitems*{e3a1060b-50d0-44e8-88b6-f44ef2e5bd72}*SharedItemsImports = 4 src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13 src\Shared\RenderHelpers\RenderHelpers.projitems*{fb05ac90-89ba-4f2f-a924-f37875fb547c}*SharedItemsImports = 4 - samples\TestApplicationShared\TestApplicationShared.projitems*{ff69b927-c545-49ae-8e16-3d14d621aa12}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU diff --git a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj index 2d6fbb289d..dfc28b6332 100644 --- a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj +++ b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj @@ -187,7 +187,6 @@ Avalonia.Skia.Android - + \ No newline at end of file diff --git a/samples/ControlCatalog.Android/GettingStarted.Xamarin b/samples/ControlCatalog.Android/GettingStarted.Xamarin new file mode 100644 index 0000000000..e9d4f6a411 --- /dev/null +++ b/samples/ControlCatalog.Android/GettingStarted.Xamarin @@ -0,0 +1,4 @@ + + GS\Android\CS\AndroidApp\GettingStarted.html + false + \ No newline at end of file diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs new file mode 100644 index 0000000000..3f357b0e70 --- /dev/null +++ b/samples/ControlCatalog.Android/MainActivity.cs @@ -0,0 +1,46 @@ +using System; +using Android.App; + +using Android.OS; +using Android.Content.PM; +using Avalonia.Android.Platform.Specific; +using Avalonia.Controls; +using Avalonia.Controls.Templates; +using Avalonia.Markup.Xaml; +using Avalonia.Media; +using Avalonia.Styling; +using Avalonia.Themes.Default; +using Avalonia; + +namespace ControlCatalog.Android +{ + [Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)] + public class MainActivity : AvaloniaActivity + { + public MainActivity() : base(typeof (App)) + { + + } + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + + App app; + if (Avalonia.Application.Current != null) + app = (App)Avalonia.Application.Current; + else + { + app = new App(); + AppBuilder.Configure(app) + .UseAndroid() + .UseSkia() + .SetupWithoutStarting(); + } + + var mainWindow = new MainWindow(); + app.Run(mainWindow); + } + } +} + diff --git a/samples/ControlCatalog.Android/Properties/AndroidManifest.xml b/samples/ControlCatalog.Android/Properties/AndroidManifest.xml new file mode 100644 index 0000000000..e39ec39f1c --- /dev/null +++ b/samples/ControlCatalog.Android/Properties/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/samples/ControlCatalog.Android/Properties/AssemblyInfo.cs b/samples/ControlCatalog.Android/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..baeec94648 --- /dev/null +++ b/samples/ControlCatalog.Android/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Android.App; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ControlCatalog.Android")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ControlCatalog.Android")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/ControlCatalog.Android/Resources/AboutResources.txt b/samples/ControlCatalog.Android/Resources/AboutResources.txt new file mode 100644 index 0000000000..c2bca974c4 --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/AboutResources.txt @@ -0,0 +1,44 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.axml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable/ + icon.png + + layout/ + main.axml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called "R" +(this is an Android convention) that contains the tokens for each one of the resources +included. For example, for the above Resources layout, this is what the R class would expose: + +public class R { + public class drawable { + public const int icon = 0x123; + } + + public class layout { + public const int main = 0x456; + } + + public class strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main +to reference the layout/main.axml file, or R.strings.first_string to reference the first +string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/samples/ControlCatalog.Android/Resources/Resource.Designer.cs b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs new file mode 100644 index 0000000000..96f0e76fd8 --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs @@ -0,0 +1,114 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +[assembly: global::Android.Runtime.ResourceDesignerAttribute("ControlCatalog.Android.Resource", IsApplication=true)] + +namespace ControlCatalog.Android +{ + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] + public partial class Resource + { + + static Resource() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + public static void UpdateIdValues() + { + global::Avalonia.Android.Resource.String.ApplicationName = global::ControlCatalog.Android.Resource.String.ApplicationName; + global::Avalonia.Android.Resource.String.Hello = global::ControlCatalog.Android.Resource.String.Hello; + } + + public partial class Attribute + { + + static Attribute() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Attribute() + { + } + } + + public partial class Drawable + { + + // aapt resource value: 0x7f020000 + public const int Icon = 2130837504; + + static Drawable() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Drawable() + { + } + } + + public partial class Id + { + + // aapt resource value: 0x7f050000 + public const int MyButton = 2131034112; + + static Id() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Id() + { + } + } + + public partial class Layout + { + + // aapt resource value: 0x7f030000 + public const int Main = 2130903040; + + static Layout() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private Layout() + { + } + } + + public partial class String + { + + // aapt resource value: 0x7f040001 + public const int ApplicationName = 2130968577; + + // aapt resource value: 0x7f040000 + public const int Hello = 2130968576; + + static String() + { + global::Android.Runtime.ResourceIdManager.UpdateIdValues(); + } + + private String() + { + } + } + } +} +#pragma warning restore 1591 diff --git a/samples/ControlCatalog.Android/Resources/drawable/Icon.png b/samples/ControlCatalog.Android/Resources/drawable/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8074c4c571b8cd19e27f4ee5545df367420686d7 GIT binary patch literal 4147 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 literal 0 HcmV?d00001 diff --git a/samples/ControlCatalog.Android/Resources/layout/Main.axml b/samples/ControlCatalog.Android/Resources/layout/Main.axml new file mode 100644 index 0000000000..570c96ad72 --- /dev/null +++ b/samples/ControlCatalog.Android/Resources/layout/Main.axml @@ -0,0 +1,13 @@ + + +