Skip to content

Commit

Permalink
Release 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kamu authored and kamu committed May 26, 2018
1 parent 6bf2112 commit 3a15de8
Show file tree
Hide file tree
Showing 26 changed files with 653 additions and 357 deletions.
42 changes: 7 additions & 35 deletions AiForms.Layouts/AiForms.Layouts.csproj
Original file line number Diff line number Diff line change
@@ -1,42 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{921EC4B4-C014-4C1D-8BF3-ED28838B22E5}</ProjectGuid>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<RootNamespace>AiForms.Layouts</RootNamespace>
<AssemblyName>AiForms.Layouts</AssemblyName>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="RepeatableWrapLayout.cs" />
<Compile Include="WrapLayout.cs" />
<Compile Include="RepeatableStack.cs" />
<Compile Include="LayoutsInit.cs" />
</ItemGroup>

<ItemGroup>
<None Include="project.json" />
<PackageReference Include="Xamarin.Forms" Version="3.0.0.482510" />
</ItemGroup>

<ItemGroup>
<Folder Include="Properties\" />
<None Remove="AiForms.Layouts.csproj.nuget.cache" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<Import Project="..\packages\Xamarin.Forms.2.3.3.180\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\packages\Xamarin.Forms.2.3.3.180\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" />
</Project>
18 changes: 0 additions & 18 deletions AiForms.Layouts/AiForms.Layouts.nuget.props

This file was deleted.

9 changes: 0 additions & 9 deletions AiForms.Layouts/AiForms.Layouts.nuget.targets

This file was deleted.

151 changes: 151 additions & 0 deletions AiForms.Layouts/RepeatableFlex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using Xamarin.Forms;

namespace AiForms.Layouts
{
public class RepeatableFlex: FlexLayout
{
public static BindableProperty ItemsSourceProperty =
BindableProperty.Create(
nameof(ItemsSource),
typeof(IEnumerable),
typeof(RepeatableFlex),
null,
defaultBindingMode: BindingMode.OneWay,
propertyChanged: ItemsChanged
);

public IEnumerable ItemsSource {
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}

public static BindableProperty ItemTemplateProperty =
BindableProperty.Create(
nameof(ItemTemplate),
typeof(DataTemplate),
typeof(RepeatableFlex),
default(DataTemplate),
propertyChanged: (bindable, oldValue, newValue) => {
var control = (RepeatableFlex)bindable;
//when to occur propertychanged earlier ItemsSource than ItemTemplate, raise ItemsChanged manually
if (newValue != null && control.ItemsSource != null && !control.doneItemSourceChanged) {
ItemsChanged(bindable, null, control.ItemsSource);
}
}
);

public DataTemplate ItemTemplate {
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}

private bool doneItemSourceChanged = false;

private static void ItemsChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (RepeatableFlex)bindable;
// when to occur propertychanged earlier ItemsSource than ItemTemplate, do nothing.
if (control.ItemTemplate == null) {
control.doneItemSourceChanged = false;
return;
}

control.doneItemSourceChanged = true;

IEnumerable newValueAsEnumerable;
try {
newValueAsEnumerable = newValue as IEnumerable;
}
catch (Exception e) {
throw e;
}

var oldObservableCollection = oldValue as INotifyCollectionChanged;

if (oldObservableCollection != null) {
oldObservableCollection.CollectionChanged -= control.OnItemsSourceCollectionChanged;
}

var newObservableCollection = newValue as INotifyCollectionChanged;

if (newObservableCollection != null) {
newObservableCollection.CollectionChanged += control.OnItemsSourceCollectionChanged;
}

control.Children.Clear();

if (newValueAsEnumerable != null) {
foreach (var item in newValueAsEnumerable) {
var view = CreateChildViewFor(control.ItemTemplate, item, control);

control.Children.Add(view);
}
}

control.UpdateChildrenLayout();
control.InvalidateLayout();
}

private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Replace) {

this.Children.RemoveAt(e.OldStartingIndex);

var item = e.NewItems[e.NewStartingIndex];
var view = CreateChildViewFor(this.ItemTemplate, item, this);

this.Children.Insert(e.NewStartingIndex, view);
}

else if (e.Action == NotifyCollectionChangedAction.Add) {
if (e.NewItems != null) {
for (var i = 0; i < e.NewItems.Count; ++i) {
var item = e.NewItems[i];
var view = CreateChildViewFor(this.ItemTemplate, item, this);

this.Children.Insert(i + e.NewStartingIndex, view);
}
}
}

else if (e.Action == NotifyCollectionChangedAction.Remove) {
if (e.OldItems != null) {
this.Children.RemoveAt(e.OldStartingIndex);
}
}

else if (e.Action == NotifyCollectionChangedAction.Reset) {
this.Children.Clear();
}

else {
return;
}

}

private View CreateChildViewFor(object item)
{
this.ItemTemplate.SetValue(BindableObject.BindingContextProperty, item);
return (View)this.ItemTemplate.CreateContent();
}

private static View CreateChildViewFor(DataTemplate template, object item, BindableObject container)
{
var selector = template as DataTemplateSelector;

if (selector != null) {
template = selector.SelectTemplate(item, container);
}

//Binding context
template.SetValue(BindableObject.BindingContextProperty, item);

return (View)template.CreateContent();
}
}
}
10 changes: 0 additions & 10 deletions AiForms.Layouts/project.json

This file was deleted.

30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ This is a collection of Xamarin.Forms custom layouts

## Features

* [RepeatableFlex](#repeatableflex)
* [WrapLayout](#wraplayout)
* [RepeatableWrapLayout](#repeatablewraplayout)
* [RepeatableStack](#repeatablestack)

<img src="images/1.png" width=200 /><img src="images/2.png" width=200 /><img src="images/3.png" width=200 />


## Demo

https://twitter.com/muak_x/status/830061279330996224
Expand All @@ -28,9 +28,6 @@ https://twitter.com/muak_x/status/830061279330996224
Install-Package AiForms.Layouts
```

~~All you need to do is installing to PCL project.~~
~~You need not to install this nuget package to each platform project.~~

You need to install this package to .NETStandard / PCL project and **each platform project**.

### iOS
Expand All @@ -49,10 +46,35 @@ public override bool FinishedLaunching(UIApplication app, NSDictionary options)
}
```

## RepeatableFlex

This layout is a FlexLayout corresponding to DataTemplate and DataTemplateSelector.

### Parameters

* ItemsSource
* ItemTemplate

### How to write with Xaml

```xml
<ScrollView Orientation="Virtical" HeightRequest="86">
<al:RepeatableFlex Direction="Row" Wrap="Wrap" AlignItems="Start" JustifyContent="Start" ItemsSource="{Binding BoxList}">
<al:RepeatableFlex.ItemTemplate>
<DataTemplate>
<ContentView BackgroundColor="{Binding Color}" WidthRequest="80" HeightRequest="80" Padding="3" />
</DataTemplate>
</al:RepeatableFlex.ItemTemplate>
</al:RepeatableFlex>
</ScrollView>
```

## WrapLayout

This Layout performs wrapping on the boundaries.

_By Flex Layout having come, there is seldom opportunity using this layout. But it can be used when you want to arrange uniformly each items depending on screen width or make it square._

### Parameters

* Spacing
Expand Down
8 changes: 4 additions & 4 deletions Sample/Sample.Droid/MainActivity.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Android.App;
using Android.Content.PM;
using Android.OS;
using Microsoft.Practices.Unity;
using Prism.Unity;
using Prism;
using Prism.Ioc;

namespace Sample.Droid
{
Expand All @@ -18,15 +18,15 @@ protected override void OnCreate(Bundle bundle)
global::Xamarin.Forms.Forms.SetFlags("FastRenderers_Experimental");
global::Xamarin.Forms.Forms.Init(this, bundle);


LoadApplication(new App(new AndroidInitializer()));
}
}

public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
public void RegisterTypes(IContainerRegistry containerRegistry)
{

}
}
}
Loading

0 comments on commit 3a15de8

Please sign in to comment.