简体   繁体   English

Xamarin形式的平移图像

[英]Pan Image in Xamarin Forms

I try to create a ContentPage, where i can do an article presentation with rotation (just multiple images), comparable to this solution: http://www.360-javascriptviewer.com/index.html . 我尝试创建一个ContentPage,可以在其中进行旋转的文章演示(仅显示多个图像),与以下解决方案类似: http : //www.360-javascriptviewer.com/index.html When the user does a Pan Gesture the image needs to be exchanged. 用户进行“平移手势”时,需要交换图像。

View: 视图:

<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>

Viewmodel/Model: 视图模型/模型:

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);
    }
}

I hope you understand what i tried to do: OnPanUpdated loads a new Image from the Filesystem, depending on how far the user panned. 我希望您理解我试图做的事情:OnPanUpdated从文件系统加载新图像,具体取决于用户平移的距离。 On UWP Platform it is working, but far away from running... very laggy and no "realtime" rotation. 在UWP Platform上,它正在运行,但是距离运行很远……非常缓慢,并且没有“实时”旋转。 On Android I get an out of memory exception after 2 successful pans. 在Android上,两次成功平移后,出现内存不足异常。 Is my approach generally wrong? 我的方法通常是错误的吗? How could I handle the image changing? 如何处理图像变化?

Thanks for any answers! 感谢您的任何答案!

It sort of looks like you are trying to emulate what a CarouselView does. 看起来您正在尝试模仿CarouselView功能。 You may want to take a look at using this control which will allow you to swipe between images. 您可能需要看一下使用此控件的方法,该控件可让您在图像之间滑动。 It also is virtualized, so you will likely not run into those memory issues. 它还是虚拟化的,因此您可能不会遇到这些内存问题。

There is a post on the Xamarin blog to help get started, here . Xamarin博客上有一篇文章可以帮助您入门,请点击这里

This package is available on NuGet and is currently a pre-release version, so make sure you are searching with Include PreRelease Packages checked in Visual Studio. 此程序包在NuGet上可用,并且当前是预发行版本,因此请确保您正在使用Visual Studio中选中的“包括预发布程序包”进行搜索。

Sample from blog post: 博客文章样本:

Since the CarouselView is in a separate assembly, we must bring in the CarouselView's namespace in root of our page: 由于CarouselView位于单独的程序集中,因此我们必须在页面的根目录中引入CarouselView的名称空间:

xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"

Then, add the control to your page content: 然后,将该控件添加到页面内容中:

<cv:CarouselView ItemsSource="{Binding Images}" x:Name="CarouselImages">
    <cv:CarouselView.ItemTemplate>
      <DataTemplate>
        <Grid>
          <Image Source="{Binding Url}"/>
        </Grid>
      </DataTemplate>
    </cv:CarouselView.ItemTemplate>
  </cv:CarouselView>

If you are building applications for Windows, a DataTemplate needs to be added to the Application Resources in the App.xaml of the application. 如果要为Windows构建应用程序,则需要将DataTemplate添加到应用程序App.xaml中的“应用程序资源”中。

First add a new namespace in the root node: 首先在根节点中添加一个新的名称空间:

xmlns:uwp="using:Xamarin.Forms.Platform"

Then add the following to the Application.Resources node: 然后将以下内容添加到Application.Resources节点:

<DataTemplate x:Key="ItemTemplate">
    <uwp:ItemControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
</DataTemplate>

It should look something like this: 它看起来应该像这样:

<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>

Linker Considerations 链接器注意事项

To ensure that the CarouselView does not get “Linked-out” when compiling in release mode ensure that you are using Compiled XAML by adding the following code into the project's AssemblyInfo.cs where your XAMLexists: 为确保在发布模式下进行编译时CarouselView不会被“链接输出”,请通过将以下代码添加到XAML存在的项目的AssemblyInfo.cs中,确保您使用的是已编译的XAML:

using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

Or add the following code after the Forms.Init(); 或在Forms.Init()之后添加以下代码; call in each project: 调用每个项目:

var cv = typeof (Xamarin.Forms.CarouselView);
var assembly = Assembly.Load(cv.FullName);

Additional Resources: 其他资源:

Forms Documentation 表格文件

Source code for sample 样本源代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM