mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-08-19 14:53:24 +08:00
feat: 新增 Android 移动端 head 与共享移动壳(组件面板)
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Avalonia" Version="12.1.0" />
|
||||
<PackageVersion Include="Avalonia.Android" Version="12.1.0" />
|
||||
<PackageVersion Include="Avalonia.Angle.Windows.Natives" Version="2.1.27548.20260419" />
|
||||
<PackageVersion Include="Avalonia.Controls.WebView" Version="12.0.1" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="12.1.0" />
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0-android</TargetFramework>
|
||||
<SupportedOSPlatformVersion>24</SupportedOSPlatformVersion>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<ApplicationId>org.lanmountain.desktop</ApplicationId>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
<ApplicationDisplayVersion>0.0.0-dev</ApplicationDisplayVersion>
|
||||
<AndroidPackageFormat>apk</AndroidPackageFormat>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LanMountainDesktop.Mobile\LanMountainDesktop.Mobile.csproj" />
|
||||
<ProjectReference Include="..\LanMountainDesktop.Platform.Android\LanMountainDesktop.Platform.Android.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Android" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
19
LanMountainDesktop.Mobile.Android/MainActivity.cs
Normal file
19
LanMountainDesktop.Mobile.Android/MainActivity.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Avalonia.Android;
|
||||
|
||||
namespace LanMountainDesktop.Mobile.Android;
|
||||
|
||||
/// <summary>
|
||||
/// Android 入口 Activity。承载 MobileApp(单视图组件面板)。
|
||||
/// Avalonia 12 起 AppBuilder 定制移至 <see cref="MobileAndroidApplication"/>。
|
||||
/// </summary>
|
||||
[Activity(
|
||||
Label = "阑山桌面",
|
||||
Theme = "@style/MyTheme.NoActionBar",
|
||||
Icon = "@drawable/icon",
|
||||
MainLauncher = true,
|
||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
|
||||
public class MainActivity : AvaloniaMainActivity
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
using Avalonia;
|
||||
using Avalonia.Android;
|
||||
using LanMountainDesktop.Mobile;
|
||||
|
||||
namespace LanMountainDesktop.Mobile.Android;
|
||||
|
||||
/// <summary>
|
||||
/// Android 应用级入口。Avalonia 12 中 AppBuilder 的创建/定制由
|
||||
/// AvaloniaAndroidApplication<TApp> 子类负责(而非 Activity)。
|
||||
/// </summary>
|
||||
[Application]
|
||||
public class MobileAndroidApplication : AvaloniaAndroidApplication<MobileApp>
|
||||
{
|
||||
protected MobileAndroidApplication(nint javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
|
||||
{
|
||||
return base.CustomizeAppBuilder(builder)
|
||||
.WithInterFont();
|
||||
}
|
||||
}
|
||||
BIN
LanMountainDesktop.Mobile.Android/Resources/drawable/icon.png
Normal file
BIN
LanMountainDesktop.Mobile.Android/Resources/drawable/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="MyTheme.NoActionBar" parent="@android:style/Theme.Material.Light.NoActionBar">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:colorPrimary">#3B82F6</item>
|
||||
</style>
|
||||
</resources>
|
||||
23
LanMountainDesktop.Mobile/LanMountainDesktop.Mobile.csproj
Normal file
23
LanMountainDesktop.Mobile/LanMountainDesktop.Mobile.csproj
Normal file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||
<ProjectReference Include="..\LanMountainDesktop.Settings.Core\LanMountainDesktop.Settings.Core.csproj" />
|
||||
<ProjectReference Include="..\LanMountainDesktop.Appearance\LanMountainDesktop.Appearance.csproj" />
|
||||
<ProjectReference Include="..\LanMountainDesktop.DesktopComponents.Runtime\LanMountainDesktop.DesktopComponents.Runtime.csproj" />
|
||||
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
8
LanMountainDesktop.Mobile/MobileApp.axaml
Normal file
8
LanMountainDesktop.Mobile/MobileApp.axaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="LanMountainDesktop.Mobile.MobileApp"
|
||||
RequestedThemeVariant="Default">
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
33
LanMountainDesktop.Mobile/MobileApp.axaml.cs
Normal file
33
LanMountainDesktop.Mobile/MobileApp.axaml.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using LanMountainDesktop.Mobile.ViewModels;
|
||||
using LanMountainDesktop.Mobile.Views;
|
||||
|
||||
namespace LanMountainDesktop.Mobile;
|
||||
|
||||
/// <summary>
|
||||
/// 移动端应用入口。以单视图生命周期承载组件面板。
|
||||
/// 与桌面宿主 (LanMountainDesktop.App) 共享契约、外观与组件运行时,
|
||||
/// 但不包含桌面层、托盘、进程外插件等桌面专属能力。
|
||||
/// </summary>
|
||||
public partial class MobileApp : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
|
||||
{
|
||||
singleView.MainView = new WidgetPanelView
|
||||
{
|
||||
DataContext = new WidgetPanelViewModel()
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
57
LanMountainDesktop.Mobile/ViewModels/WidgetPanelViewModel.cs
Normal file
57
LanMountainDesktop.Mobile/ViewModels/WidgetPanelViewModel.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace LanMountainDesktop.Mobile.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// 组件面板视图模型。
|
||||
/// 移动端不提供桌面自由摆放,组件以卡片流形式呈现。
|
||||
/// 后续由组件运行时(DesktopComponents.Runtime)通过
|
||||
/// <see cref="RegisterWidget"/> 注入真实组件视图。
|
||||
/// </summary>
|
||||
public sealed partial class WidgetPanelViewModel : ObservableObject
|
||||
{
|
||||
public ObservableCollection<WidgetCardViewModel> Widgets { get; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string _title = "组件面板";
|
||||
|
||||
public WidgetPanelViewModel()
|
||||
{
|
||||
// 首版占位卡片:标记组件运行时的接入点。
|
||||
Widgets.Add(new WidgetCardViewModel("时间表", "课程表 / 日程组件将在此呈现"));
|
||||
Widgets.Add(new WidgetCardViewModel("天气", "天气组件将在此呈现"));
|
||||
Widgets.Add(new WidgetCardViewModel("插件组件", "已安装插件提供的组件将在此呈现"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组件运行时接入点:注册一个真实组件卡片。
|
||||
/// </summary>
|
||||
public void RegisterWidget(WidgetCardViewModel widget)
|
||||
{
|
||||
Widgets.Add(widget);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单个组件卡片。<see cref="Content"/> 为空时显示占位说明文本,
|
||||
/// 非空时承载组件运行时提供的真实控件。
|
||||
/// </summary>
|
||||
public sealed partial class WidgetCardViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string _name;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _placeholder;
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _content;
|
||||
|
||||
public WidgetCardViewModel(string name, string placeholder, object? content = null)
|
||||
{
|
||||
_name = name;
|
||||
_placeholder = placeholder;
|
||||
_content = content;
|
||||
}
|
||||
}
|
||||
44
LanMountainDesktop.Mobile/Views/WidgetPanelView.axaml
Normal file
44
LanMountainDesktop.Mobile/Views/WidgetPanelView.axaml
Normal file
@@ -0,0 +1,44 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:LanMountainDesktop.Mobile.ViewModels"
|
||||
x:Class="LanMountainDesktop.Mobile.Views.WidgetPanelView"
|
||||
x:DataType="vm:WidgetPanelViewModel">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Border Grid.Row="0" Padding="20,16">
|
||||
<TextBlock Text="{Binding Title}"
|
||||
FontSize="22"
|
||||
FontWeight="SemiBold" />
|
||||
</Border>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Padding="12,0,12,12">
|
||||
<ItemsControl ItemsSource="{Binding Widgets}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Spacing="12" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:WidgetCardViewModel">
|
||||
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
|
||||
CornerRadius="16"
|
||||
Padding="16"
|
||||
MinHeight="96">
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="{Binding Name}"
|
||||
FontSize="15"
|
||||
FontWeight="SemiBold" />
|
||||
<ContentControl Content="{Binding Content}"
|
||||
IsVisible="{Binding Content, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
||||
<TextBlock Text="{Binding Placeholder}"
|
||||
FontSize="13"
|
||||
Opacity="0.6"
|
||||
TextWrapping="Wrap"
|
||||
IsVisible="{Binding Content, Converter={x:Static ObjectConverters.IsNull}}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
11
LanMountainDesktop.Mobile/Views/WidgetPanelView.axaml.cs
Normal file
11
LanMountainDesktop.Mobile/Views/WidgetPanelView.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace LanMountainDesktop.Mobile.Views;
|
||||
|
||||
public partial class WidgetPanelView : UserControl
|
||||
{
|
||||
public WidgetPanelView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user