在 Xamarin 窗体中平移图像
本文关键字:图像 Xamarin 窗体 | 更新日期: 2023-09-27 17:56:59
我尝试创建一个内容页面,在那里我可以旋转(只有多个图像)进行文章演示,类似于以下解决方案:http://www.360-javascriptviewer.com/index.html。当用户执行平移手势时,需要交换图像。
视图:
<ContentPage.Content>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image Source="{Binding SelectedArticleImage.ImageSource}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Image.GestureRecognizers>
<PanGestureRecognizer PanUpdated="OnPanUpdated"/>
</Image.GestureRecognizers>
</Image>
<Label Text="A simple Label for test purposes"/>
</StackLayout>
</ContentPage.Content>
视图模型/模型:
public partial class RotationPage : ContentPage
{
public RotationPage()
{
InitializeComponent();
BindingContext = App.Locator.Rotation;
}
public void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
App.Locator.Rotation.OnPanUpdated(sender, e);
}
}
public class RotationViewModel : ViewModelBase
{
private double panValueBeginning;
private double panValueRunning;
private double screenWidthFactor = 100;
private List<ArticleImage> articleImages;
private ArticleImage selectedArticleImage;
public ArticleImage SelectedArticleImage
{
get
{
return (selectedArticleImage == null ? articleImages.FirstOrDefault() : selectedArticleImage);
}
set
{
Set(() => SelectedArticleImage, ref selectedArticleImage, value);
}
}
public RotationViewModel()
{
articleImages = new List<ArticleImage>();
LoadImageList();
}
private void LoadImageList()
{
for (int i = 0; i < 64; i++)
{
string name = "_" + (i + 1).ToString("D2") + ".jpg";
articleImages.Add(new ArticleImage(name));
}
}
public void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
Debug.WriteLine(e.StatusType.ToString() + ": " + e.TotalX);
switch (e.StatusType)
{
case GestureStatus.Started:
panValueRunning = 0;
break;
case GestureStatus.Running:
panValueRunning = e.TotalX;
SelectImage(e.StatusType, e.TotalX);
break;
case GestureStatus.Completed:
panValueBeginning = panValueRunning;
SelectImage(e.StatusType, e.TotalX);
break;
case GestureStatus.Canceled:
panValueBeginning = 0;
break;
}
}
private void SelectImage(GestureStatus status, double totalX)
{
double panValueRelative = (panValueBeginning + panValueRunning) % screenWidthFactor;
double panValueAbsolute = (panValueRelative < 0 ? screenWidthFactor : 0) + panValueRelative;
int index = Convert.ToInt32(Math.Max(1, Math.Min((panValueAbsolute / screenWidthFactor) * articleImages.Count, articleImages.Count))) - 1;
SelectedArticleImage = articleImages[index];
}
}
public class ArticleImage
{
public string Path { get; }
public ImageSource ImageSource { get; set; }
public ArticleImage(string path)
{
Path = path;
ImageSource.FromFile(path);
}
}
我希望您了解我尝试执行的操作:OnPanUpdated 从文件系统加载新图像,具体取决于用户平移的距离。在 UWP 平台上,它正在工作,但远未运行......非常滞后,没有"实时"旋转。在 Android 上,我在 2 次成功平移后出现内存不足异常。我的方法通常是错误的吗?我该如何处理图像更改?
感谢您的任何回答!
你正在试图模仿CarouselView
的作用。您可能需要查看使用此控件,该控件将允许您在图像之间轻扫。它也是虚拟化的,因此您可能不会遇到这些内存问题。
Xamarin博客上有一篇文章可以帮助入门,在这里。
此包在 NuGet 上可用,当前是预发行版本,因此请确保在搜索时选中 Visual Studio 中的"包括预发行包"。
博客文章示例:
由于轮播视图位于单独的程序集中,因此我们必须在页面的根目录中引入轮播视图的命名空间:
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
然后,将控件添加到页面内容:
<cv:CarouselView ItemsSource="{Binding Images}" x:Name="CarouselImages">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding Url}"/>
</Grid>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
如果要为 Windows 生成应用程序,则需要将数据模板添加到应用程序的 App.xaml 中的应用程序资源中。
首先在根节点中添加一个新的命名空间:
xmlns:uwp="using:Xamarin.Forms.Platform"
然后将以下内容添加到"应用程序资源"节点:
<DataTemplate x:Key="ItemTemplate">
<uwp:ItemControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
</DataTemplate>
它应该看起来像这样:
<Application
x:Class="MyApp.UWP.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uwp="using:Xamarin.Forms.Platform"
xmlns:local="using:MyApp.UWP"
RequestedTheme="Light">
<Application.Resources>
<DataTemplate x:Key="ItemTemplate">
<uwp:ItemControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
</DataTemplate>
</Application.Resources>
</Application>
链接器注意事项
若要确保轮播视图在发布模式下编译时不会"链接出",请确保通过将以下代码添加到项目的 AssemblyInfo(XAML 所在的位置).cs使用已编译的 XAML:
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
或者在每个项目中的 Forms.Init(); 调用之后添加以下代码:
var cv = typeof (Xamarin.Forms.CarouselView);
var assembly = Assembly.Load(cv.FullName);
其他资源:
表单文档
示例的源代码