XAML in Xamarin.Forms 基礎篇 電子書

特別說明

2017/11/22

Xamarin.Forms / .NET Standard 體驗之旅 4 : QR Code 條碼掃描

在 Xamarin.Forms / .NET Standard 體驗之旅 4 的文章中,我們將要來測試每次進行 Xamarin.Forms 實戰課程,大家最想要學習與使用的這個 NuGet 套件:ZXing.Net.Mobile,也就是要開發出具有跨平台的條碼掃描程式。
我們從這個套件在 NuGet 官網上的內容可以看的出來,這個 NuGet 套件尚未支援 .NET Standard 標準類別庫,而是之前的可攜式 PCL 類別庫,不過,因為 .NET Standard 2.0 類別庫也支援可以使用 PCL 類別庫,因此,我們來測試看看,這個套件可否用於 Prism Template Pack 2.0.7 產生的 Xamarin.Forms 跨平台專案,並且進行一維條碼或者二維條碼 QR Code。
Realm NuGet

測試範例專案原始碼

這篇文章中的測試範例專案原始碼,您可以從這裡取得 https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFQRCode

開始建立專案

請點選功能表 [檔案] > [新增] > [專案],此時,您會看到底下的 [新增專案] 對話視窗。
我們點選 Prism Template Pack 提供的 Xamarin.Forms 專用的專案樣板,請點選 [已安裝] > [Visual C#] > [Prism] > [Prism Blank App (Xamarin.Forms)]。
接著在名稱欄位輸入該專案名稱後,點選 [確定] 按鈕,以建立此練習專案。
然後,在 [PRISM PROJEC WIZAD] 對話窗中,選擇您要跨平台的作業系統,容器 (Container) 這裡,我個人喜歡與習慣使用 Prism,您可以選擇您自己要用的容器,最後,點選 [CREATE PROJECT] 按鈕。
.NET Standard Xamarin.Forms Project

安裝 ZXing.Net.Mobile.Forms NuGet 套件

在這裡,請使用滑鼠右建,點選剛剛建立好的共用類別庫(也就是 .NET Standard 標準類別庫)節點,選擇 [管理方案的 NuGet 套件] 項目。
在 [瀏覽] 標籤頁次上,輸入 ZXing.Net.Mobile 這個關鍵字,搜尋出這個套件。請選擇 ZXing.Net.Mobile.Forms 這個套件,要來安裝到 .NET Standard 專案內。
從下圖中,我們可以看到這個套件並不支援 .NET Standard,不過,我們還是要把這個套件安裝到 .NET Standard 專案內。
ZXing.Net.Mobile.Forms
當我們點選 [安裝] 按鈕之後,會看到 Visual Studio 會提示您這樣會安裝那些相依性的套件。
.NET Standard Xamarin.Forms Project

修正首頁頁面

我們對於這個應用程式的設計構想是這樣的,當這個應用程式一旦啟動,會在螢幕上顯示一個按鈕,和一些 Label 欄位,這些 Label 欄位是要用來顯示掃描到的條碼資訊。因此,當使用者按下 Scan... 按鈕之後,就會切換到另外一個頁面,這個頁面將會使用 ZXingScannerView 用來進行協助我們做到條碼掃描的工作。
安裝好套件之後,讓我們打開 MainPage.xaml 檔案,修改XAML內容。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFQRCode.Views.MainPage"
             Title="ZXing.Net.Mobile 條碼掃描">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Label
            Text="條碼類型"/>
        <Label
            Text="{Binding BarcodeFormatType}"/>
        <Label
            Text="{Binding BarcodeResult}"/>
        <Button
            Text="Scan..."
            Command="{Binding ScanCommand}"/>
    </StackLayout>

</ContentPage>
接著我們打開 MainPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
這裡特別說明的是,當掃描條碼的頁面有掃描到結果,我們是透過頁面導航機制提供的相關事件,進行讀取來自掃描頁面的掃描結果。因此,您可以觀察 OnNavigatingTo 方法,我們將會透過比對 parameters.ContainsKey("Result")表示式,確認該事件可以讀取掃描結果內容。
namespace XFQRCode.ViewModels
{

    public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string BarcodeFormatType { get; set; }
        public string BarcodeResult { get; set; }

        public DelegateCommand ScanCommand { get; set; }

        private readonly INavigationService _navigationService;

        public MainPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;

            ScanCommand = new DelegateCommand(() =>
            {
                _navigationService.NavigateAsync("ScanPage");
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {
            if(parameters.ContainsKey("Result"))
            {
                var fooReslut = parameters["Result"] as Result;
                BarcodeFormatType = fooReslut.BarcodeFormat.ToString();
                BarcodeResult = fooReslut.Text;
            }
        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {

        }

    }

}

新增條碼頁面

接下來,我們需要新建立一個頁面,ScanPage,我們將會在這個頁面上使用 ZXingScannerView 用來進行協助我們做到條碼掃描的工作。
當新增完成 ScanPage 頁面,讓我們打開 ScanPage.xaml 檔案,修改XAML內容。
首先我們先宣告一個新的命名空間,xmlns:Zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms",這樣,我們就可以使用這個命名空間前置詞參考到這個 ZXingScannerView 控制項。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:Zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="XFQRCode.Views.ScanPage"
             Title="進行條碼掃描中..."
             >

    <Grid
        >
        <Zxing:ZXingScannerView
            HorizontalOptions="Fill"
            IsAnalyzing="{Binding IsAnalyzing}"
            IsScanning="{Binding IsScanning}"
            Result="{Binding ScanResult, Mode=TwoWay}" 
            ScanResultCommand="{Binding ScanResultCommand}"
             />
        <Zxing:ZXingDefaultOverlay Opacity="0.9" ShowFlashButton="False" />
    </Grid>
</ContentPage>
接著我們打開 ScanPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
一旦條碼有掃描到之後,將會執行 ScanResultCommand 的委派方法,不過,您需要特別注意,我們需要使用 Device.BeginInvokeOnMainThread 方法,將您要執行的程式碼,全部都指定在 UI (Main) Thread 上運行。
namespace XFQRCode.ViewModels
{

    public class ScanPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public bool IsAnalyzing { get; set; } = true;
        public bool IsScanning { get; set; } = true;
        public Result ScanResult { get; set; }
        private readonly INavigationService _navigationService;

        public DelegateCommand ScanResultCommand { get; set; }

        public ScanPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;


            ScanResultCommand = new DelegateCommand(async () =>
            {
                Device.BeginInvokeOnMainThread(async () =>
                {
                    IsAnalyzing = false;
                    IsScanning = false;
                    var fooPara = new NavigationParameters();
                    fooPara.Add("Result", ScanResult);
                    // 回到上頁,並且把掃描結果帶回去
                    await _navigationService.GoBackAsync(fooPara);
                });
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {

        }

    }
}

進行測試

最後,設定預設起始專案為 Android 專案,並且需要使用實體手機來進行測試。

Acr.UserDialogs 執行結果 Acr.UserDialogs 執行結果

沒有留言:

張貼留言