Avalonia-实现控件出现时上升效果(简单)

Avalonia实践-实现控件出现时上升效果


最近在学习 Avalonia,看到 WinUI 里有个经典的出现时上升样式,拿来练练手,同时学习 Style 和 Animation
非常简单的动画

目标效果是下面这样

image

Demo

使用版本: Avalonia (11.0.10) CommunityToolkit.Mvvm (8.2.1) .NET8.0
简单用 CommunityToolKit.MVVM 写了一下代码

MainWindowViewModel.cs

using Avalonia.Controls.Shapes;
using Avalonia.Media;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;

namespace StyleSample.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    public ObservableCollection<Rectangle> Rectangles { get; } = [];

    [RelayCommand]
    private void AddRectangle()
    {
        Rectangles.Add(new Rectangle() { Width = 50, Height = 50, Fill = Brushes.Blue, Margin = new(10) });
    }

    [RelayCommand]
    private void RemoveOneRectangle()
    {
        if (Rectangles.Count > 0) Rectangles.RemoveAt(0);
    }

    [RelayCommand]
    private void RemoveAllRectangle()
    {
        Rectangles.Clear();
    }
}

MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:StyleSample.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        x:Class="StyleSample.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/avalonia-logo.ico"
        Title="StyleSample" Width="550"  Height="300">

  <Window.Styles>
	<!-- 具体样式放到后面 -->
  </Window.Styles>

  <Grid ColumnDefinitions="*,Auto" Margin="20">
    <!-- 放矩形的容器 -->
    <ItemsControl ItemsSource="{Binding Rectangles}" VerticalAlignment="Center" Background="Cyan">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <WrapPanel />
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
    </ItemsControl>
    
	<!-- Button -->
    <StackPanel Spacing="10" Grid.Column="1" VerticalAlignment="Center" Margin="10">
      <Button HorizontalAlignment="Stretch" Command="{Binding AddRectangleCommand}">Add one</Button>
      <Button HorizontalAlignment="Stretch" Command="{Binding RemoveOneRectangleCommand}">Remove one</Button>
      <Button HorizontalAlignment="Stretch" Command="{Binding RemoveAllRectangleCommand}">Remove all</Button>
    </StackPanel>
  </Grid>

</Window>

下面就是实现具体样式了

  <Window.Styles>
	
    <Style Selector="Rectangle[IsVisible=True]">
      <Style.Animations>
        <Animation Duration="0:0:0.7" IterationCount="1" Easing="ExponentialEaseOut" >
          <KeyFrame Cue="0%">
            <Setter Property="TranslateTransform.Y" Value="20"/>
            <Setter Property="Opacity" Value="0.0"/>
          </KeyFrame>
        </Animation>
      </Style.Animations>
    </Style>
	
  </Window.Styles>

最终实现效果

image

Avalonia 可以像 css 一样选择特定的对象,然后指定相应的样式,且样式之间可以覆盖

我的实现方式是直接使用动画,设置动画的初始状态为往下偏移 20px,结束状态则是本来的位置
这样在方块展示时就可以直接触发动画,然后返回初始位置

下面介绍样式中的每一个参数

Selector

<Style Selector="Rectangle[IsVisible=True]">
	...
</Style>

指定选择的控件为矩形;[IsVisible=True] 选择控件可见时展示
可以看 样式选择器语法 | Avalonia Docs ,下面列出三个例子

  • 按名称选择 <Style Selector="Button#myButton">
  • 按伪类选择 <Style Selector="Button:focus"> 伪类(Pseudoclasses) | Avalonia Docs
  • 子操作符 <Style Selector="StackPanel > Button"> StackPanel 下的直接子控件 Button

只需要把选择器选择成自己的控件就可以直接使用了

Animation

<Style.Animations>
	<Animation Duration="0:0:0.7" IterationCount="1" Easing="ExponentialEaseOut" >
		...
	</Animation>
</Style.Animations>
  • 使用 Style.Animations 元素来包含动画。
  • 添加一个 Animation 元素,并设置其动画时长 Duration ,格式为 时:分:秒
  • 设置重复次数 IterationCount
  • 设置动画函数 Easing ,可以在这里找 动画设置 | Avalonia Docs 看到了合适的可以直接拿过来用

KeyFrame

<KeyFrame Cue="0%">
    <Setter Property="TranslateTransform.Y" Value="20"/>
    <Setter Property="Opacity" Value="0.0"/>
</KeyFrame>

设置关键帧,关键帧从 0% - 100%,如何使用关键帧动画 | Avalonia Docs
在开始时向原来的位置向下偏移 20px,然后结束时没有设置,默认是原属性,这样就实现了动画
至于有哪些 Transform 属性可以使用不是特别清楚,应该可以在 Avalonia UI Framework - API - ITransform Interface 找一下
image

尾声

ITransform 的实现类不是很清楚,导致在设置关键帧属性时没有参考,翻了挺久的官方文档也没有具体说明有哪些可以用

Avalonia 中文文档

posted @   HUOE  阅读(235)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示