xamarin 实现选择文件功能

参考:https://docs.microsoft.com/en-us/xamarin/essentials/file-picker?context=xamarin%2Fandroid&tabs=android

示例:

权限添加——

前端xaml代码——

 <StackLayout Padding="12" Spacing="6">
                    <Label Text="Pick files from storage." FontAttributes="Bold" />

                    <FlexLayout Direction="Row" Wrap="Wrap">
                        <Button Text="Pick file" Command="{Binding PickFileCommand}" HorizontalOptions="FillAndExpand" />
                        <Button Text="Pick image" Command="{Binding PickImageCommand}" HorizontalOptions="FillAndExpand" />
                        <Button Text="Pick pdf" Command="{Binding PickPdfCommand}" HorizontalOptions="FillAndExpand" />
                        <Button Text="Pick custom type" Command="{Binding PickCustomTypeCommand}" HorizontalOptions="FillAndExpand" />
                        <Button Text="Pick image and send email" Command="{Binding PickAndSendCommand}" HorizontalOptions="FillAndExpand" />
                        <Button Text="Pick multiple files" Command="{Binding PickMultipleFilesCommand}" HorizontalOptions="FillAndExpand" />
                    </FlexLayout>

                    <Label Text="{Binding Text}" HorizontalOptions="FillAndExpand" />

                    <Image Source="{Binding Image}" IsVisible="{Binding IsImageVisible}"
               HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
                </StackLayout>

后端viewmodel代码——

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Samples.ViewModel
{
    public class FilePickerViewModel : BaseViewModel
    {
        string text;
        ImageSource image;
        bool isImageVisible;

        public FilePickerViewModel()
        {
            PickFileCommand = new Command(() => DoPickFile());
            PickImageCommand = new Command(() => DoPickImage());
            PickPdfCommand = new Command(() => DoPickPdf());
            PickCustomTypeCommand = new Command(() => DoPickCustomType());
            PickAndSendCommand = new Command(() => DoPickAndSend());
            PickMultipleFilesCommand = new Command(() => DoPickMultipleFiles());
        }

        public ICommand PickFileCommand { get; }

        public ICommand PickImageCommand { get; }

        public ICommand PickPdfCommand { get; }

        public ICommand PickCustomTypeCommand { get; }

        public ICommand PickAndSendCommand { get; }

        public ICommand PickMultipleFilesCommand { get; }

        public string Text
        {
            get => text;
            set => SetProperty(ref text, value);
        }

        public ImageSource Image
        {
            get => image;
            set => SetProperty(ref image, value);
        }

        public bool IsImageVisible
        {
            get => isImageVisible;
            set => SetProperty(ref isImageVisible, value);
        }

        async void DoPickFile()
        {
            await PickAndShow(PickOptions.Default);
        }

        async void DoPickImage()
        {
            var options = new PickOptions
            {
                PickerTitle = "Please select an image",
                FileTypes = FilePickerFileType.Images,
            };

            await PickAndShow(options);
        }

        async void DoPickPdf()
        {
            var options = new PickOptions
            {
                PickerTitle = "Please select a pdf",
                FileTypes = FilePickerFileType.Pdf,
            };

            await PickAndShow(options);
        }

        async void DoPickCustomType()
        {
            var customFileType =
                new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
                {
                    { DevicePlatform.iOS, new[] { "public.my.comic.extension" } }, // or general UTType values
                    { DevicePlatform.Android, new[] { "application/comics" } },
                    { DevicePlatform.UWP, new[] { ".cbr", ".cbz" } },
                    { DevicePlatform.Tizen, new[] { "*/*" } },
                    { DevicePlatform.macOS, new[] { "cbr", "cbz" } }, // or general UTType values
                });

            var options = new PickOptions
            {
                PickerTitle = "Please select a comic file",
                FileTypes = customFileType,
            };

            await PickAndShow(options);
        }

        async void DoPickAndSend()
        {
            // pick a file
            var result = await PickAndShow(PickOptions.Images);
            if (result == null)
                return;

            // copy it locally
            var copyPath = Path.Combine(FileSystem.CacheDirectory, result.FileName);
            using (var destination = File.Create(copyPath))
            using (var source = await result.OpenReadAsync())
                await source.CopyToAsync(destination);

            // send it via an email
            await Email.ComposeAsync(new EmailMessage
            {
                Subject = "Test Subject",
                Body = "This is the body. There should be an image attached.",
                Attachments =
                {
                    new EmailAttachment(copyPath)
                }
            });
        }

        async Task<FileResult> PickAndShow(PickOptions options)
        {
            try
            {
                var result = await FilePicker.PickAsync(options);

                if (result != null)
                {
                    var size = await GetStreamSizeAsync(result);

                    Text = $"File Name: {result.FileName} ({size:0.00} KB)";

                    var ext = Path.GetExtension(result.FileName).ToLowerInvariant();
                    if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif")
                    {
                        var stream = await result.OpenReadAsync();

                        Image = ImageSource.FromStream(() => stream);
                        IsImageVisible = true;
                    }
                    else
                    {
                        IsImageVisible = false;
                    }
                }
                else
                {
                    Text = $"Pick cancelled.";
                }

                return result;
            }
            catch (Exception ex)
            {
                Text = ex.ToString();
                IsImageVisible = false;
                return null;
            }
        }

        async Task<double> GetStreamSizeAsync(FileResult result)
        {
            try
            {
                using var stream = await result.OpenReadAsync();
                return stream.Length / 1024.0;
            }
            catch
            {
                return 0.0;
            }
        }

        async void DoPickMultipleFiles()
        {
            try
            {
                var resultList = await FilePicker.PickMultipleAsync();

                if (resultList != null && resultList.Any())
                {
                    Text = "File Names: " + string.Join(", ", resultList.Select(result => result.FileName));

                    // only showing the first file's content
                    var firstResult = resultList.First();

                    if (firstResult.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) ||
                        firstResult.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase))
                    {
                        var stream = await firstResult.OpenReadAsync();
                        Image = ImageSource.FromStream(() => stream);
                        IsImageVisible = true;
                    }
                    else
                    {
                        IsImageVisible = false;
                    }
                }
                else
                {
                    Text = $"Pick cancelled.";
                    IsImageVisible = false;
                }
            }
            catch (Exception ex)
            {
                Text = ex.ToString();
                IsImageVisible = false;
            }
        }
    }
}

效果——

 

posted @ 2021-04-15 10:29  lishidefengchen  阅读(690)  评论(0编辑  收藏  举报