change app directory

This commit is contained in:
2023-07-19 21:01:19 +08:00
parent 8b759c94ec
commit 02ac33fc07
56 changed files with 781 additions and 535 deletions

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@ -0,0 +1,18 @@
using Android.App;
using Android.Content.PM;
namespace Blahblah.FlowerApp;
[Activity(
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges =
ConfigChanges.ScreenSize |
ConfigChanges.Orientation |
ConfigChanges.UiMode |
ConfigChanges.ScreenLayout |
ConfigChanges.SmallestScreenSize |
ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}

View File

@ -0,0 +1,15 @@
using Android.App;
using Android.Runtime;
namespace Blahblah.FlowerApp;
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>

View File

@ -0,0 +1,9 @@
using Foundation;
namespace Blahblah.FlowerApp;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@ -0,0 +1,125 @@
using CoreGraphics;
using Foundation;
using UIKit;
namespace Blahblah.FlowerApp.Platforms.iOS.Controls;
public class FlowLayout : UICollectionViewFlowLayout
{
public CalculateCellHeightHandler? CalculateCellHeight { get; set; }
private readonly List<UICollectionViewLayoutAttributes> layoutAttributes = new();
private CGSize oldBounds;
private bool dirty;
private int cols;
private nfloat[]? yArray;
private nfloat maxHeight;
public FlowLayout(int cols = 2)
{
SetCols(cols);
}
public void SetCols(int cols)
{
if (this.cols != cols)
{
dirty = true;
this.cols = cols;
}
}
public void Invalidate()
{
dirty = true;
}
private void Clean()
{
dirty = false;
yArray = new nfloat[cols];
maxHeight = 0f;
layoutAttributes.Clear();
}
public override CGSize CollectionViewContentSize => new(CollectionView.Bounds.Width, maxHeight);
public override bool ShouldInvalidateLayoutForBoundsChange(CGRect newBounds)
{
return newBounds.Width != CollectionView.Bounds.Width;
}
public override void PrepareLayout()
{
base.PrepareLayout();
var bounds = CollectionView.Bounds.Size;
if (dirty || oldBounds.Width != bounds.Width)
{
oldBounds = bounds;
Clean();
}
var sectionLeft = SectionInset.Left;
var sectionTop = SectionInset.Top;
var minSpacing = MinimumInteritemSpacing;
var itemWidth = (bounds.Width - sectionLeft - SectionInset.Right - minSpacing * (cols - 1)) / cols;
var itemCount = CollectionView.NumberOfItemsInSection(0);
for (nint i = layoutAttributes.Count; i < itemCount; i++)
{
var indexPath = NSIndexPath.FromItemSection(i, 0);
var attr = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
var itemHeight = CalculateCellHeight?.Invoke(indexPath, itemWidth) ?? 20;
nfloat value = nfloat.MaxValue;
int minHeightIndex = 0;
if (yArray?.Length >= cols)
{
for (var n = 0; n < cols; n++)
{
if (yArray[n] < value)
{
value = yArray[n];
minHeightIndex = n;
}
}
}
var itemY = value;
if (itemY < sectionTop)
{
itemY = sectionTop;
}
if (i >= cols)
{
itemY += minSpacing;
}
var itemX = sectionLeft + (itemWidth + minSpacing) * minHeightIndex;
attr.Frame = new CGRect(itemX, itemY, itemWidth, itemHeight);
layoutAttributes.Add(attr);
if (yArray != null)
{
yArray[minHeightIndex] = itemY + itemHeight;
}
}
nfloat y = 0f;
if (yArray != null)
{
for (var i = 0; i < yArray.Length; i++)
{
if (yArray[i] > y)
{
y = yArray[i];
}
}
}
maxHeight = y + SectionInset.Bottom;
}
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect)
{
return layoutAttributes.Where(a => a.Frame.IntersectsWith(rect)).ToArray();
}
}
public delegate nfloat CalculateCellHeightHandler(NSIndexPath indexPath, nfloat itemWidth);

View File

@ -0,0 +1,86 @@
using Blahblah.FlowerApp.Controls;
using Foundation;
using UIKit;
namespace Blahblah.FlowerApp.Platforms.iOS.Controls;
public class MauiWaterfallLayout : UIView, IUICollectionViewDataSource, IUICollectionViewDelegate
{
WaterfallLayout? layout;
UICollectionView? collectionView;
public MauiWaterfallLayout(WaterfallLayout layout)
{
this.layout = layout;
var flow = new FlowLayout(layout.Columns)
{
//CalculateCellHeight =
MinimumInteritemSpacing = 12f,
SectionInset = new UIEdgeInsets(12f, 12f, 12f, 12f)
};
var refreshControl = new UIRefreshControl
{
TintColor = UIColor.SystemFill
};
refreshControl.ValueChanged += (sender, e) =>
{
if (sender is UIRefreshControl control)
{
control.EndRefreshing();
}
};
collectionView = new UICollectionView(Bounds, flow)
{
DataSource = this,
Delegate = this,
RefreshControl = refreshControl,
TranslatesAutoresizingMaskIntoConstraints = false
};
AddSubview(collectionView);
var safe = SafeAreaLayoutGuide;
AddConstraints(new[]
{
NSLayoutConstraint.Create(collectionView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, safe, NSLayoutAttribute.Leading, 1f, 0f),
NSLayoutConstraint.Create(collectionView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, safe, NSLayoutAttribute.Trailing, 1f, 0f),
NSLayoutConstraint.Create(collectionView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, safe, NSLayoutAttribute.Top, 1f, 0f),
NSLayoutConstraint.Create(collectionView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, safe, NSLayoutAttribute.Bottom, 1f, 0f),
});
}
public UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
return new UICollectionViewCell();
}
public nint GetItemsCount(UICollectionView collectionView, nint section)
{
return 5;
}
public void UpdateColumns()
{
if (layout != null && collectionView?.CollectionViewLayout is FlowLayout flow)
{
flow.SetCols(layout.Columns);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (collectionView != null)
{
collectionView.Dispose();
collectionView = null;
}
layout = null;
}
base.Dispose(disposing);
}
}

View File

@ -0,0 +1,26 @@
using Blahblah.FlowerApp.Controls;
using Blahblah.FlowerApp.Platforms.iOS.Controls;
using Microsoft.Maui.Handlers;
namespace Blahblah.FlowerApp.Handlers;
partial class WaterfallLayoutHandler : ViewHandler<WaterfallLayout, MauiWaterfallLayout>
{
static void MapColumns(WaterfallLayoutHandler handler, WaterfallLayout layout)
{
handler.PlatformView?.UpdateColumns();
}
protected override MauiWaterfallLayout CreatePlatformView() => new MauiWaterfallLayout(VirtualView);
protected override void ConnectHandler(MauiWaterfallLayout platformView)
{
base.ConnectHandler(platformView);
}
protected override void DisconnectHandler(MauiWaterfallLayout platformView)
{
platformView.Dispose();
base.DisconnectHandler(platformView);
}
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>

View File

@ -0,0 +1,14 @@
using UIKit;
namespace Blahblah.FlowerApp;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}