101*_*ris 1 xamarin xamarin.forms
我想在我的Xamarin表格上放一点动画徽标.
它基本上有效,但看起来很糟糕.IE闪烁
它似乎是ImageSource.FromFile()是懒惰的,每次访问时都从存储器加载文件,或者设置Image.Source没有缓冲并导致撕裂/闪烁,或两者兼而有之?
我是xamarin的新手,我以前从未在本机java/obj-c中使用过这个问题.
有没有人有什么建议?有没有办法强制ImageSource实际预先加载到内存中?有没有办法更新Image.Source属性没有闪烁?或者我应该尝试转移到XamarinIOS/Android自定义(本机)控件?
public partial class SplashIntro : ContentPage {
ImageSource[] sprites = new ImageSource[17];
public SplashIntro() {
InitializeComponent();
LoadSplashImages();
this.Appearing += SplashIntro_Appearing;
}
private void SplashIntro_Appearing(object sender, EventArgs e) {
PlayAni();
}
void LoadSplashImages() {
for (int i = 0; i < sprites.Length; i++) {
ImageSource ims = ImageSource.FromFile($"logani{i + 1}.png");
sprites[i] = ims;
}
}
void PlayAni() {
aniImage.Source = sprites[0];
int nextFrame = 1;
Device.StartTimer(TimeSpan.FromMilliseconds(80), () => {
// Device.BeginInvokeOnMainThread(() => { aniImage.Source = sprites[nextFrame]; });
aniImage.Source = sprites[nextFrame];
nextFrame++;
if (nextFrame == sprites.Length) nextFrame = 0;
return true;
});
}
}
Run Code Online (Sandbox Code Playgroud)
通过自定义渲染器执行此操作将是了解每个平台功能的最佳方法:
iOS:这可以通过将UIImages 数组应用于UIImageView.AnimationImage属性来完成.
Android:一种方法,就是将"动画列表"设置为可绘制的背景ImageView.
(gif很奇怪,但这两种技术在设备上运行顺畅(大多数模拟器;-)
注意:此示例代码使用10个图像(frame_X.png),这些图像链接在iOS 资源和Android 资源/ drawable下.
Xamarin.Forms具有Image可绑定Animate属性的自定义控件:public class AnimatedImage : Image
{
public static readonly BindableProperty AnimateProperty = BindableProperty.Create(
propertyName: "Animate",
returnType: typeof(bool),
declaringType: typeof(AnimatedImage),
defaultValue: false);
public bool Animate
{
get { return (bool)GetValue(AnimateProperty); }
set { SetValue(AnimateProperty, value); }
}
}
Run Code Online (Sandbox Code Playgroud)
ImageRenderer:[assembly: ExportRenderer(typeof(AnimatedImage), typeof(AnimatedImageRenderer_iOS))]
namespace AnimImage.iOS
{
public class AnimatedImageRenderer_iOS : ImageRenderer
{
const int imageCount = 10;
NSMutableArray imageArray;
public AnimatedImageRenderer_iOS() {
imageArray = new NSMutableArray(imageCount);
for (int i = 0; i < imageCount; i++)
imageArray.Add(UIImage.FromFile(new NSString($"frame_{i}.png")));
}
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.AnimationImages = NSArray.FromArray<UIImage>(imageArray);
Control.AnimationDuration = 1;
Control.AnimationRepeatCount = 0;
if (e.NewElement != null)
{
if ((e.NewElement as AnimatedImage).Animate)
Control.StartAnimating();
}
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Animate")
{
if ((sender as AnimatedImage).Animate)
Control?.StartAnimating();
else
Control?.StopAnimating();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
ImageRenderer:[assembly: ExportRenderer(typeof(AnimatedImage), typeof(AnimatedImageRenderer_Droid))]
namespace AnimImage.Droid
{
public class AnimatedImageRenderer_Droid : ImageRenderer
{
public AnimatedImageRenderer_Droid() { }
AnimationDrawable anim;
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.SetBackgroundResource(Resource.Drawable.animatedlogo);
if (e.NewElement != null)
{
if ((e.NewElement as AnimatedImage).Animate)
{
(Control.Background as AnimationDrawable)?.Start();
Control.ImageAlpha = 0;
}
}
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Animate")
{
if ((sender as AnimatedImage).Animate)
{
(Control.Background as AnimationDrawable)?.Start();
Control.ImageAlpha = 0;
}
else
{
Control.ImageAlpha = 255;
(Control.Background as AnimationDrawable)?.Stop();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
animation-listDrawable:<?xml version="1.0" encoding="UTF-8" ?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/frame_0" android:duration="100" />
<item android:drawable="@drawable/frame_1" android:duration="100" />
<item android:drawable="@drawable/frame_2" android:duration="100" />
<item android:drawable="@drawable/frame_3" android:duration="100" />
<item android:drawable="@drawable/frame_4" android:duration="100" />
<item android:drawable="@drawable/frame_5" android:duration="100" />
<item android:drawable="@drawable/frame_6" android:duration="100" />
<item android:drawable="@drawable/frame_7" android:duration="100" />
<item android:drawable="@drawable/frame_8" android:duration="100" />
<item android:drawable="@drawable/frame_9" android:duration="100" />
</animation-list>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |