Xamarin。表示在导航另一页后如何在同一页面上保存图像

时间:2016-06-08 12:43:22

标签: c# xamarin xamarin.ios xamarin.android xamarin.forms

我已在我的个人资料页面上传了图片,我希望保留该图片,直到我以xamarin格式退出。

如果我选择另一个页面,我的图像将丢失,所以我想保留它直到我退出。

var profile = new Image { };
profile.Source = "profile.png";
profile.HorizontalOptions = LayoutOptions.StartAndExpand;
profile.VerticalOptions = LayoutOptions.StartAndExpand;

var profiletap = new TapGestureRecognizer();

profiletap.Tapped += async (s, e) =>
{
    var file = await CrossMedia.Current.PickPhotoAsync();
    if (file == null)
        return;
    await DisplayAlert("File Location", file.Path, "OK");

    im = ImageSource.FromStream(() =>
    {
        var stream = file.GetStream();
        //file.Dispose();
        return stream;
    });

    profile.Source = im;

//   await Navigation.PushModalAsync(new PhotoPage(im));
};

profile.GestureRecognizers.Add(profiletap);

1 个答案:

答案 0 :(得分:2)

导航到另一个页面并返回时,页面不会被破坏,这就是页面构造函数仅在第一次显示时才被执行的原因。所以当你说你想要保留那个形象时,我不确定你的意思。

话说回来,您总是可以将整个profile变量分配到static类中的App全局变量,如下所示,无论如何都保持不变。然后你必须在正确的时间分配/初始化全局变量。

但是,我不确定这是否有必要,所以你可能会尝试更多地解释这个问题:

App课程中:

public class App : Application {

    public static Image ProfileImage = new Image {
        Source            = "profile.png",
        HorizontalOptions = LayoutOptions.StartAndExpand,
        VerticalOptions   = LayoutOptions.StartAndExpand
    };
    ....
}

然后在你的页面中:

public class ProfilePage : ContentPage {

    public ProfilePage() {

        ....

        App.ProfileImage.GestureRecognizers.Add(profiletap);
    }

}

编辑:有关使用插件允许用户从其设备的相机胶卷中选择照片的示例,请参阅我的回答here。获得照片路径后,只需使用HttpClient即可发送图像和base64字符串。网上还有很多关于如何做到这一点的例子。

编辑#2:在此代码行之后:

var file = await CrossMedia.Current.PickPhotoAsync();

您现在拥有file变量中的文件和路径。因此,目前您所做的只是使用ImageSource.FromStream显示图像,但为了在返回页面时继续显示图像,您还需要将图像保存到设备中。为此,您需要在每个项目中编写特定于平台的代码,并在共享代码中引用该代码。像这样:

在您的iOS和Android项目中,创建一个新文件(例如FileHelper_Android.csFileHelper_iOS.cs)并添加以下内容(相同的代码可以添加到iOS和Android文件中,只需更改类和文件的名称:

using ....;

[assembly: Dependency(typeof(FileHelper_Android))]

namespace YourNamespace.Droid{

    /// <summary>
    /// Responsible for working with files on an Android device.
    /// </summary>
    internal class FileHelper_Android : IFileHelper {

        #region Constructor

        public FileHelper_Android() { }

        #endregion

        public string CopyFile(string sourceFile, string destinationFilename, bool overwrite = true) {

            if(!File.Exists(sourceFile)) { return string.Empty; }
            string fullFileLocation = Path.Combine(Environment.GetFolderPath (Environment.SpecialFolder.Personal), destinationFilename);
            File.Copy(sourceFile, fullFileLocation, overwrite);
            return fullFileLocation;
        }
    }
}

在iOS上执行相同操作,只需更改文件名即可。现在,在您的共享项目中,您需要像这样创建IFileHelper.cs

public interface IFileHelper {

    string CopyFile(string sourceFile, string destinationFilename, bool overwrite = true);

}

最后,在您的页面中,您将编写以下内容:

_fileHelper = _fileHelper ?? DependencyService.Get<IFileHelper>();

profiletap.Tapped += async (s, e) =>
{
    var file = await CrossMedia.Current.PickPhotoAsync();
    if (file == null)
        return;
    await DisplayAlert("File Location", file.Path, "OK");

    profile.Source = im;

    imageName = "SomeUniqueFileName" + DateTime.Now.ToString("yyyy-MM-dd_hh-mm-ss-tt");
    filePath  = _fileHelper.CopyFile(file.Path, imageName);

    im = ImageSource.FromFile(filePath)

//   await Navigation.PushModalAsync(new PhotoPage(im));
};

上面,一旦用户选择了该文件,我们就会在本地复制该文件,并且我们还将您的im变量设置为新的本地文件路径,该路径从IFileHelper.CopyFile方法返回。

当用户返回页面或关闭再打开应用程序时,您仍需要处理此案例。在这种情况下,您需要加载保存的图像路径。我建议将图像路径保存到数据库中,除非用户只有一个配置文件图像,然后你总是可以加载相同的路径和文件名。如果您还有问题,请告诉我。