[tests] Xamarin.Forms-Performance-Integration test (#818)
Add `tests/Xamarin.Forms-Performance-Integration` to measure UI app startup times. Add a new `<RunUITests/>` task to start an app/activity. Rename `@(UnitTestApk)` to `@(TestApk)`, as it also handles UI tests. Update `<ProcessLogcatTiming/>` to be able to process the `adb logcat` output of started Android Activity processes.
This commit is contained in:
Родитель
03407251f7
Коммит
09ba1ee45d
|
@ -148,15 +148,15 @@ make variable:
|
|||
## Running Individual `.apk` Projects
|
||||
|
||||
See also the [`tests/RunApkTests.targets`](../tests/RunApkTests.targets) and
|
||||
[`build-tools/scripts/UnitTestApks.targets`](../build-tools/scripts/UnitTestApks.targets)
|
||||
[`build-tools/scripts/TestApks.targets`](../build-tools/scripts/TestApks.targets)
|
||||
files.
|
||||
|
||||
All `.apk`-based unit test projects provide the following targets:
|
||||
|
||||
* `DeployUnitTestApks`: Installs the associated `.apk` to an Android device.
|
||||
* `UndeployUnitTestApks`: Uninstalls the associated `.apk` from an Android device.
|
||||
* `RunUnitTestApks`: Executes the unit tests contained within a `.apk`.
|
||||
Must be executed *after* the `DeployUnitTestApks` target.
|
||||
* `DeployTestApks`: Installs the associated `.apk` to an Android device.
|
||||
* `UndeployTestApks`: Uninstalls the associated `.apk` from an Android device.
|
||||
* `RunTestApks`: Executes the unit tests contained within a `.apk`.
|
||||
Must be executed *after* the `DeployTestApks` target.
|
||||
|
||||
To run an individual `.apk`-based test project, a package must be built, using the
|
||||
`SignAndroidPackage` target, installed, and executed.
|
||||
|
@ -164,23 +164,23 @@ To run an individual `.apk`-based test project, a package must be built, using t
|
|||
For example:
|
||||
|
||||
$ tools/scripts/xabuild /t:SignAndroidPackage tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
$ tools/scripts/xabuild /t:DeployUnitTestApks tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
$ tools/scripts/xabuild /t:RunUnitTestApks tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
$ tools/scripts/xabuild /t:DeployTestApks tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
$ tools/scripts/xabuild /t:RunTestApks tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
|
||||
### Running A Single Test Fixture
|
||||
|
||||
A single NUnit *Test Fixture* -- a class with the `[TestFixture]`
|
||||
custom attribute -- may be executed instead of executing *all* test fixtures.
|
||||
|
||||
The `RunUnitTestApks` target accepts a `TestFixture` MSBuild property
|
||||
The `RunTestApks` target accepts a `TestFixture` MSBuild property
|
||||
to specify the test fixture class to execute:
|
||||
|
||||
$ tools/scripts/xabuild /t:RunUnitTestApks \
|
||||
$ tools/scripts/xabuild /t:RunTestApks \
|
||||
/p:TestFixture=Xamarin.Android.LocaleTests.SatelliteAssemblyTests \
|
||||
tests/locales/Xamarin.Android.Locale-Tests/Xamarin.Android.Locale-Tests.csproj
|
||||
|
||||
If using `Xamarin.Android.NUnitLite` for projects outside the `xamarin-android`
|
||||
repository, such as NUnit tests for a custom app, the `RunUnitTestApks` target
|
||||
repository, such as NUnit tests for a custom app, the `RunTestApks` target
|
||||
will not exist. In such scenarios, the [`adb shell am`][adb-shell-am]
|
||||
`instrument` command can be used instead. It follows the format:
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.BindingReso
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.BindingResolveImports-Tests", "tests\ResolveImports\Xamarin.Android.BindingResolveImports-Tests\Xamarin.Android.BindingResolveImports-Tests.csproj", "{B297008B-C313-455E-B230-E119589D2D79}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Xamarin.Forms.Performance.Integration", "tests\Xamarin.Forms-Performance-Integration\Xamarin.Forms.Performance.Integration.shproj", "{195BE9C2-1F91-40DC-BD6D-DE860BF083FB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.Performance.Integration.Droid", "tests\Xamarin.Forms-Performance-Integration\Droid\Xamarin.Forms.Performance.Integration.Droid.csproj", "{576312CC-83FF-48B1-A473-488CDC7121AD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -115,6 +119,10 @@ Global
|
|||
{B297008B-C313-455E-B230-E119589D2D79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B297008B-C313-455E-B230-E119589D2D79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B297008B-C313-455E-B230-E119589D2D79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{576312CC-83FF-48B1-A473-488CDC7121AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{576312CC-83FF-48B1-A473-488CDC7121AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{576312CC-83FF-48B1-A473-488CDC7121AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{576312CC-83FF-48B1-A473-488CDC7121AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{2305B00D-DE81-4744-B0DA-357835CAFE5A} = {43A4FB09-279A-4138-8027-EC1E1CED2E8A}
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.CheckAdbTarget" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.CreateAndroidEmulator" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.RunInstrumentationTests" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.RunUITests" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.StartAndroidEmulator" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.KillProcess" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.Sleep" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ProcessLogcatTiming" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_TestImageName>XamarinAndroidUnitTestRunner</_TestImageName>
|
||||
<_TestImageName>XamarinAndroidTestRunner</_TestImageName>
|
||||
<_AdbEmulatorPort>5570</_AdbEmulatorPort>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -107,54 +108,62 @@
|
|||
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<UnitTestApk Include="ApkFile">
|
||||
<TestApk Include="ApkFile">
|
||||
<Package></Package>
|
||||
<InstrumentationType></InstrumentationType>
|
||||
<ResultsPath></ResultsPath>
|
||||
</UnitTestApk>
|
||||
</TestApk>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<Target Name="DeployUnitTestApks"
|
||||
Condition=" '@(UnitTestApk)' != '' ">
|
||||
<Target Name="DeployTestApks"
|
||||
Condition=" '@(TestApk)' != '' ">
|
||||
<Xamarin.Android.Tools.BootstrapTasks.Adb
|
||||
Arguments="$(_AdbTarget) $(AdbOptions) install "%(UnitTestApk.Identity)""
|
||||
Arguments="$(_AdbTarget) $(AdbOptions) install "%(TestApk.Identity)""
|
||||
ToolExe="$(AdbToolExe)"
|
||||
ToolPath="$(AdbToolPath)"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target Name="UndeployUnitTestApks"
|
||||
Condition=" '@(UnitTestApk)' != '' ">
|
||||
<Target Name="UndeployTestApks"
|
||||
Condition=" '@(TestApk)' != '' ">
|
||||
<Xamarin.Android.Tools.BootstrapTasks.Adb
|
||||
Arguments="$(_AdbTarget) $(AdbOptions) uninstall "%(UnitTestApk.Package)""
|
||||
Arguments="$(_AdbTarget) $(AdbOptions) uninstall "%(TestApk.Package)""
|
||||
ToolExe="$(AdbToolExe)"
|
||||
ToolPath="$(AdbToolPath)"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target Name="RunUnitTestApks"
|
||||
Condition=" '@(UnitTestApk)' != '' ">
|
||||
<Target Name="RunTestApks"
|
||||
Condition=" '@(TestApk)' != '' ">
|
||||
<RunInstrumentationTests
|
||||
Condition=" '%(TestApk.InstrumentationType)' != ''"
|
||||
AdbTarget="$(_AdbTarget)"
|
||||
AdbOptions="$(AdbOptions)"
|
||||
Component="%(UnitTestApk.Package)/%(UnitTestApk.InstrumentationType)"
|
||||
NUnit2TestResultsFile="%(UnitTestApk.ResultsPath)"
|
||||
Component="%(TestApk.Package)/%(TestApk.InstrumentationType)"
|
||||
NUnit2TestResultsFile="%(TestApk.ResultsPath)"
|
||||
TestFixture="$(TestFixture)"
|
||||
ToolExe="$(AdbToolExe)"
|
||||
ToolPath="$(AdbToolPath)">
|
||||
<Output TaskParameter="FailedToRun" ItemName="_FailedComponent"/>
|
||||
</RunInstrumentationTests>
|
||||
<RunUITests
|
||||
Condition=" '%(TestApk.Activity)' != '' "
|
||||
AdbTarget="$(_AdbTarget)"
|
||||
AdbOptions="$(AdbOptions)"
|
||||
Activity="%(TestApk.Activity)">
|
||||
</RunUITests>
|
||||
<PropertyGroup>
|
||||
<_LogcatFilename>logcat-$(Configuration)$(_AotName).txt</_LogcatFilename>
|
||||
</PropertyGroup>
|
||||
<Exec Command=""$(AdbToolPath)\$(AdbToolExe)" $(_AdbTarget) $(AdbOptions) logcat -v threadtime -d > $(_LogcatFilename)" />
|
||||
<ProcessLogcatTiming
|
||||
Condition=" '%(UnitTestApk.TimingDefinitionsFilename)' != '' "
|
||||
Condition=" '%(TestApk.TimingDefinitionsFilename)' != '' "
|
||||
InputFilename="$(_LogcatFilename)"
|
||||
ApplicationPackageName="%(UnitTestApk.Package)"
|
||||
ResultsFilename="%(UnitTestApk.ResultsPath)"
|
||||
DefinitionsFilename="%(UnitTestApk.TimingDefinitionsFilename)"
|
||||
AddResults="true" />
|
||||
ApplicationPackageName="%(TestApk.Package)"
|
||||
ResultsFilename="%(TestApk.ResultsPath)"
|
||||
DefinitionsFilename="%(TestApk.TimingDefinitionsFilename)"
|
||||
AddResults="true"
|
||||
Activity="%(TestApk.Activity)" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -10,13 +10,16 @@ namespace Xamarin.Android.BuildTools.PrepTasks
|
|||
{
|
||||
public class ProcessLogcatTiming : ProcessPlotInput
|
||||
{
|
||||
public string Activity { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
LoadDefinitions ();
|
||||
using (var reader = new StreamReader (InputFilename)) {
|
||||
string line;
|
||||
int pid = -1;
|
||||
var procStartRegex = new Regex ($@"^(?<timestamp>\d+-\d+\s+[\d:\.]+)\s+.*ActivityManager: Start proc.*for added application {ApplicationPackageName}: pid=(?<pid>\d+)");
|
||||
var procIdentification = string.IsNullOrEmpty (Activity) ? $"added application {ApplicationPackageName}" : $"activity {Activity}";
|
||||
var procStartRegex = new Regex ($@"^(?<timestamp>\d+-\d+\s+[\d:\.]+)\s+.*ActivityManager: Start proc.*for {procIdentification}: pid=(?<pid>\d+)");
|
||||
Regex timingRegex = null;
|
||||
DateTime start = DateTime.Now;
|
||||
DateTime last = start;
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
<_MonoAndroidTestApkSizesInput>apk-sizes-$(_MonoAndroidTestPackage)-$(Configuration)$(_AotName).txt</_MonoAndroidTestApkSizesInput>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<UnitTestApk Include="$(_MonoAndroidTestApkFile)">
|
||||
<TestApk Include="$(_MonoAndroidTestApkFile)">
|
||||
<Package>$(_MonoAndroidTestPackage)</Package>
|
||||
<InstrumentationType>xamarin.android.runtimetests.TestInstrumentation</InstrumentationType>
|
||||
<ResultsPath>$(_MonoAndroidTestResultsPath)</ResultsPath>
|
||||
<TimingDefinitionsFilename>$(MSBuildThisFileDirectory)timing-definitions-$(Configuration)$(_AotName).txt</TimingDefinitionsFilename>
|
||||
</UnitTestApk>
|
||||
</TestApk>
|
||||
</ItemGroup>
|
||||
<Target Name="_RecordApkSizes" AfterTargets="DeployUnitTestApks">
|
||||
<Target Name="_RecordApkSizes" AfterTargets="DeployTestApks">
|
||||
<Delete Files="$(MSBuildThisFileDirectory)..\..\..\TestResult-Mono.Android_Tests-values.csv;$(MSBuildThisFileDirectory)..\..\..\TestResult-Mono.Android_Tests-times.csv" Condition=" '$(Configuration)' == 'Debug' " />
|
||||
<Exec Condition=" '$(HostOS)' == 'Darwin' " Command="stat -f "stat: %z %N" "$(_MonoAndroidTestApkFile)" > $(_MonoAndroidTestApkSizesInput)" />
|
||||
<Exec Condition=" '$(HostOS)' == 'Linux' " Command="stat -c "stat: %s %N" "$(_MonoAndroidTestApkFile)" > $(_MonoAndroidTestApkSizesInput)" />
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<AndroidNativeLibrary Include="libs\x86_64\libreuse-threads.so" />
|
||||
</ItemGroup>
|
||||
<Import Project="Mono.Android-Tests.projitems" />
|
||||
<Import Project="..\..\..\build-tools\scripts\UnitTestApks.targets" />
|
||||
<Import Project="..\..\..\build-tools\scripts\TestApks.targets" />
|
||||
<Target Name="BuildNativeLibs"
|
||||
BeforeTargets="Build"
|
||||
DependsOnTargets="AndroidPrepareForBuild"
|
||||
|
|
|
@ -46,11 +46,12 @@
|
|||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\GenerateMonoDroidIncludes.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\GenerateProfile.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\GetNugetPackageBasePath.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\RunInstrumentationTests.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\StartAndroidEmulator.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\UnzipDirectoryChildren.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\Zip.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\KillProcess.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\RunUITests.cs" />
|
||||
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\RunInstrumentationTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\external\LibZipSharp\libZipSharp.csproj">
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Xamarin.Android.Tools.BootstrapTasks
|
|||
|
||||
public string TargetId {get; set;}
|
||||
|
||||
public string ImageName {get; set;} = "XamarinAndroidUnitTestRunner";
|
||||
public string ImageName {get; set;} = "XamarinAndroidTestRunner";
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using Microsoft.Build.Framework;
|
||||
|
||||
namespace Xamarin.Android.Tools.BootstrapTasks
|
||||
{
|
||||
public class RunUITests : Adb
|
||||
{
|
||||
public string AdbTarget { get; set; }
|
||||
public string AdbOptions { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Activity { get; set; }
|
||||
|
||||
protected override bool LogTaskMessages {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
Log.LogMessage (MessageImportance.Low, $"Task {nameof (RunUITests)}");
|
||||
Log.LogMessage (MessageImportance.Low, $" {nameof (AdbTarget)}: {AdbTarget}");
|
||||
Log.LogMessage (MessageImportance.Low, $" {nameof (AdbOptions)}: {AdbOptions}");
|
||||
Log.LogMessage (MessageImportance.Low, $" {nameof (Activity)}: {Activity}");
|
||||
|
||||
base.Execute ();
|
||||
|
||||
Log.LogMessage(MessageImportance.Low, $" going to wait for 15 seconds");
|
||||
System.Threading.Thread.Sleep (15000);
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
protected override string GenerateCommandLineCommands ()
|
||||
{
|
||||
return $"{AdbTarget} {AdbOptions} shell am start -n \"{Activity}\"";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace Xamarin.Android.Tools.BootstrapTasks
|
|||
|
||||
public string AndroidSdkHome {get; set;}
|
||||
public string Port {get; set;}
|
||||
public string ImageName {get; set;} = "XamarinAndroidUnitTestRunner";
|
||||
public string ImageName {get; set;} = "XamarinAndroidTestRunner";
|
||||
public string ToolPath {get; set;}
|
||||
public string ToolExe {get; set;}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<UnitTestApk Include="$(OutputPath)Xamarin.Android.JcwGen_Tests-Signed.apk">
|
||||
<TestApk Include="$(OutputPath)Xamarin.Android.JcwGen_Tests-Signed.apk">
|
||||
<Package>Xamarin.Android.JcwGen_Tests</Package>
|
||||
<InstrumentationType>xamarin.android.jcwgentests.TestInstrumentation</InstrumentationType>
|
||||
<ResultsPath>$(MSBuildThisFileDirectory)..\..\..\TestResult-Xamarin.Android.JcwGen_Tests.xml</ResultsPath>
|
||||
<TimingDefinitionsFilename>$(MSBuildThisFileDirectory)..\..\..\build-tools\scripts\TimingDefinitions.txt</TimingDefinitionsFilename>
|
||||
</UnitTestApk>
|
||||
</TestApk>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="Xamarin.Android.JcwGen-Tests.projitems" />
|
||||
<Import Project="..\..\..\build-tools\scripts\UnitTestApks.targets" />
|
||||
<Import Project="..\..\..\build-tools\scripts\TestApks.targets" />
|
||||
<Target Name="BuildNativeLibs"
|
||||
DependsOnTargets="AndroidPrepareForBuild"
|
||||
Inputs="jni\Android.mk;jni\timing.c"
|
||||
|
|
|
@ -9,19 +9,20 @@
|
|||
<_AotName Condition=" '$(AotAssemblies)' == 'true' ">-Aot</_AotName>
|
||||
</PropertyGroup>
|
||||
<!--
|
||||
Note that the `.csproj` for each `@(UnitTestApk)` entry *must* be added to
|
||||
Note that the `.csproj` for each `@(TestApk)` entry *must* be added to
|
||||
`$(TEST_APK_PROJECTS)` in the toplevel Makefile so that the `.apk` is built.
|
||||
-->
|
||||
<Import Project="..\src\Mono.Android\Test\Mono.Android-Tests.projitems" />
|
||||
<Import Project="..\tests\CodeGen-Binding\Xamarin.Android.JcwGen-Tests\Xamarin.Android.JcwGen-Tests.projitems" Condition=" '$(Configuration)' == 'Debug' " />
|
||||
<Import Project="..\tests\locales\Xamarin.Android.Locale-Tests\Xamarin.Android.Locale-Tests.projitems" Condition=" '$(Configuration)' == 'Debug' " />
|
||||
<Import Project="..\build-tools\scripts\UnitTestApks.targets" />
|
||||
<Import Project="..\tests\Xamarin.Forms-Performance-Integration\Droid\Xamarin.Forms.Performance.Integration.Droid.projitems" Condition=" '$(Configuration)' == 'Release' " />
|
||||
<Import Project="..\build-tools\scripts\TestApks.targets" />
|
||||
<PropertyGroup>
|
||||
<RunApkTestsDependsOn>
|
||||
AcquireAndroidTarget;
|
||||
UndeployUnitTestApks;
|
||||
DeployUnitTestApks;
|
||||
RunUnitTestApks;
|
||||
UndeployTestApks;
|
||||
DeployTestApks;
|
||||
RunTestApks;
|
||||
ReleaseAndroidTarget
|
||||
</RunApkTestsDependsOn>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Performance.Integration.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<Color x:Key="Primary">#2196F3</Color>
|
||||
<Color x:Key="PrimaryDark">#1976D2</Color>
|
||||
<Color x:Key="Accent">#96d1ff</Color>
|
||||
<Color x:Key="LightBackgroundColor">#FAFAFA</Color>
|
||||
<Color x:Key="DarkBackgroundColor">#C0C0C0</Color>
|
||||
<Color x:Key="MediumGrayTextColor">#4d4d4d</Color>
|
||||
<Color x:Key="LightTextColor">#999999</Color>
|
||||
<Style TargetType="NavigationPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{StaticResource Primary}" />
|
||||
<Setter Property="BarTextColor" Value="White" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
public static bool UseMockDataStore = true;
|
||||
public static string BackendUrl = "https://localhost:5000";
|
||||
|
||||
public App ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
if (UseMockDataStore)
|
||||
DependencyService.Register<MockDataStore> ();
|
||||
else
|
||||
DependencyService.Register<CloudDataStore> ();
|
||||
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
MainPage = new MainPage ();
|
||||
else
|
||||
MainPage = new NavigationPage (new MainPage ());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 your 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,71 @@
|
|||
using System;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.OS;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration.Droid
|
||||
{
|
||||
[Activity (Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
bool firstOnCreate = true;
|
||||
bool firstOnStart = true;
|
||||
bool firstOnResume = true;
|
||||
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
if (firstOnCreate)
|
||||
Console.WriteLine ("startup-timing: OnCreate reached");
|
||||
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
base.OnCreate (bundle);
|
||||
|
||||
global::Xamarin.Forms.Forms.Init (this, bundle);
|
||||
|
||||
LoadApplication (new App ());
|
||||
|
||||
if (firstOnCreate) {
|
||||
Console.WriteLine ("startup-timing: OnCreate end reached");
|
||||
firstOnCreate = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
base.OnActivityResult (requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
protected override void OnStart ()
|
||||
{
|
||||
if (firstOnStart)
|
||||
Console.WriteLine ("startup-timing: OnStart reached");
|
||||
|
||||
base.OnStart ();
|
||||
|
||||
if (firstOnStart) {
|
||||
Console.WriteLine ("startup-timing: OnStart end reached");
|
||||
firstOnStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResume ()
|
||||
{
|
||||
if (firstOnResume)
|
||||
Console.WriteLine ("startup-timing: OnResume reached");
|
||||
|
||||
base.OnResume ();
|
||||
|
||||
if (firstOnResume) {
|
||||
Console.WriteLine ("startup-timing: OnResume end reached");
|
||||
firstOnResume = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?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="Xamarin.Forms_Performance_Integration">
|
||||
<uses-sdk android:minSdkVersion="15" />
|
||||
<application android:label="Xamarin.Forms.Performance.Integration"></application>
|
||||
</manifest>
|
|
@ -0,0 +1,27 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Android.App;
|
||||
|
||||
// Information about this assembly is defined by the following attributes.
|
||||
// Change them to the values specific to your project.
|
||||
|
||||
[assembly: AssemblyTitle ("Xamarin.Forms.Performance.Integration.Droid")]
|
||||
[assembly: AssemblyDescription ("")]
|
||||
[assembly: AssemblyConfiguration ("")]
|
||||
[assembly: AssemblyCompany ("")]
|
||||
[assembly: AssemblyProduct ("")]
|
||||
[assembly: AssemblyCopyright ("${AuthorCopyright}")]
|
||||
[assembly: AssemblyTrademark ("")]
|
||||
[assembly: AssemblyCulture ("")]
|
||||
|
||||
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
|
||||
[assembly: AssemblyVersion ("1.0.0")]
|
||||
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
|
@ -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.
|
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-hdpi/icon.png
Normal file
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-hdpi/icon.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-xhdpi/icon.png
Normal file
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-xhdpi/icon.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.7 KiB |
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-xxhdpi/icon.png
Normal file
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable-xxhdpi/icon.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable/icon.png
Normal file
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable/icon.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable/xamarin_logo.png
Normal file
Двоичные данные
tests/Xamarin.Forms-Performance-Integration/Droid/Resources/drawable/xamarin_logo.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 21 KiB |
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:tabIndicatorColor="@android:color/white" app:tabGravity="fill" app:tabMode="fixed" />
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<style name="MyTheme" parent="MyTheme.Base">
|
||||
</style>
|
||||
<!-- Base theme applied no matter what API -->
|
||||
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
|
||||
<item name="windowNoTitle">true</item>
|
||||
<!--We will be using the toolbar so no need to show ActionBar-->
|
||||
<item name="windowActionBar">false</item>
|
||||
<!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette-->
|
||||
<!-- colorPrimary is used for the default action bar background -->
|
||||
<item name="colorPrimary">#2196F3</item>
|
||||
<!-- colorPrimaryDark is used for the status bar -->
|
||||
<item name="colorPrimaryDark">#1976D2</item>
|
||||
<!-- colorAccent is used as the default value for colorControlActivated
|
||||
which is used to tint widgets -->
|
||||
<item name="colorAccent">#FF4081</item>
|
||||
<!-- You can also set colorControlNormal, colorControlActivated
|
||||
colorControlHighlight and colorSwitchThumbNormal. -->
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
|
||||
</style>
|
||||
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
|
||||
<item name="colorAccent">#FF4081</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{576312CC-83FF-48B1-A473-488CDC7121AD}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Xamarin.Forms.Performance.Integration.Droid</RootNamespace>
|
||||
<AssemblyName>Xamarin.Forms.Performance.Integration.Droid</AssemblyName>
|
||||
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
|
||||
<AndroidApplication>True</AndroidApplication>
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\bin\TestDebug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\bin\TestRelease</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidManagedSymbols>true</AndroidManagedSymbols>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86</AndroidSupportedAbis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Plugin.Connectivity.Abstractions">
|
||||
<HintPath>..\..\..\packages\Xam.Plugin.Connectivity.2.3.0\lib\MonoAndroid10\Plugin.Connectivity.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Plugin.Connectivity">
|
||||
<HintPath>..\..\..\packages\Xam.Plugin.Connectivity.2.3.0\lib\MonoAndroid10\Plugin.Connectivity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v4">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.Vector.Drawable">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.Animated.Vector.Drawable">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.RecyclerView">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.AppCompat">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.Design">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.CardView">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.MediaRouter">
|
||||
<HintPath>..\..\..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FormsViewGroup">
|
||||
<HintPath>..\..\..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\FormsViewGroup.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Forms.Core">
|
||||
<HintPath>..\..\..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Forms.Platform.Android">
|
||||
<HintPath>..\..\..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Forms.Platform">
|
||||
<HintPath>..\..\..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Forms.Xaml">
|
||||
<HintPath>..\..\..\packages\Xamarin.Forms.2.3.4.247\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
<Compile Include="MainActivity.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\icon.png" />
|
||||
<AndroidResource Include="Resources\drawable\xamarin_logo.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\icon.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\icon.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\icon.png" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\Xamarin.Forms.Performance.Integration.projitems" Label="Shared" Condition="Exists('..\Xamarin.Forms.Performance.Integration.projitems')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets" Condition="Exists('..\..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets')" />
|
||||
<Import Project="..\..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" />
|
||||
</Project>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<TestApk Include="$(OutputPath)Xamarin.Forms_Performance_Integration-Signed.apk">
|
||||
<Package>Xamarin.Forms_Performance_Integration</Package>
|
||||
<Activity>Xamarin.Forms_Performance_Integration/md52b709e14dec302485bbcaeac0bd817ce.MainActivity</Activity>
|
||||
<ResultsPath>$(MSBuildThisFileDirectory)..\..\..\TestResult-Xamarin.Forms_Test.xml</ResultsPath>
|
||||
<TimingDefinitionsFilename>$(MSBuildThisFileDirectory)timing-definitions.txt</TimingDefinitionsFilename>
|
||||
</TestApk>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="monoandroid71" />
|
||||
<package id="Xam.Plugin.Connectivity" version="2.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.Design" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.v4" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.v7.AppCompat" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.v7.CardView" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.v7.MediaRouter" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.v7.RecyclerView" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.Vector.Drawable" version="23.3.0" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Forms" version="2.3.4.247" targetFramework="monoandroid71" />
|
||||
</packages>
|
|
@ -0,0 +1,14 @@
|
|||
# measure time of last monodroid-timing message appearance
|
||||
last=monodroid-timing:\s+(?<message>.*)$
|
||||
|
||||
# measure time of runtime and JNIEnv initialization end
|
||||
init=monodroid-timing:\s+(?<message>Runtime\.init: end native-to-managed.*)$
|
||||
JNI.init=monodroid-timing:\s+(?<message>JNIEnv\.Initialize end:.*)$
|
||||
|
||||
# measure UI startup
|
||||
OnCreateBegin=mono-stdout: startup-timing: (?<message>OnCreate reached)$
|
||||
OnCreateEnd=mono-stdout: startup-timing: (?<message>OnCreate end reached)$
|
||||
OnStartBegin=mono-stdout: startup-timing: (?<message>OnStart reached)$
|
||||
OnStartEnd=mono-stdout: startup-timing: (?<message>OnStart end reached)$
|
||||
OnResumeBegin=mono-stdout: startup-timing: (?<message>OnResume reached)$
|
||||
OnResumeEnd=mono-stdout: startup-timing: (?<message>OnResume end reached)$
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Text { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Plugin.Connectivity;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class CloudDataStore : IDataStore<Item>
|
||||
{
|
||||
HttpClient client;
|
||||
IEnumerable<Item> items;
|
||||
|
||||
public CloudDataStore ()
|
||||
{
|
||||
client = new HttpClient ();
|
||||
client.BaseAddress = new Uri ($"{App.BackendUrl}/");
|
||||
|
||||
items = new List<Item> ();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Item>> GetItemsAsync (bool forceRefresh = false)
|
||||
{
|
||||
if (forceRefresh && CrossConnectivity.Current.IsConnected) {
|
||||
var json = await client.GetStringAsync ($"api/item");
|
||||
items = await Task.Run (() => JsonConvert.DeserializeObject<IEnumerable<Item>> (json));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public async Task<Item> GetItemAsync (string id)
|
||||
{
|
||||
if (id != null && CrossConnectivity.Current.IsConnected) {
|
||||
var json = await client.GetStringAsync ($"api/item/{id}");
|
||||
return await Task.Run (() => JsonConvert.DeserializeObject<Item> (json));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> AddItemAsync (Item item)
|
||||
{
|
||||
if (item == null || !CrossConnectivity.Current.IsConnected)
|
||||
return false;
|
||||
|
||||
var serializedItem = JsonConvert.SerializeObject (item);
|
||||
|
||||
var response = await client.PostAsync ($"api/item", new StringContent (serializedItem, Encoding.UTF8, "application/json"));
|
||||
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateItemAsync (Item item)
|
||||
{
|
||||
if (item == null || item.Id == null || !CrossConnectivity.Current.IsConnected)
|
||||
return false;
|
||||
|
||||
var serializedItem = JsonConvert.SerializeObject (item);
|
||||
var buffer = Encoding.UTF8.GetBytes (serializedItem);
|
||||
var byteContent = new ByteArrayContent (buffer);
|
||||
|
||||
var response = await client.PutAsync (new Uri ($"api/item/{item.Id}"), byteContent);
|
||||
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteItemAsync (string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty (id) && !CrossConnectivity.Current.IsConnected)
|
||||
return false;
|
||||
|
||||
var response = await client.DeleteAsync ($"api/item/{id}");
|
||||
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public interface IDataStore<T>
|
||||
{
|
||||
Task<bool> AddItemAsync (T item);
|
||||
Task<bool> UpdateItemAsync (T item);
|
||||
Task<bool> DeleteItemAsync (string id);
|
||||
Task<T> GetItemAsync (string id);
|
||||
Task<IEnumerable<T>> GetItemsAsync (bool forceRefresh = false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class MockDataStore : IDataStore<Item>
|
||||
{
|
||||
List<Item> items;
|
||||
|
||||
public MockDataStore ()
|
||||
{
|
||||
items = new List<Item> ();
|
||||
var mockItems = new List<Item>
|
||||
{
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "First item", Description="This is an item description." },
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "Second item", Description="This is an item description." },
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "Third item", Description="This is an item description." },
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "Fourth item", Description="This is an item description." },
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "Fifth item", Description="This is an item description." },
|
||||
new Item { Id = Guid.NewGuid().ToString(), Text = "Sixth item", Description="This is an item description." },
|
||||
};
|
||||
|
||||
foreach (var item in mockItems) {
|
||||
items.Add (item);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> AddItemAsync (Item item)
|
||||
{
|
||||
items.Add (item);
|
||||
|
||||
return await Task.FromResult (true);
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateItemAsync (Item item)
|
||||
{
|
||||
var _item = items.Where ((Item arg) => arg.Id == item.Id).FirstOrDefault ();
|
||||
items.Remove (_item);
|
||||
items.Add (item);
|
||||
|
||||
return await Task.FromResult (true);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteItemAsync (string id)
|
||||
{
|
||||
var _item = items.Where ((Item arg) => arg.Id == id).FirstOrDefault ();
|
||||
items.Remove (_item);
|
||||
|
||||
return await Task.FromResult (true);
|
||||
}
|
||||
|
||||
public async Task<Item> GetItemAsync (string id)
|
||||
{
|
||||
return await Task.FromResult (items.FirstOrDefault (s => s.Id == id));
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Item>> GetItemsAsync (bool forceRefresh = false)
|
||||
{
|
||||
return await Task.FromResult (items);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class AboutViewModel : BaseViewModel
|
||||
{
|
||||
public AboutViewModel ()
|
||||
{
|
||||
Title = "About";
|
||||
|
||||
OpenWebCommand = new Command (() => Device.OpenUri (new Uri ("https://xamarin.com/platform")));
|
||||
}
|
||||
|
||||
public ICommand OpenWebCommand { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class BaseViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>> () ?? new MockDataStore ();
|
||||
|
||||
bool isBusy = false;
|
||||
public bool IsBusy {
|
||||
get { return isBusy; }
|
||||
set { SetProperty (ref isBusy, value); }
|
||||
}
|
||||
|
||||
string title = string.Empty;
|
||||
public string Title {
|
||||
get { return title; }
|
||||
set { SetProperty (ref title, value); }
|
||||
}
|
||||
|
||||
protected bool SetProperty<T> (ref T backingStore, T value,
|
||||
[CallerMemberName]string propertyName = "",
|
||||
Action onChanged = null)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals (backingStore, value))
|
||||
return false;
|
||||
|
||||
backingStore = value;
|
||||
onChanged?.Invoke ();
|
||||
OnPropertyChanged (propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
#region INotifyPropertyChanged
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged ([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
var changed = PropertyChanged;
|
||||
if (changed == null)
|
||||
return;
|
||||
|
||||
changed.Invoke (this, new PropertyChangedEventArgs (propertyName));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class ItemDetailViewModel : BaseViewModel
|
||||
{
|
||||
public Item Item { get; set; }
|
||||
public ItemDetailViewModel (Item item = null)
|
||||
{
|
||||
Title = item?.Text;
|
||||
Item = item;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class ItemsViewModel : BaseViewModel
|
||||
{
|
||||
public ObservableCollection<Item> Items { get; set; }
|
||||
public Command LoadItemsCommand { get; set; }
|
||||
|
||||
public ItemsViewModel ()
|
||||
{
|
||||
Title = "Browse";
|
||||
Items = new ObservableCollection<Item> ();
|
||||
LoadItemsCommand = new Command (async () => await ExecuteLoadItemsCommand ());
|
||||
|
||||
MessagingCenter.Subscribe<NewItemPage, Item> (this, "AddItem", async (obj, item) => {
|
||||
var _item = item as Item;
|
||||
Items.Add (_item);
|
||||
await DataStore.AddItemAsync (_item);
|
||||
});
|
||||
}
|
||||
|
||||
async Task ExecuteLoadItemsCommand ()
|
||||
{
|
||||
if (IsBusy)
|
||||
return;
|
||||
|
||||
IsBusy = true;
|
||||
|
||||
try {
|
||||
Items.Clear ();
|
||||
var items = await DataStore.GetItemsAsync (true);
|
||||
foreach (var item in items) {
|
||||
Items.Add (item);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Debug.WriteLine (ex);
|
||||
} finally {
|
||||
IsBusy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Performance.Integration.AboutPage" xmlns:vm="clr-namespace:Xamarin.Forms.Performance.Integration;" Title="{Binding Title}">
|
||||
<ContentPage.BindingContext>
|
||||
<vm:AboutViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackLayout BackgroundColor="{StaticResource Accent}" VerticalOptions="FillAndExpand" HorizontalOptions="Fill">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
|
||||
<ContentView Padding="0,40,0,40" VerticalOptions="FillAndExpand">
|
||||
<Image Source="xamarin_logo.png" VerticalOptions="Center" HeightRequest="64" />
|
||||
</ContentView>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<ScrollView Grid.Row="1">
|
||||
<StackLayout Orientation="Vertical" Padding="16,40,16,40" Spacing="10">
|
||||
<Label FontSize="22">
|
||||
<Label.FormattedText>
|
||||
<FormattedString>
|
||||
<FormattedString.Spans>
|
||||
<Span Text="AppName" FontAttributes="Bold" FontSize="22" />
|
||||
<Span Text=" " />
|
||||
<Span Text="1.0" ForegroundColor="{StaticResource LightTextColor}" />
|
||||
</FormattedString.Spans>
|
||||
</FormattedString>
|
||||
</Label.FormattedText>
|
||||
</Label>
|
||||
<Label>
|
||||
<Label.FormattedText>
|
||||
<FormattedString>
|
||||
<FormattedString.Spans>
|
||||
<Span Text="This app is written in C# and native APIs using the" />
|
||||
<Span Text=" " />
|
||||
<Span Text="Xamarin Platform" FontAttributes="Bold" />
|
||||
<Span Text="." />
|
||||
</FormattedString.Spans>
|
||||
</FormattedString>
|
||||
</Label.FormattedText>
|
||||
</Label>
|
||||
<Label>
|
||||
<Label.FormattedText>
|
||||
<FormattedString>
|
||||
<FormattedString.Spans>
|
||||
<Span Text="It shares code with its" />
|
||||
<Span Text=" " />
|
||||
<Span Text="iOS, Android, and Windows" FontAttributes="Bold" />
|
||||
<Span Text=" " />
|
||||
<Span Text="versions." />
|
||||
</FormattedString.Spans>
|
||||
</FormattedString>
|
||||
</Label.FormattedText>
|
||||
</Label>
|
||||
<Button Margin="0,10,0,0" Text="Learn more" Command="{Binding OpenWebCommand}" BackgroundColor="{StaticResource Primary}" TextColor="White" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage>
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public partial class AboutPage : ContentPage
|
||||
{
|
||||
public AboutPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Performance.Integration.ItemDetailPage" Title="{Binding Title}">
|
||||
<StackLayout Spacing="20" Padding="15">
|
||||
<Label Text="{Binding Item.Text}" FontSize="Medium" />
|
||||
<Label Text="{Binding Item.Description}" FontSize="Small" />
|
||||
</StackLayout>
|
||||
</ContentPage>
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public partial class ItemDetailPage : ContentPage
|
||||
{
|
||||
ItemDetailViewModel viewModel;
|
||||
|
||||
// Note - The Xamarin.Forms Previewer requires a default, parameterless constructor to render a page.
|
||||
public ItemDetailPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
var item = new Item {
|
||||
Text = "Item 1",
|
||||
Description = "This is an item description."
|
||||
};
|
||||
|
||||
viewModel = new ItemDetailViewModel (item);
|
||||
BindingContext = viewModel;
|
||||
}
|
||||
|
||||
public ItemDetailPage (ItemDetailViewModel viewModel)
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
BindingContext = this.viewModel = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Performance.Integration.ItemsPage" Title="{Binding Title}" x:Name="BrowseItemsPage">
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<ListView x:Name="ItemsListView" ItemsSource="{Binding Items}" VerticalOptions="FillAndExpand" HasUnevenRows="true" RefreshCommand="{Binding LoadItemsCommand}" IsPullToRefreshEnabled="true" IsRefreshing="{Binding IsBusy, Mode=OneWay}" CachingStrategy="RecycleElement" ItemSelected="OnItemSelected">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<StackLayout Padding="10">
|
||||
<Label Text="{Binding Text}" LineBreakMode="NoWrap" Style="{DynamicResource ListItemTextStyle}" FontSize="16" />
|
||||
<Label Text="{Binding Description}" LineBreakMode="NoWrap" Style="{DynamicResource ListItemDetailTextStyle}" FontSize="13" />
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public partial class ItemsPage : ContentPage
|
||||
{
|
||||
ItemsViewModel viewModel;
|
||||
|
||||
public ItemsPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
BindingContext = viewModel = new ItemsViewModel ();
|
||||
}
|
||||
|
||||
async void OnItemSelected (object sender, SelectedItemChangedEventArgs args)
|
||||
{
|
||||
var item = args.SelectedItem as Item;
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
await Navigation.PushAsync (new ItemDetailPage (new ItemDetailViewModel (item)));
|
||||
|
||||
// Manually deselect item
|
||||
ItemsListView.SelectedItem = null;
|
||||
}
|
||||
|
||||
async void AddItem_Clicked (object sender, EventArgs e)
|
||||
{
|
||||
await Navigation.PushAsync (new NewItemPage ());
|
||||
}
|
||||
|
||||
protected override void OnAppearing ()
|
||||
{
|
||||
base.OnAppearing ();
|
||||
|
||||
if (viewModel.Items.Count == 0)
|
||||
viewModel.LoadItemsCommand.Execute (null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public class MainPage : TabbedPage
|
||||
{
|
||||
public MainPage ()
|
||||
{
|
||||
Page itemsPage, aboutPage = null;
|
||||
|
||||
switch (Device.RuntimePlatform) {
|
||||
case Device.iOS:
|
||||
itemsPage = new NavigationPage (new ItemsPage ()) {
|
||||
Title = "Browse"
|
||||
};
|
||||
|
||||
aboutPage = new NavigationPage (new AboutPage ()) {
|
||||
Title = "About"
|
||||
};
|
||||
itemsPage.Icon = "tab_feed.png";
|
||||
aboutPage.Icon = "tab_about.png";
|
||||
break;
|
||||
default:
|
||||
itemsPage = new ItemsPage () {
|
||||
Title = "Browse"
|
||||
};
|
||||
|
||||
aboutPage = new AboutPage () {
|
||||
Title = "About"
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
Children.Add (itemsPage);
|
||||
Children.Add (aboutPage);
|
||||
|
||||
Title = Children [0].Title;
|
||||
}
|
||||
|
||||
protected override void OnCurrentPageChanged ()
|
||||
{
|
||||
base.OnCurrentPageChanged ();
|
||||
Title = CurrentPage?.Title ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Performance.Integration.NewItemPage" Title="New Item">
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Save" Clicked="Save_Clicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
<ContentPage.Content>
|
||||
<StackLayout Spacing="20" Padding="15">
|
||||
<Label Text="Text" FontSize="Medium" />
|
||||
<Entry Text="{Binding Item.Text}" FontSize="Small" />
|
||||
<Label Text="Description" FontSize="Medium" />
|
||||
<Editor Text="{Binding Item.Description}" FontSize="Small" Margin="0" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Xamarin.Forms.Performance.Integration
|
||||
{
|
||||
public partial class NewItemPage : ContentPage
|
||||
{
|
||||
public Item Item { get; set; }
|
||||
|
||||
public NewItemPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
Item = new Item {
|
||||
Text = "Item name",
|
||||
Description = "This is an item description."
|
||||
};
|
||||
|
||||
BindingContext = this;
|
||||
}
|
||||
|
||||
async void Save_Clicked (object sender, EventArgs e)
|
||||
{
|
||||
MessagingCenter.Send (this, "AddItem", Item);
|
||||
await Navigation.PopToRootAsync ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>{195BE9C2-1F91-40DC-BD6D-DE860BF083FB}</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Xamarin.Forms.Performance.Integration</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Models\Item.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Services\CloudDataStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Services\IDataStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Services\MockDataStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\AboutViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\BaseViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ItemDetailViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ItemsViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Views\MainPage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Views\AboutPage.xaml.cs">
|
||||
<DependentUpon>AboutPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Views\ItemDetailPage.xaml.cs">
|
||||
<DependentUpon>ItemDetailPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Views\ItemsPage.xaml.cs">
|
||||
<DependentUpon>ItemsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Views\NewItemPage.xaml.cs">
|
||||
<DependentUpon>NewItemPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\AboutPage.xaml" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\ItemDetailPage.xaml" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\ItemsPage.xaml" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\NewItemPage.xaml" />
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)App.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{195BE9C2-1F91-40DC-BD6D-DE860BF083FB}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<Import Project="Xamarin.Forms.Performance.Integration.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
|
@ -70,7 +70,7 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="Xamarin.Android.Locale-Tests.projitems" />
|
||||
<Import Project="..\..\..\build-tools\scripts\UnitTestApks.targets" />
|
||||
<Import Project="..\..\..\build-tools\scripts\TestApks.targets" />
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="strings.de-DE.resx" />
|
||||
<EmbeddedResource Include="strings.fr-FR.resx" />
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<UnitTestApk Include="$(OutputPath)Xamarin.Android.Locale_Tests-Signed.apk">
|
||||
<TestApk Include="$(OutputPath)Xamarin.Android.Locale_Tests-Signed.apk">
|
||||
<Package>Xamarin.Android.Locale_Tests</Package>
|
||||
<InstrumentationType>xamarin.android.localetests.TestInstrumentation</InstrumentationType>
|
||||
<ResultsPath>$(MSBuildThisFileDirectory)..\..\..\TestResult-Xamarin.Android.Locale_Tests.xml</ResultsPath>
|
||||
<TimingDefinitionsFilename>$(MSBuildThisFileDirectory)..\..\..\build-tools\scripts\TimingDefinitions.txt</TimingDefinitionsFilename>
|
||||
</UnitTestApk>
|
||||
</TestApk>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
Загрузка…
Ссылка в новой задаче