Xamarin.Form跨平臺訪問系統(tǒng)圖片庫

這篇文章主要介紹如何在Xamarin.Form實現(xiàn)跨平臺的調(diào)用系統(tǒng)圖片庫。
由于系統(tǒng)圖片庫是一個平臺相關(guān)性比較大的系統(tǒng)工具,在Xamarin.Form上沒有現(xiàn)成的統(tǒng)一API可用,所以我們只能利用DependencyService
來自己實現(xiàn)一個對系統(tǒng)圖片庫的調(diào)用。

下面,我們就一步一步來實現(xiàn)這個DependencyService調(diào)用。

聲明接口

namespace DependencyServiceSample
{
    public interface IPicturePicker
    {
        Task<Stream> GetImageStreamAsync();
    }
}

這里我們將方法聲明為異步的,因為只有等到用戶選擇完圖片之后這個方法才會返回,聲明成異步方法才不至于阻塞主線程。

iOS平臺下的實現(xiàn)

在iOS平臺下,我們要利用UIImagePickerController
來打開圖片庫。

[assembly: Dependency (typeof (PicturePickerImplementation))]

namespace DependencyServiceSample.iOS
{
    public class PicturePickerImplementation : IPicturePicker
    {
        TaskCompletionSource<Stream> taskCompletionSource;
        UIImagePickerController imagePicker;

        public Task<Stream> GetImageStreamAsync()
        {
            // 創(chuàng)建UIImagePickerController
            imagePicker = new UIImagePickerController
            {
                SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
                MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary)
            };

            // 添加事件處理
            imagePicker.FinishedPickingMedia += OnImagePickerFinishedPickingMedia;
            imagePicker.Canceled += OnImagePickerCancelled;

            // 顯示UIImagePickerController;
            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            var viewController = window.RootViewController;
            viewController.PresentModalViewController(imagePicker, true);

            // 返回Task對象
            taskCompletionSource = new TaskCompletionSource<Stream>();
            return taskCompletionSource.Task;
        }
        void OnImagePickerFinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs args)
        {
            UIImage image = args.EditedImage ?? args.OriginalImage;

            if (image != null)
            {
                //將 UIImage轉(zhuǎn)換成 .NET Stream對象
                NSData data = image.AsJPEG(1);
                Stream stream = data.AsStream();

                // 將Stream設(shè)置為Task的結(jié)果
                taskCompletionSource.SetResult(stream);
            }
            else
            {
                taskCompletionSource.SetResult(null);
            }
            imagePicker.DismissModalViewController(true);
        }

        void OnImagePickerCancelled(object sender, EventArgs args)
        {
            taskCompletionSource.SetResult(null);
            imagePicker.DismissModalViewController(true);
        }
    }
}

為了使程序可以正常運(yùn)行,我們還需要在plist文件中的dict段里添加如下聲明:

<key>NSPhotoLibraryUsageDescription</key>
<string>Picture Picker uses photo library</string>

Android平臺下的實現(xiàn)

在Android平臺下,我們要聲明一個Activity。

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    ...
    // 以下是為圖片選擇器而聲明的字段、屬性和方法
    public static readonly int PickImageId = 1000;

    public TaskCompletionSource<Stream> PickImageTaskCompletionSource { set; get; }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
    {
        base.OnActivityResult(requestCode, resultCode, intent);

        if (requestCode == PickImageId)
        {
            if ((resultCode == Result.Ok) && (intent != null))
            {
                Android.Net.Uri uri = intent.Data;
                Stream stream = ContentResolver.OpenInputStream(uri);

                // 將Stream設(shè)置為Task的結(jié)果
                PickImageTaskCompletionSource.SetResult(stream);
            }
            else
            {
                PickImageTaskCompletionSource.SetResult(null);
            }
        }
    }
}

還有圖片選擇器的實現(xiàn):

[assembly: Dependency(typeof(PicturePickerImplementation))]

namespace DependencyServiceSample.Droid
{
    public class PicturePickerImplementation : IPicturePicker
    {
        public Task<Stream> GetImageStreamAsync()
        {
            // 定義一個用于獲取圖片的Intent
            Intent intent = new Intent();
            intent.SetType("image/*");
            intent.SetAction(Intent.ActionGetContent);

            // 獲取MainActivity的實例
            MainActivity activity = Forms.Context as MainActivity;

            //啟動圖片選擇的 activity (選擇結(jié)果在MainActivity.cs中處理)
            activity.StartActivityForResult(
                Intent.CreateChooser(intent, "Select Picture"),
                MainActivity.PickImageId);

            // 保存一個TaskCompletionSource 對象作為 MainActivity的屬性
            activity.PickImageTaskCompletionSource = new TaskCompletionSource<Stream>();

            // 返回 Task 對象
            return activity.PickImageTaskCompletionSource.Task;
        }
    }
}

在Xamarin.Form中調(diào)用圖片選擇器

 Stream stream = await DependencyService.Get<IPicturePicker>().GetImageStreamAsync();

 if (stream != null)
    {
        Image image = new Image
        {
            Source = ImageSource.FromStream(() => stream)
        };
    }

參考文獻(xiàn)

Picking a Photo from the Picture Library

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,812評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 不打開相冊就不必想你的樣子,不傾吐過往就不必念你的名字,不重復(fù)那首合唱的歌就不必遺憾你的品位與我相似。我真的沒有想...
    一枚小番茄閱讀 498評論 0 0
  • 作為新媒體的小白,一直都以為微信公眾平臺上那個編輯器就是千萬篇熱點(diǎn)文章的溫床,滾了一番鼠標(biāo)后,我只有呵呵噠!以下是...
    水牛哥閱讀 577評論 0 0
  • 2017年11月17日 星期五 天陰 不敢上路怕扣分肆無忌憚...
    _阿南_閱讀 258評論 0 1

友情鏈接更多精彩內(nèi)容