Added initial implemention for Android

This commit is contained in:
Jon Lipsky 2019-06-23 21:00:02 -06:00
Родитель f98c912170
Коммит 3644e5dd7f
66 изменённых файлов: 1720 добавлений и 12852 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -402,4 +402,5 @@ ASALocalRun/
.mfractor/
# Local History for Visual Studio
.localhistory/
.localhistory/
Resource.designer.cs

Просмотреть файл

@ -1,4 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Loader", "src\Xamarin.Forms.Loader\Xamarin.Forms.Loader.csproj", "{B2AB3B6E-89C6-4223-ACFF-4E3C027868A9}"
@ -27,6 +27,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotUI.Samples", "sample\Hot
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotUI.Mac", "src\HotUI.Mac\HotUI.Mac.csproj", "{BCAF5569-30DB-4D44-BF46-DFFE93DDCBD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotUI.Android", "src\HotUI.Android\HotUI.Android.csproj", "{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotUI.Android.Sample", "sample\HotUI.Android.Sample\HotUI.Android.Sample.csproj", "{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -157,6 +161,30 @@ Global
{BCAF5569-30DB-4D44-BF46-DFFE93DDCBD0}.Debug|iPhone.Build.0 = Debug|Any CPU
{BCAF5569-30DB-4D44-BF46-DFFE93DDCBD0}.Release|iPhone.ActiveCfg = Release|Any CPU
{BCAF5569-30DB-4D44-BF46-DFFE93DDCBD0}.Release|iPhone.Build.0 = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|Any CPU.Build.0 = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Debug|iPhone.Build.0 = Debug|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|iPhone.ActiveCfg = Release|Any CPU
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}.Release|iPhone.Build.0 = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|Any CPU.Build.0 = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Debug|iPhone.Build.0 = Debug|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|iPhone.ActiveCfg = Release|Any CPU
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}.Release|iPhone.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{B2AB3B6E-89C6-4223-ACFF-4E3C027868A9} = {AB9AD206-4B1E-4B0C-88A2-5C769314E8A4}
@ -169,5 +197,7 @@ Global
{12BE5947-A64A-4968-96A6-5CA3CE36C244} = {C3FDCDB7-0C29-472D-A406-E2F21A4B0EAE}
{D058A769-9AE6-438F-960C-2ECC287F6D1E} = {C3FDCDB7-0C29-472D-A406-E2F21A4B0EAE}
{BCAF5569-30DB-4D44-BF46-DFFE93DDCBD0} = {AB9AD206-4B1E-4B0C-88A2-5C769314E8A4}
{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D} = {AB9AD206-4B1E-4B0C-88A2-5C769314E8A4}
{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D} = {C3FDCDB7-0C29-472D-A406-E2F21A4B0EAE}
EndGlobalSection
EndGlobal

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,19 @@
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories) and given a Build Action of "AndroidAsset".
These files will be deployed with you package and will be accessible using Android's
AssetManager, like this:
public class ReadAsset : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
InputStream input = Assets.Open ("my_asset.txt");
}
}
Additionally, some Android functions will automatically load asset files:
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");

Просмотреть файл

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1B3F8AD2-4252-44CA-8DD6-A7702C46A25D}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{84dd83c5-0fe3-4294-9419-09e7c8ba324f}</TemplateGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HotUI.Android.Sample</RootNamespace>
<AssemblyName>HotUI.Android.Sample</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidApplication>True</AndroidApplication>
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidManagedSymbols>true</AndroidManagedSymbols>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Mono.Android" />
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AboutResources.txt" />
<None Include="Properties\AndroidManifest.xml" />
<None Include="Assets\AboutAssets.txt" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\activity_main.axml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\layout\content_main.axml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\values\dimens.xml" />
<AndroidResource Include="Resources\values\ic_launcher_background.xml" />
<AndroidResource Include="Resources\values\strings.xml" />
<AndroidResource Include="Resources\values\styles.xml" />
<AndroidResource Include="Resources\menu\menu_main.xml" />
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher_round.xml" />
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_foreground.png" />
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_foreground.png" />
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_foreground.png" />
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_foreground.png" />
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_foreground.png" />
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Android.Support.Design" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.FFImageLoading">
<Version>2.4.11.982</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\HotUI\HotUI.csproj">
<Project>{1817646E-E71E-48CF-80A4-3030EF870D61}</Project>
<Name>HotUI</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\HotUI.Android\HotUI.Android.csproj">
<Project>{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}</Project>
<Name>HotUI.Android</Name>
</ProjectReference>
<ProjectReference Include="..\HotUI.Samples\HotUI.Samples.csproj">
<Project>{D058A769-9AE6-438F-960C-2ECC287F6D1E}</Project>
<Name>HotUI.Samples</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,27 @@
using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using HotUI.Samples;
namespace HotUI.Android.Sample
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : HotActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Page = new MainPage();
}
}
}

Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.xamarin.hotui_android_sample">
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="28" />
<application android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

Просмотреть файл

@ -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("HotUI.Android.Sample")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HotUI.Android.Sample")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[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")]

Просмотреть файл

@ -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.

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

Просмотреть файл

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!" />
</RelativeLayout>

Просмотреть файл

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>

Двоичные данные
sample/HotUI.Android.Sample/Resources/mipmap-hdpi/ic_launcher.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичные данные
sample/HotUI.Android.Sample/Resources/mipmap-mdpi/ic_launcher.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 958 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичные данные
sample/HotUI.Android.Sample/Resources/mipmap-xhdpi/ic_launcher.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#2c3e50</color>
<color name="colorPrimaryDark">#1B3147</color>
<color name="colorAccent">#3498db</color>
</resources>

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#2C3E50</color>
</resources>

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="app_name">HotUI.Android.Sample</string>
<string name="action_settings">Settings</string>
</resources>

Просмотреть файл

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<!-- Base application theme. -->
<style name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay"
parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay"
parent="ThemeOverlay.AppCompat.Light" />
</resources>

Просмотреть файл

@ -0,0 +1,23 @@
using Android.App;
namespace HotUI.Android
{
public delegate void ContextChanged(Activity activity);
public static class AndroidContext
{
public static event ContextChanged ContextChanged;
private static Activity _context;
public static Activity CurrentContext
{
get => _context;
set
{
_context = value;
ContextChanged?.Invoke(_context);
}
}
}
}

Просмотреть файл

@ -0,0 +1,61 @@
using Android.App;
using AView = Android.Views.View;
namespace HotUI.Android
{
public static partial class AndroidExtensions
{
static AndroidExtensions()
{
HotUI.Android.UI.Init();
}
/*public static Activity ToActivity(this HotPage hotPage)
{
if (hotPage == null)
return null;
var handler = hotPage.ViewHandler;
if (handler == null)
{
handler = Registrar.Pages.GetRenderer(hotPage.GetType()) as IViewContainer;
hotPage.ViewHandler = handler;
hotPage.ReBuildView();
}
var page = handler as IViewContainer;
return page.Activity;
}*/
public static AView ToView(this HotPage hotPage, Activity activity)
{
if (hotPage == null)
return null;
var handler = hotPage.ViewHandler;
if (handler == null)
{
handler = Registrar.Pages.GetRenderer(hotPage.GetType()) as IViewContainer;
hotPage.ViewHandler = handler;
hotPage.ReBuildView();
}
var page = handler as IViewContainer;
return page.View;
}
public static AView ToView(this View view)
{
if (view == null)
return null;
var handler = view.ViewHandler;
if (handler == null)
{
handler = Registrar.Handlers.GetRenderer(view.GetType()) as IViewHandler;
view.ViewHandler = handler;
}
var page = handler as IView;
return page.View;
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using AView = Android.Views.View;
namespace HotUI.Android
{
public static partial class ControlExtensions
{
public static void UpdateProperties(this AView view, View hView)
{
}
public static void UpdateBaseProperties(this AView view, View hView)
{
view.UpdateProperties(hView);
}
public static bool UpdateProperty(this AView view, string property, object value)
{
return false;
}
public static bool UpdateBaseProperty(this AView view, string property, object value) => view.UpdateProperty(property, value);
}
}

Просмотреть файл

@ -0,0 +1,57 @@
using System;
using AButton = Android.Widget.Button;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class ButtonHandler : AButton, IViewHandler, IView
{
public ButtonHandler() : base(AndroidContext.CurrentContext)
{
Click += HandleClick;
}
private void HandleClick(object sender, EventArgs e) => button?.OnClick();
public AView View => this;
Button button;
public void Remove(View view)
{
button = null;
}
public void SetView(View view)
{
button = view as Button;
this.UpdateProperties(button);
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this AButton view, Button hView)
{
view.Text = hView?.Text;
view.UpdateBaseProperties(hView);
}
public static bool UpdateProperty(this AButton view, string property, object value)
{
switch (property)
{
case nameof(Button.Text):
view.Text = (string) value;
return true;
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
using System;
using Android.Content;
using Android.Runtime;
using Android.Widget;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class EntryHandler : EditText, IView
{
public EntryHandler() : base(AndroidContext.CurrentContext)
{
TextChanged += HandleTextChanged;
}
private void HandleTextChanged(object sender, EventArgs e) => entry?.Completed(Text);
public AView View => this;
public void Remove(View view)
{
entry = null;
}
Entry entry;
public void SetView(View view)
{
entry = view as Entry;
this.UpdateProperties(entry);
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this EditText view, Entry hView)
{
view.Text = hView?.Text;
view.UpdateBaseProperties(hView);
}
public static bool UpdateProperty(this EditText view, string property, object value)
{
switch (property)
{
case nameof(Entry.Text):
view.Text = (string) value;
return true;
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
using Android.App;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class HotPageHandler : IViewContainer
{
HotPage hotpage;
AView currentView;
public AView View => currentView;
public void Remove(View view)
{
// todo: implement this
}
public void SetView(View view)
{
currentView = view.ToView();
}
public void SetViewBuilder(ViewBuilder builder)
{
hotpage = builder as HotPage;
if (hotpage.View == null)
hotpage.ReBuildView();
// todo: needs to be implemented
}
public void UpdateValue(string property, object value)
{
// todo: needs to be implemented
}
}
}

Просмотреть файл

@ -0,0 +1,100 @@
using System;
using FFImageLoading;
using System.Threading.Tasks;
using System.Diagnostics;
using Android.Content;
using Android.Runtime;
using Android.Widget;
using FFImageLoading.Drawables;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class ImageHandler : ImageView, IView
{
public ImageHandler() : base(AndroidContext.CurrentContext)
{
}
public AView View => throw new NotImplementedException();
private Image image;
public void Remove(View view)
{
image = null;
}
public void SetView(View view)
{
image = view as Image;
this.UpdateProperties(image);
}
public void UpdateValue(string property, object value)
{
}
string currentSource;
public async void UpdateSource(string source)
{
if (source == currentSource)
return;
currentSource = source;
try
{
var image = await source.LoadImage();
if (source == currentSource)
this.SetImageBitmap(image.Bitmap);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this ImageHandler view, Image hView)
{
view.UpdateSource(hView.Source);
view.UpdateBaseProperties(hView);
}
public static bool UpdateProperty(this ImageHandler view, string property, object value)
{
switch (property)
{
case nameof(Image.Source):
view.UpdateSource((string) value);
return true;
}
return view.UpdateBaseProperty(property, value);
}
public static Task<SelfDisposingBitmapDrawable> LoadImage(this string source)
{
var isUrl = Uri.IsWellFormedUriString(source, UriKind.RelativeOrAbsolute);
if (isUrl)
return LoadImageAsync(source);
return LoadFileAsync(source);
}
private static Task<SelfDisposingBitmapDrawable> LoadImageAsync(string urlString)
{
return ImageService.Instance
.LoadUrl(urlString)
.AsBitmapDrawableAsync();
}
private static Task<SelfDisposingBitmapDrawable> LoadFileAsync(string filePath)
{
return ImageService.Instance
.LoadFile(filePath)
.AsBitmapDrawableAsync();
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
using System;
using Android.Content;
using Android.Runtime;
using Android.Widget;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class LabelHandler : TextView, IViewHandler, IView
{
public AView View => this;
public LabelHandler() : base(AndroidContext.CurrentContext)
{
}
public void Remove(View view)
{
}
public void SetView(View view)
{
var label = view as Label;
this.UpdateLabelProperties(label);
}
public void UpdateValue(string property, object value)
{
this.UpdateLabelProperty(property, value);
}
}
public static partial class ControlExtensions
{
public static void UpdateLabelProperties(this TextView view, Label hView)
{
view.Text = hView?.Text;
view.UpdateBaseProperties(hView);
}
public static bool UpdateLabelProperty(this TextView view, string property, object value)
{
switch (property)
{
case nameof(Label.Text):
view.Text = (string) value;
return true;
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -0,0 +1,52 @@
using System;
using Android.Content;
using Android.Runtime;
using AView = Android.Views.View;
using AScrollView = Android.Widget.ScrollView;
namespace HotUI.Android
{
public class ScrollViewHandler : AScrollView, IView
{
public ScrollViewHandler() : base(AndroidContext.CurrentContext)
{
}
public AView View => this;
public void Remove(View view)
{
if (content != null)
{
RemoveView(content);
content = null;
}
}
AView content;
public void SetView(View view)
{
var scroll = view as ScrollView;
var newContent = scroll?.View?.ToView();
if (content == null || newContent != content)
{
if (content != null)
RemoveView(content);
content = newContent;
if (content != null)
base.AddView(content);
}
this.UpdateProperties(view);
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
}

Просмотреть файл

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Graphics;
using Android.Runtime;
using Android.Widget;
using AView = Android.Views.View;
namespace HotUI.Android
{
public class StackHandler : LinearLayout, IViewHandler, IView
{
public StackHandler() : base(AndroidContext.CurrentContext)
{
Orientation = Orientation.Vertical;
base.SetBackgroundColor(Color.Green);
}
public AView View => this;
public void Remove(View view)
{
}
Stack stack;
public void SetView(View view)
{
stack = view as Stack;
UpdateChildren(stack);
stack.ChildrenChanged += Stack_ChildrenChanged;
}
private void Stack_ChildrenChanged(object sender, EventArgs e)
{
UpdateChildren(stack);
}
public void UpdateValue(string property, object value)
{
}
List<AView> views = new List<AView>();
protected void UpdateChildren(Stack stack)
{
var children = stack.GetChildren();
if (views.Count == children.Count)
{
bool areSame = false;
for (var i = 0; i < views.Count; i++)
{
var v = views[i];
var c = children[i].ToView();
areSame = c == v;
if (!areSame)
{
break;
}
}
if (areSame)
return;
}
foreach (var v in views)
{
base.RemoveView(v);
}
views.Clear();
foreach (var child in children)
{
var cview = child.ToView();
views.Add(cview);
//cview.ContentMode = UIViewContentMode.Top;
base.AddView(cview);
}
}
}
}

Просмотреть файл

@ -0,0 +1,86 @@
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using AView = Android.Views.View;
namespace HotUI.Android
{
public abstract class HotActivity : AppCompatActivity
{
private HotPage _page;
public HotPage Page
{
get => _page;
set
{
_page = value;
SetContentView(_page?.ToView(this));
}
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
AndroidContext.CurrentContext = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] global::Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnRestart()
{
base.OnRestart();
_page?.OnAppearing();
}
protected override void OnResume()
{
base.OnResume();
_page?.OnAppearing();
}
protected override void OnStart()
{
base.OnStart();
_page?.OnAppearing();
}
protected override void OnStop()
{
base.OnStop();
_page?.OnDisppearing();
}
protected override void OnPause()
{
base.OnPause();
_page?.OnDisppearing();
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this Activity view, HotPage hView)
{
view.Title = hView.Title;
}
public static bool UpdateProperty(this Activity view, string property, object value)
{
switch (property)
{
case nameof(HotPage.Title):
view.Title = (string) value;
return true;
}
return false;
}
}
}

Просмотреть файл

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1E8FBBC2-9E06-4960-A116-65CDEFEFE11D}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HotUI.Android</RootNamespace>
<AssemblyName>HotUI.Android</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Android.Support.v7.AppCompat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\..\..\..\Users\jlipsky\.nuget\packages\xamarin.android.support.v7.appcompat\28.0.0.1\lib\monoandroid90\Xamarin.Android.Support.v7.AppCompat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AndroidContext.cs" />
<Compile Include="Extensions\ControlExtensions.cs" />
<Compile Include="Extensions\AndroidExtensions.cs" />
<Compile Include="Handlers\ButtonHandler.cs" />
<Compile Include="Handlers\EntryHandler.cs" />
<Compile Include="Handlers\HotPageHandler.cs" />
<Compile Include="Handlers\ImageHandler.cs" />
<Compile Include="Handlers\LabelHandler.cs" />
<Compile Include="Handlers\ScrollViewHandler.cs" />
<Compile Include="Handlers\StackHandler.cs" />
<Compile Include="HotActivity.cs" />
<Compile Include="IView.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AboutResources.txt" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\strings.xml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\drawable\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HotUI\HotUI.csproj">
<Project>{1817646e-e71e-48cf-80a4-3030ef870d61}</Project>
<Name>HotUI</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.FFImageLoading" Version="2.4.11.982" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,15 @@
using Android.App;
using AView = Android.Views.View;
namespace HotUI.Android
{
public interface IView : IViewHandler
{
AView View { get; }
}
public interface IViewContainer : IViewBuilderHandler
{
AView View { get; }
}
}

Просмотреть файл

@ -0,0 +1,28 @@
using System.Reflection;
using System.Runtime.InteropServices;
// 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("HotUI.Android")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HotUI.Android")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[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")]

Просмотреть файл

@ -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.

Просмотреть файл

@ -0,0 +1,4 @@
<resources>
<string name="hello">Hello World, Click Me!</string>
<string name="app_name">HotUI.Android</string>
</resources>

22
src/HotUI.Android/UI.cs Normal file
Просмотреть файл

@ -0,0 +1,22 @@
namespace HotUI.Android
{
public static class UI
{
static bool hasInit;
public static void Init()
{
if (hasInit)
return;
hasInit = true;
Registrar.Handlers.Register<Button, ButtonHandler>();
Registrar.Handlers.Register<Entry, EntryHandler>();
Registrar.Handlers.Register<Label, LabelHandler>();
Registrar.Handlers.Register<Stack, StackHandler>();
//Registrar.Handlers.Register<WebView, WebViewHandler> ();
Registrar.Handlers.Register<ScrollView, ScrollViewHandler>();
Registrar.Pages.Register<HotPage, HotPageHandler>();
}
}
}

Просмотреть файл

@ -1,22 +1,23 @@
using AppKit;
namespace HotUI.Mac.Extensions {
public static partial class ControlExtensions {
public static void UpdateProperties (this NSView view, View hView)
{
namespace HotUI.Mac.Extensions
{
public static partial class ControlExtensions
{
public static void UpdateProperties(this NSView view, View hView)
{
}
}
public static void UpdateBaseProperties (this NSView view, View hView)
{
view.UpdateProperties (hView);
}
public static void UpdateBaseProperties(this NSView view, View hView)
{
view.UpdateProperties(hView);
}
public static bool UpdateProperty (this NSView view, string property, object value)
{
return false;
}
public static bool UpdateBaseProperty (this NSView view, string property, object value) => view.UpdateProperty (property, value);
public static bool UpdateProperty(this NSView view, string property, object value)
{
return false;
}
}
}
public static bool UpdateBaseProperty(this NSView view, string property, object value) => view.UpdateProperty(property, value);
}
}

Просмотреть файл

@ -1,40 +1,43 @@
using AppKit;
namespace HotUI.Mac.Extensions {
public static partial class MacExtensions {
namespace HotUI.Mac.Extensions
{
public static partial class MacExtensions
{
static MacExtensions()
{
UI.Init();
}
public static NSViewController ToViewController(this HotPage hotPage)
{
if (hotPage == null)
return null;
var handler = hotPage.ViewHandler;
if (handler == null)
{
handler = Registrar.Pages.GetRenderer(hotPage.GetType()) as IViewBuilderHandler;
hotPage.ViewHandler = handler;
hotPage.ReBuildView();
}
static MacExtensions()
{
UI.Init ();
}
public static NSViewController ToViewController (this HotPage hotPage)
{
if (hotPage == null)
return null;
var handler = hotPage.ViewHandler;
if (handler == null) {
var page = handler as INSViewController;
return page.ViewController;
}
handler = Registrar.Pages.GetRenderer (hotPage.GetType ()) as IViewBuilderHandler;
hotPage.ViewHandler = handler;
hotPage.ReBuildView ();
}
var page = handler as INSViewController;
return page.ViewController;
}
public static NSView ToView(this View view)
{
if (view == null)
return null;
var handler = view.ViewHandler;
if (handler == null)
{
handler = Registrar.Handlers.GetRenderer(view.GetType()) as IViewHandler;
view.ViewHandler = handler;
}
public static NSView ToView (this View view)
{
if (view == null)
return null;
var handler = view.ViewHandler;
if (handler == null) {
handler = Registrar.Handlers.GetRenderer (view.GetType ()) as IViewHandler;
view.ViewHandler = handler;
}
var page = handler as INSView;
return page.View;
}
}
}
var page = handler as INSView;
return page.View;
}
}
}

Просмотреть файл

@ -2,51 +2,55 @@
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class ButtonHandler : NSButton, IViewHandler, INSView {
public ButtonHandler ()
{
Activated += ButtonHandler_TouchUpInside;
}
namespace HotUI.Mac.Handlers
{
public class ButtonHandler : NSButton, IViewHandler, INSView
{
public ButtonHandler()
{
Activated += ButtonHandler_TouchUpInside;
}
private void ButtonHandler_TouchUpInside (object sender, EventArgs e) => button?.OnClick ();
private void ButtonHandler_TouchUpInside(object sender, EventArgs e) => button?.OnClick();
public NSView View => this;
public NSView View => this;
Button button;
public void Remove (View view)
{
Button button;
}
public void Remove(View view)
{
}
public void SetView (View view)
{
button = view as Button;
this.UpdateProperties (button);
}
public void SetView(View view)
{
button = view as Button;
this.UpdateProperties(button);
}
public void UpdateValue (string property, object value)
{
this.UpdateProperty (property, value);
}
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
public static partial class ControlExtensions {
public static partial class ControlExtensions
{
public static void UpdateProperties(this NSButton view, Button hView)
{
view.Title = hView?.Text;
view.UpdateBaseProperties(hView);
}
public static void UpdateProperties (this NSButton view, Button hView)
{
view.Title = hView?.Text;
view.UpdateBaseProperties (hView);
}
public static bool UpdateProperty(this NSButton view, string property, object value)
{
switch (property)
{
case nameof(Button.Text):
view.Title = (string) value;
return true;
}
public static bool UpdateProperty (this NSButton view, string property, object value)
{
switch (property) {
case nameof (Button.Text):
view.Title = (string)value;
return true;
}
return view.UpdateBaseProperty (property, value);
}
}
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -2,53 +2,56 @@
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class EntryHandler : NSTextField, INSView {
public EntryHandler ()
{
EditingEnded += EntryHandler_Ended;
}
namespace HotUI.Mac.Handlers
{
public class EntryHandler : NSTextField, INSView
{
public EntryHandler()
{
EditingEnded += EntryHandler_Ended;
}
void EntryHandler_Ended (object sender, EventArgs e) => entry?.Completed (StringValue);
void EntryHandler_Ended(object sender, EventArgs e) => entry?.Completed(StringValue);
public NSView View => this;
public NSView View => this;
public void Remove (View view)
{
entry = null;
}
Entry entry;
public void SetView (View view)
{
entry = view as Entry;
this.UpdateProperties (entry);
public void Remove(View view)
{
entry = null;
}
}
Entry entry;
public void UpdateValue (string property, object value)
{
this.UpdateProperty (property, value);
}
public void SetView(View view)
{
entry = view as Entry;
this.UpdateProperties(entry);
}
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this NSTextField view, Entry hView)
{
view.StringValue = hView?.Text;
view.UpdateBaseProperties(hView);
}
public static partial class ControlExtensions {
public static bool UpdateProperty(this NSTextField view, string property, object value)
{
switch (property)
{
case nameof(Entry.Text):
view.StringValue = (string) value;
return true;
}
public static void UpdateProperties (this NSTextField view, Entry hView)
{
view.StringValue = hView?.Text;
view.UpdateBaseProperties (hView);
}
public static bool UpdateProperty (this NSTextField view, string property, object value)
{
switch (property) {
case nameof (Entry.Text):
view.StringValue = (string)value;
return true;
}
return view.UpdateBaseProperty (property, value);
}
}
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -1,71 +1,77 @@
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class HotPageHandler : NSViewController, INSViewController {
namespace HotUI.Mac.Handlers
{
public class HotPageHandler : NSViewController, INSViewController
{
public NSViewController ViewController => this;
public NSViewController ViewController => this;
NSView currentView;
NSView currentView;
public void Remove (View view)
{
currentView?.RemoveFromSuperview ();
}
public void Remove(View view)
{
currentView?.RemoveFromSuperview();
}
public void SetView (View view)
{
currentView?.RemoveFromSuperview ();
currentView = view.ToView ();
View.AddSubview(currentView);
}
HotPage hotpage;
public void SetViewBuilder (ViewBuilder builder)
{
hotpage = builder as HotPage;
if (hotpage.View == null)
hotpage.ReBuildView ();
this.UpdateProperties (hotpage);
}
public void SetView(View view)
{
currentView?.RemoveFromSuperview();
currentView = view.ToView();
View.AddSubview(currentView);
}
public void UpdateValue (string property, object value)
{
this.UpdateProperty (property, value);
}
HotPage hotpage;
public override void ViewWillAppear()
{
base.ViewWillAppear();
hotpage?.OnAppearing ();
}
public override void ViewWillDisappear ()
{
base.ViewWillDisappear ();
hotpage?.OnDisppearing ();
}
public override void LoadView ()
{
base.LoadView ();
View.Layer.BackgroundColor = NSColor.Gray.CGColor;
}
}
public void SetViewBuilder(ViewBuilder builder)
{
hotpage = builder as HotPage;
if (hotpage.View == null)
hotpage.ReBuildView();
this.UpdateProperties(hotpage);
}
public static partial class ControlExtensions {
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
public static void UpdateProperties (this NSViewController view, HotPage hView)
{
view.Title = hView.Title;
}
public override void ViewWillAppear()
{
base.ViewWillAppear();
hotpage?.OnAppearing();
}
public static bool UpdateProperty (this NSViewController view, string property, object value)
{
switch (property) {
case nameof (HotPage.Title):
view.Title = (string)value;
return true;
}
return false;
}
}
}
public override void ViewWillDisappear()
{
base.ViewWillDisappear();
hotpage?.OnDisppearing();
}
public override void LoadView()
{
base.LoadView();
View.Layer.BackgroundColor = NSColor.Gray.CGColor;
}
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this NSViewController view, HotPage hView)
{
view.Title = hView.Title;
}
public static bool UpdateProperty(this NSViewController view, string property, object value)
{
switch (property)
{
case nameof(HotPage.Title):
view.Title = (string) value;
return true;
}
return false;
}
}
}

Просмотреть файл

@ -4,88 +4,96 @@ using System.Threading.Tasks;
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class ImageHandler : NSImageView, INSView {
public ImageHandler ()
{
}
namespace HotUI.Mac.Handlers
{
public class ImageHandler : NSImageView, INSView
{
public ImageHandler()
{
}
public NSView View => throw new NotImplementedException ();
public NSView View => throw new NotImplementedException();
public void Remove (View view)
{
throw new NotImplementedException ();
}
public void Remove(View view)
{
throw new NotImplementedException();
}
public void SetView (View view)
{
throw new NotImplementedException ();
}
public void SetView(View view)
{
throw new NotImplementedException();
}
public void UpdateValue (string property, object value)
{
throw new NotImplementedException ();
}
string currentSource;
public async void UpdateSource(string source)
{
if (source == currentSource)
return;
currentSource = source;
try {
var image = await source.LoadImage ();
if (source == currentSource)
this.Image = image;
} catch(Exception e) {
Debug.WriteLine (e);
}
}
}
public void UpdateValue(string property, object value)
{
throw new NotImplementedException();
}
public static partial class ControlExtensions {
string currentSource;
public static void UpdateProperties (this ImageHandler view, Image hView)
{
view.UpdateSource (hView.Source);
view.UpdateBaseProperties (hView);
}
public async void UpdateSource(string source)
{
if (source == currentSource)
return;
currentSource = source;
try
{
var image = await source.LoadImage();
if (source == currentSource)
this.Image = image;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
}
public static bool UpdateProperty (this ImageHandler view, string property, object value)
{
switch (property) {
case nameof (Image.Source):
view.UpdateSource ((string)value);
return true;
}
return view.UpdateBaseProperty (property, value);
}
public static partial class ControlExtensions
{
public static void UpdateProperties(this ImageHandler view, Image hView)
{
view.UpdateSource(hView.Source);
view.UpdateBaseProperties(hView);
}
public static Task<NSImage> LoadImage(this string source)
{
var isUrl = Uri.IsWellFormedUriString (source, UriKind.RelativeOrAbsolute);
if (isUrl)
return LoadImageAsync (source);
return LoadFileAsync (source);
}
public static bool UpdateProperty(this ImageHandler view, string property, object value)
{
switch (property)
{
case nameof(Image.Source):
view.UpdateSource((string) value);
return true;
}
private static Task<NSImage> LoadImageAsync (string urlString)
{
throw new NotImplementedException();
/*
return ImageService.Instance
.LoadUrl (urlString)
.AsUIImageAsync ();*/
}
return view.UpdateBaseProperty(property, value);
}
private static Task<NSImage> LoadFileAsync (string filePath)
{
throw new NotImplementedException();
/*
return ImageService.Instance
.LoadFile (filePath)
.AsUIImageAsync ();*/
}
public static Task<NSImage> LoadImage(this string source)
{
var isUrl = Uri.IsWellFormedUriString(source, UriKind.RelativeOrAbsolute);
if (isUrl)
return LoadImageAsync(source);
return LoadFileAsync(source);
}
}
}
private static Task<NSImage> LoadImageAsync(string urlString)
{
throw new NotImplementedException();
/*
return ImageService.Instance
.LoadUrl (urlString)
.AsUIImageAsync ();*/
}
private static Task<NSImage> LoadFileAsync(string filePath)
{
throw new NotImplementedException();
/*
return ImageService.Instance
.LoadFile (filePath)
.AsUIImageAsync ();*/
}
}
}

Просмотреть файл

@ -1,50 +1,51 @@
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class LabelHandler : NSTextField, IViewHandler, INSView {
namespace HotUI.Mac.Handlers
{
public class LabelHandler : NSTextField, IViewHandler, INSView
{
public NSView View => this;
public NSView View => this;
public LabelHandler()
{
Editable = false;
}
public LabelHandler()
{
Editable = false;
}
public void Remove (View view)
{
public void Remove(View view)
{
}
}
public void SetView(View view)
{
var label = view as Label;
this.UpdateLabelProperties(label);
}
public void SetView (View view)
{
var label = view as Label;
this.UpdateLabelProperties (label);
public void UpdateValue(string property, object value)
{
this.UpdateLabelProperty(property, value);
}
}
}
public static partial class ControlExtensions
{
public static void UpdateLabelProperties(this NSTextField view, Label hView)
{
view.StringValue = hView?.Text;
view.UpdateBaseProperties(hView);
}
public void UpdateValue (string property, object value)
{
this.UpdateLabelProperty (property, value);
}
}
public static bool UpdateLabelProperty(this NSTextField view, string property, object value)
{
switch (property)
{
case nameof(Label.Text):
view.StringValue = (string) value;
return true;
}
public static partial class ControlExtensions {
public static void UpdateLabelProperties (this NSTextField view, Label hView)
{
view.StringValue = hView?.Text;
view.UpdateBaseProperties (hView);
}
public static bool UpdateLabelProperty (this NSTextField view, string property, object value)
{
switch (property) {
case nameof (Label.Text):
view.StringValue = (string)value;
return true;
}
return view.UpdateBaseProperty (property, value);
}
}
}
return view.UpdateBaseProperty(property, value);
}
}
}

Просмотреть файл

@ -1,35 +1,40 @@
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class ScrollViewHandler : NSScrollView, INSView {
public NSView View => this;
namespace HotUI.Mac.Handlers
{
public class ScrollViewHandler : NSScrollView, INSView
{
public NSView View => this;
public void Remove (View view)
{
content?.RemoveFromSuperview ();
}
NSView content;
public void SetView (View view)
{
var scroll = view as ScrollView;
public void Remove(View view)
{
content?.RemoveFromSuperview();
}
content = scroll?.View?.ToView ();
if(content != null)
AddSubview(content);
this.UpdateProperties (view);
NSLayoutConstraint.ActivateConstraints (new []{
content.LeadingAnchor.ConstraintEqualToAnchor (this.LeadingAnchor),
content.TrailingAnchor.ConstraintEqualToAnchor (this.TrailingAnchor),
content.TopAnchor.ConstraintEqualToAnchor (this.TopAnchor),
content.BottomAnchor.ConstraintEqualToAnchor (this.BottomAnchor),
});
NSView content;
}
public void SetView(View view)
{
var scroll = view as ScrollView;
public void UpdateValue (string property, object value)
{
this.UpdateProperty (property, value);
}
}
}
content = scroll?.View?.ToView();
if (content != null)
AddSubview(content);
this.UpdateProperties(view);
NSLayoutConstraint.ActivateConstraints(
new[]
{
content.LeadingAnchor.ConstraintEqualToAnchor(this.LeadingAnchor),
content.TrailingAnchor.ConstraintEqualToAnchor(this.TrailingAnchor),
content.TopAnchor.ConstraintEqualToAnchor(this.TopAnchor),
content.BottomAnchor.ConstraintEqualToAnchor(this.BottomAnchor),
});
}
public void UpdateValue(string property, object value)
{
this.UpdateProperty(property, value);
}
}
}

Просмотреть файл

@ -3,94 +3,102 @@ using System.Collections.Generic;
using AppKit;
using HotUI.Mac.Extensions;
namespace HotUI.Mac.Handlers {
public class StackHandler : NSStackView, IViewHandler, INSView {
namespace HotUI.Mac.Handlers
{
public class StackHandler : NSStackView, IViewHandler, INSView
{
public StackHandler()
{
this.Orientation = NSUserInterfaceLayoutOrientation.Vertical;
this.Alignment = NSLayoutAttribute.Left & NSLayoutAttribute.Right;
this.Spacing = 0;
this.Distribution = NSStackViewDistribution.Fill;
public StackHandler ()
{
this.Orientation = NSUserInterfaceLayoutOrientation.Vertical;
this.Alignment = NSLayoutAttribute.Left & NSLayoutAttribute.Right;
this.Spacing = 0;
this.Distribution = NSStackViewDistribution.Fill;
this.Layer.BackgroundColor = NSColor.Green.CGColor;
this.TranslatesAutoresizingMaskIntoConstraints = false;
}
this.Layer.BackgroundColor = NSColor.Green.CGColor;
this.TranslatesAutoresizingMaskIntoConstraints = false;
}
public NSView View => this;
public void Remove (View view)
{
public NSView View => this;
}
Stack stack;
public void SetView (View view)
{
stack = view as Stack;
UpdateChildren (stack);
stack.ChildrenChanged += Stack_ChildrenChanged;
}
public void Remove(View view)
{
}
private void Stack_ChildrenChanged (object sender, EventArgs e)
{
UpdateChildren (stack);
}
Stack stack;
public void UpdateValue (string property, object value)
{
public void SetView(View view)
{
stack = view as Stack;
UpdateChildren(stack);
stack.ChildrenChanged += Stack_ChildrenChanged;
}
}
List<NSView> views = new List<NSView> ();
protected void UpdateChildren (Stack stack)
{
var children = stack.GetChildren ();
if (views.Count == children.Count) {
bool areSame = false;
for (var i = 0; i < views.Count; i++) {
var v = views [i];
var c = children [i].ToView ();
areSame = c == v;
if (!areSame) {
break;
}
}
if (areSame)
return;
}
private void Stack_ChildrenChanged(object sender, EventArgs e)
{
UpdateChildren(stack);
}
foreach (var v in views) {
RemoveArrangedSubview (v);
v.RemoveFromSuperview ();
}
views.Clear ();
foreach (var child in children) {
var cview = child.ToView ();
views.Add (cview);
//cview.ContentMode = UIViewContentMode.Top;
AddSubview (cview);
AddArrangedSubview (cview);
public void UpdateValue(string property, object value)
{
}
}
List<NSView> views = new List<NSView>();
protected void UpdateChildren(Stack stack)
{
var children = stack.GetChildren();
if (views.Count == children.Count)
{
bool areSame = false;
for (var i = 0; i < views.Count; i++)
{
var v = views[i];
var c = children[i].ToView();
areSame = c == v;
if (!areSame)
{
break;
}
}
//var children = stack.GetChildren ();
//var childrenCount = children.Count;
//var maxInt = Math.Max (Subviews.Length, childrenCount);
//for (var i = 0; i < maxInt; i++) {
// if (i >= childrenCount) {
// Subviews [i].RemoveFromSuperview ();
// continue;
// }
// if (i >= Subviews.Length) {
// this.Add (children [i].ToView ());
// }
// var cView = children [i].ToView ();
// if (Subviews [i] == cView)
// continue;
if (areSame)
return;
}
// Subviews [i].RemoveFromSuperview();
// InsertSubview (cView, i);
//}
foreach (var v in views)
{
RemoveArrangedSubview(v);
v.RemoveFromSuperview();
}
}
}
}
views.Clear();
foreach (var child in children)
{
var cview = child.ToView();
views.Add(cview);
//cview.ContentMode = ViewContentMode.Top;
AddSubview(cview);
AddArrangedSubview(cview);
}
//var children = stack.GetChildren ();
//var childrenCount = children.Count;
//var maxInt = Math.Max (Subviews.Length, childrenCount);
//for (var i = 0; i < maxInt; i++) {
// if (i >= childrenCount) {
// Subviews [i].RemoveFromSuperview ();
// continue;
// }
// if (i >= Subviews.Length) {
// this.Add (children [i].ToView ());
// }
// var cView = children [i].ToView ();
// if (Subviews [i] == cView)
// continue;
// Subviews [i].RemoveFromSuperview();
// InsertSubview (cView, i);
//}
}
}
}

Просмотреть файл

@ -1,10 +1,14 @@
using AppKit;
namespace HotUI.Mac {
public interface INSView : IViewHandler {
NSView View { get; }
}
public interface INSViewController : IViewBuilderHandler {
NSViewController ViewController { get; }
}
}
namespace HotUI.Mac
{
public interface INSView : IViewHandler
{
NSView View { get; }
}
public interface INSViewController : IViewBuilderHandler
{
NSViewController ViewController { get; }
}
}

Просмотреть файл

@ -23,4 +23,4 @@ using System.Runtime.CompilerServices;
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
//[assembly: AssemblyKeyFile("")]

Просмотреть файл

@ -1,21 +1,24 @@
using HotUI.Mac.Handlers;
namespace HotUI.Mac {
public static class UI {
static bool hasInit;
public static void Init ()
{
if (hasInit)
return;
hasInit = true;
Registrar.Handlers.Register<Button, ButtonHandler> ();
Registrar.Handlers.Register<Entry, EntryHandler> ();
Registrar.Handlers.Register<Label, LabelHandler> ();
Registrar.Handlers.Register<Stack, StackHandler> ();
//Registrar.Handlers.Register<WebView, WebViewHandler> ();
Registrar.Handlers.Register<ScrollView, ScrollViewHandler> ();
namespace HotUI.Mac
{
public static class UI
{
static bool hasInit;
Registrar.Pages.Register<HotPage, HotPageHandler> ();
}
}
}
public static void Init()
{
if (hasInit)
return;
hasInit = true;
Registrar.Handlers.Register<Button, ButtonHandler>();
Registrar.Handlers.Register<Entry, EntryHandler>();
Registrar.Handlers.Register<Label, LabelHandler>();
Registrar.Handlers.Register<Stack, StackHandler>();
//Registrar.Handlers.Register<WebView, WebViewHandler> ();
Registrar.Handlers.Register<ScrollView, ScrollViewHandler>();
Registrar.Pages.Register<HotPage, HotPageHandler>();
}
}
}

Просмотреть файл

@ -10,6 +10,7 @@ namespace HotUI.iOS {
public void Remove (View view)
{
currentView?.RemoveFromSuperview ();
currentView = null;
}
public void SetView (View view)

Просмотреть файл

@ -1,17 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>pdbonly</DebugType>
<DefineConstants>TRACE;DEBUG;NETSTANDARD;NETSTANDARD2_0</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType></DebugType>
<DefineConstants>TRACE;RELEASE;NETSTANDARD;NETSTANDARD2_0</DefineConstants>

Просмотреть файл

@ -1,4 +1,5 @@
using System;
namespace HotUI {
public interface IViewHandler {
void SetView (View view);