Last active
October 20, 2015 04:30
-
-
Save programmation/3e8b253dfe7ef9e3317a to your computer and use it in GitHub Desktop.
Foundations of a skinnable app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SkinnableApp/App.xaml | |
<?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="SkinnableApp.App"> | |
<Application.Resources> | |
<ResourceDictionary> | |
</ResourceDictionary> | |
</Application.Resources> | |
</Application> | |
// SkinnableApp/App.xaml.cs | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Reflection; | |
using System.Threading.Tasks; | |
using Newtonsoft.Json; | |
using Xamarin.Forms; | |
namespace SkinnableApp | |
{ | |
public partial class App : Application | |
{ | |
public App (string bundleId) | |
{ | |
SetupIOC (); | |
SetupStyles (); | |
MainPage = new StartPage(); | |
} | |
void SetupIOC () | |
{ | |
IOC.Container.Register<IStyleService, StyleService> (); | |
} | |
void SetupStyles () | |
{ | |
if (Resources == null) { | |
Resources = new ResourceDictionary (); | |
} | |
IStyleService styles = IOC.Container.Resolve<IStyleService> (); | |
var service = JsonConvert.DeserializeObject<StyleService> (AppState.StylesJson); | |
styles.Setup (service); | |
var output = JsonConvert.SerializeObject (styles); | |
Debug.WriteLine (output); | |
var methods = typeof(IStyleService) | |
.GetRuntimeMethods () | |
.Where (m => !m.Name.StartsWith ("get_")) // remove auto-properties | |
.Where (m => !m.Name.StartsWith ("set_")) // remove auto-properties | |
.Where (m => !m.Name.StartsWith ("Setup")) // remove auto-properties | |
.ToList (); | |
foreach (var method in methods) { | |
Resources.Add (method.Name, method.Invoke (styles, null)); | |
} | |
var properties = typeof(IStyleService) | |
.GetRuntimeProperties (); | |
foreach (var property in properties) { | |
Resources.Add (property.Name, property.GetValue (styles, null)); | |
} | |
} | |
} | |
} | |
// SkinnableApp.iOS/AppDelegate.cs | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using Foundation; | |
using UIKit; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.iOS; | |
namespace SkinnableApp.iOS | |
{ | |
[Register ("AppDelegate")] | |
public partial class AppDelegate : FormsApplicationDelegate | |
{ | |
public override bool FinishedLaunching (UIApplication app, NSDictionary options) | |
{ | |
global::Xamarin.Forms.Forms.Init (); | |
var formsApp = AppStarter.Start (app, options, this); | |
LoadApplication (formsApp); | |
return base.FinishedLaunching (app, options); | |
} | |
} | |
} | |
// SkinnableAppLib.iOS/AppStarter.cs | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Runtime.CompilerServices; | |
using Foundation; | |
using UIKit; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.iOS; | |
namespace SkinnableApp.iOS | |
{ | |
public static class AppStarter | |
{ | |
public static Application Start (UIApplication app, | |
NSDictionary options, FormsApplicationDelegate appDelegate) | |
{ | |
LoadConfiguration (); | |
var bundleId = NSBundle.MainBundle.BundleIdentifier; | |
var formsApp = new App (bundleId); | |
return formsApp; | |
} | |
public static void LoadConfiguration () | |
{ | |
AppState.ResourcesJson = ReadStringAsset ("Configuration/Resources.json"); | |
AppState.StylesJson = ReadStringAsset ("Configuration/Styles.json"); | |
AppState.MenusJson = ReadStringAsset ("Configuration/Menus.json"); | |
} | |
public static string ReadStringAsset (string path) | |
{ | |
string assetText = File.ReadAllText (path); | |
return assetText; | |
} | |
} | |
} | |
// SkinnableApp.Droid/MainActivity.cs | |
using System; | |
using Android.App; | |
using Android.Content; | |
using Android.Content.PM; | |
using Android.OS; | |
using Android.Runtime; | |
using Android.Views; | |
using Android.Widget; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
namespace SkinnableApp.Droid | |
{ | |
[Activity (Label = "SkinnableApp.Droid", | |
Icon = "@drawable/icon", | |
MainLauncher = false, | |
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, | |
ScreenOrientation = ScreenOrientation.Portrait, | |
Theme = "@style/MainTheme")] | |
public class MainActivity : FormsApplicationActivity | |
{ | |
protected override void OnCreate (Bundle bundle) | |
{ | |
base.OnCreate (bundle); | |
global::Xamarin.Forms.Forms.Init (this, bundle); | |
var formsApp = AppStarter.Start (this, bundle, Forms.Context); | |
LoadApplication (formsApp); | |
} | |
} | |
} | |
// SkinnableAppLib.Droid/AppStarter.cs | |
using System; | |
using System.IO; | |
using System.Linq; | |
using Android.App; | |
using Android.Content; | |
using Android.Content.Res; | |
using Android.OS; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
namespace SkinnableApp.Droid | |
{ | |
public static class AppStarter | |
{ | |
public static Xamarin.Forms.Application Start (FormsApplicationActivity activity, Bundle bundle, Context context) | |
{ | |
LoadConfiguration (context); | |
var bundleId = context.PackageName; | |
var formsApp = new App (bundleId); | |
return formsApp; | |
} | |
public static void LoadConfiguration (Context context) | |
{ | |
AppState.ResourcesJson = ReadStringAsset (context, "Resources.json"); | |
AppState.StylesJson = ReadStringAsset (context, "Styles.json"); | |
AppState.MenusJson = ReadStringAsset (context, "Menus.json"); | |
} | |
public static string ReadStringAsset (Context context, string path) | |
{ | |
var asset = ((Activity)context).Assets.Open (path); | |
string assetText; | |
using (var sr = new StreamReader (asset)) | |
{ | |
assetText = sr.ReadToEnd (); | |
} | |
return assetText; | |
} | |
} | |
} | |
// Set Configuration folder as Git Subtree in project folder | |
// skinnableupdateios.sh | |
#!/bin/sh | |
function help () { | |
echo "skinnableupdateios - simple script to keep assets in sync with designer resources" | |
echo "" | |
echo " skinnableupdateios {projectdir} {resourcedir} - {resourcedir} is resource directory in {projectdir}" | |
} | |
function dosync () { | |
cd $1 | |
rsync -avh "../Configuration/$2/Configuration" "$1/Resources/" | |
rsync -avh "../Configuration/$2/Fonts" "$1/Resources/" | |
rsync -avh "../Configuration/$2/Resources/iOS/" "$1/Resources/" | |
} | |
if [ $1 ] ; then | |
dosync $1 $2 | |
else | |
help | |
fi | |
// skinnableupdatedroid.sh | |
#!/bin/sh | |
function help () { | |
echo "skinnableupdatedroid - simple script to keep assets in sync with designer resources" | |
echo "" | |
echo " skinnableupdatedroid {projectdir} {resourcedir} - {resourcedir} is resource directory in {projectdir}" | |
} | |
function dosync () { | |
cd $1 | |
rsync -avh "../Configuration/$2/Configuration/" "./Assets/" | |
rsync -avh "../Configuration/$2/Fonts/" "./Assets/" | |
rsync -avh "../Configuration/$2/Resources/Droid/" "./Resources/" | |
} | |
if [ $1 ] ; then | |
dosync $1 $2 | |
else | |
help | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment