Xamarin.Form跨平臺(tái)訪(fǎng)問(wèn)系統(tǒng)圖片庫(kù)

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

下面,我們就一步一步來(lái)實(shí)現(xiàn)這個(gè)DependencyService調(diào)用嚷那。

聲明接口

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

這里我們將方法聲明為異步的,因?yàn)橹挥械鹊接脩?hù)選擇完圖片之后這個(gè)方法才會(huì)返回忌栅,聲明成異步方法才不至于阻塞主線(xiàn)程车酣。

iOS平臺(tái)下的實(shí)現(xiàn)

在iOS平臺(tái)下曲稼,我們要利用UIImagePickerController
來(lái)打開(kāi)圖片庫(kù)索绪。

[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對(duì)象
            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對(duì)象
                NSData data = image.AsJPEG(1);
                Stream stream = data.AsStream();

                // 將Stream設(shè)置為T(mén)ask的結(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平臺(tái)下的實(shí)現(xiàn)

在Android平臺(tái)下贫悄,我們要聲明一個(gè)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è)置為T(mén)ask的結(jié)果
                PickImageTaskCompletionSource.SetResult(stream);
            }
            else
            {
                PickImageTaskCompletionSource.SetResult(null);
            }
        }
    }
}

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

[assembly: Dependency(typeof(PicturePickerImplementation))]

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

            // 獲取MainActivity的實(shí)例
            MainActivity activity = Forms.Context as MainActivity;

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

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

            // 返回 Task 對(duì)象
            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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窄坦,一起剝皮案震驚了整個(gè)濱河市唤反,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸭津,老刑警劉巖彤侍,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逆趋,居然都是意外死亡盏阶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)闻书,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)名斟,“玉大人,你說(shuō)我怎么就攤上這事魄眉∨檠危” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵坑律,是天一觀的道長(zhǎng)岩梳。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么冀值? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任淘捡,我火速辦了婚禮,結(jié)果婚禮上池摧,老公的妹妹穿的比我還像新娘焦除。我一直安慰自己,他們只是感情好作彤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布膘魄。 她就那樣靜靜地躺著,像睡著了一般竭讳。 火紅的嫁衣襯著肌膚如雪创葡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天绢慢,我揣著相機(jī)與錄音灿渴,去河邊找鬼。 笑死胰舆,一個(gè)胖子當(dāng)著我的面吹牛骚露,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缚窿,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼棘幸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了倦零?” 一聲冷哼從身側(cè)響起误续,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤因惭,失蹤者是張志新(化名)和其女友劉穎环疼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體青自,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葫隙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年栽烂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片停蕉。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愕鼓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慧起,到底是詐尸還是另有隱情菇晃,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布蚓挤,位于F島的核電站磺送,受9級(jí)特大地震影響驻子,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜估灿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一崇呵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馅袁,春花似錦域慷、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弛针,卻和暖如春叠骑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背削茁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工宙枷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茧跋。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓慰丛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親厌衔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子璧帝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

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