Artikel ini adalah lanjutan dari artikel sebelumnya tentang pembuatan services di Azure Mobile Services. https://erickkurniawan.net/2017/11/04/xamarin-forms-azure-mobile-services-part-1/
Membuat Xamarin Forms Project
1. Buat Xamarin Forms Project dengan nama SampeMobileAzure.
2. Tambahkan package Microsoft Azure Mobile Client pada project.
3. Kemudian pada project portable tambahkan class Barang sebagai representasi dari table Barang yang ada pada Easy Table di Azure.
using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json; namespace SampleMobileAzure { public class Barang { private string _id; [JsonProperty(PropertyName = "id")] public string Id { get { return _id; } set { _id = value; } } private string _kodeBarang; [JsonProperty(PropertyName = "KodeBarang")] public string KodeBarang { get { return _kodeBarang; } set { _kodeBarang = value; } } private string _namaBarang; [JsonProperty(PropertyName = "NamaBarang")] public string NamaBarang { get { return _namaBarang; } set { _namaBarang = value; } } private int _stok; [JsonProperty(PropertyName = "Stok")] public int Stok { get { return _stok; } set { _stok = value; } } private decimal _hargaBeli; [JsonProperty(PropertyName = "HargaBeli")] public decimal HargaBeli { get { return _hargaBeli; } set { _hargaBeli = value; } } private decimal _hargaJual; [JsonProperty(PropertyName = "HargaJual")] public decimal HargaJual { get { return _hargaJual; } set { _hargaJual = value; } } [Version] public string Version { get; set; } } }
4. Tambahkan juga class dengan nama Constants.cs yang digunakan untuk menyimpan url dari web services yang diakses.
namespace SampleMobileAzure { public static class Constants { public static string ApplicationURL = @"https://actualmobileservices.azurewebsites.net"; } }
5. Tambahkan class BarangManager.cs, tambahkan method yang akan digunakan untuk mengambil data, menambah, dan mengupdate data dari Mobile App services.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.WindowsAzure.MobileServices; using System.Diagnostics; using System.Collections.ObjectModel; namespace SampleMobileAzure { public class BarangManager { private IMobileServiceTable<Barang> _barangTable; public BarangManager() { var client = new MobileServiceClient(Constants.ApplicationURL); _barangTable = client.GetTable<Barang>(); } public async Task<ObservableCollection<Barang>> GetBarangAsync() { try { IEnumerable<Barang> barangs = await _barangTable.ToEnumerableAsync(); return new ObservableCollection<Barang>(barangs); } catch (MobileServiceInvalidOperationException msioe) { Debug.WriteLine("@Invalid sync operation: {0}", msioe.Message); } catch (Exception e) { Debug.WriteLine(@"Sync error: {0}", e.Message); } return null; } public async Task SaveTaskAsync(Barang barang) { if (barang.Id == null) { await _barangTable.InsertAsync(barang); } else { await _barangTable.UpdateAsync(barang); } } } }
6. Tambahkan class dengan nama ActivityIndicatorScope.cs. Class ini akan digunakan untuk menampilkan activity indicator pada saat aplikasi mengambil data dari services.
using System.Threading.Tasks; using Xamarin.Forms; namespace SampleMobileAzure { public class ActivityIndicatorScope : IDisposable { private bool _showIndicator; private ActivityIndicator _indicator; private Task _indicatorDelay; public ActivityIndicatorScope(ActivityIndicator indicator, bool showIndicator) { _indicator = indicator; _showIndicator = showIndicator; if (showIndicator) { _indicatorDelay = Task.Delay(2000); SetIndicatorActivity(true); } else { _indicatorDelay = Task.FromResult(0); } } private void SetIndicatorActivity(bool isActive) { _indicator.IsVisible = isActive; _indicator.IsRunning = isActive; } public void Dispose() { if (_showIndicator) { _indicatorDelay.ContinueWith(t => SetIndicatorActivity(false), TaskScheduler.FromCurrentSynchronizationContext()); } } } }
7. Tambahkan halaman xaml baru dengan nama BarangPage. Halaman ini digunakan untuk menampilkan data barang pada kontrol ListView.
<?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="SampleMobileAzure.BarangPage" Title="List Of Barang"> <ContentPage.ToolbarItems> <ToolbarItem Text="+" Clicked="MenuItem_OnClicked"/> </ContentPage.ToolbarItems> <ContentPage.Content> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ActivityIndicator HorizontalOptions="Center" VerticalOptions="Center" IsVisible="False" IsEnabled="True" x:Name="syncIndicator"/> <ListView x:Name="listViewBarang" ItemTapped="ListView_OnItemTapped" IsPullToRefreshEnabled="True" Refreshing="ListViewBarang_OnRefreshing"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal"> <Label FontSize="16" Text="{Binding KodeBarang}" /> <Label FontSize="16" Text="{Binding NamaBarang}" /> <Label FontSize="16" Text="{Binding Stok}" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </ContentPage.Content> </ContentPage>
8. Kemudian tambahkan kode c#-nya pada BarangPage.xaml.cs.
using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace SampleMobileAzure { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class BarangPage : ContentPage { private BarangManager _barangManager = new BarangManager(); public BarangPage() { InitializeComponent(); } protected override async void OnAppearing() { base.OnAppearing(); await RefreshItems(true); } private async Task RefreshItems(bool showActivityIndicator) { using (var scope = new ActivityIndicatorScope(syncIndicator, showActivityIndicator)) { listViewBarang.ItemsSource = await _barangManager.GetBarangAsync(); } } private async void ListView_OnItemTapped(object sender, ItemTappedEventArgs e) { TambahBarangPage tambahPage = new TambahBarangPage(); Barang item = (Barang) e.Item; tambahPage.BindingContext = item; ((ListView) sender).SelectedItem = null; await Navigation.PushAsync(tambahPage); } private async void MenuItem_OnClicked(object sender, EventArgs e) { TambahBarangPage tambahPage = new TambahBarangPage(true); await Navigation.PushAsync(tambahPage); } private async void ListViewBarang_OnRefreshing(object sender, EventArgs e) { var list = (ListView) sender; Exception error = null; try { await RefreshItems(false); } catch (Exception ex) { error = ex; } finally { list.EndRefresh(); } if (error != null) { await DisplayAlert("Refresh Error !", "Couldn't refresh data (" + error.Message + ")", "OK"); } } } }
9. Kemudian tambahkan halaman dengan nama TambahBarangPage.xaml. Halaman ini akan digunakan untuk menampilkan data, menambah data, dan mengupdate data.
<?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="SampleMobileAzure.TambahBarangPage" Title="Tambah Barang"> <ContentPage.Content> <Grid x:Name="gvBarang"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> </Grid.RowDefinitions> <Label Text="Kode Barang :" HorizontalTextAlignment="End" VerticalTextAlignment="Center" /> <Entry x:Name="txtKodeBarang" Text="{Binding KodeBarang}" Placeholder="masukan kode barang" Grid.Row="0" Grid.Column="1" /> <Label Text="Nama Barang :" HorizontalTextAlignment="End" Grid.Row="1" Grid.Column="0" VerticalTextAlignment="Center" /> <Entry x:Name="txtNamaBarang" Text="{Binding NamaBarang}" Placeholder="masukan nama barang" Grid.Row="1" Grid.Column="1" /> <Label Text="Stok :" HorizontalTextAlignment="End" Grid.Row="2" Grid.Column="0" VerticalTextAlignment="Center" /> <Entry x:Name="txtStok" Text="{Binding Stok, StringFormat='{0:N}'}" Keyboard="Numeric" Placeholder="masukan stok" Grid.Row="2" Grid.Column="1" /> <Label Text="Harga Beli :" HorizontalTextAlignment="End" Grid.Row="3" Grid.Column="0" VerticalTextAlignment="Center" /> <Entry x:Name="txtHargaBeli" Text="{Binding HargaBeli, StringFormat='{0:N}'}" Keyboard="Numeric" Placeholder="masukan harga beli" Grid.Row="3" Grid.Column="1" /> <Label Text="Harga Jual :" HorizontalTextAlignment="End" Grid.Row="4" Grid.Column="0" VerticalTextAlignment="Center" /> <Entry x:Name="txtHargaJual" Text="{Binding HargaJual, StringFormat='{0:N}'}" Keyboard="Numeric" Placeholder="masukan harga jual" Grid.Row="4" Grid.Column="1" /> <StackLayout Orientation="Horizontal" Grid.Row="5" Grid.ColumnSpan="2"> <Button x:Name="btnSave" HorizontalOptions="EndAndExpand" Text="Save" WidthRequest="150" Clicked="BtnSave_OnClicked" /> </StackLayout> </Grid> </ContentPage.Content> </ContentPage>
10. Kemudian tambahkan kode pada TambahBarangPage.xaml.cs untuk menambah dan mengupdate data Barang.
using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace SampleMobileAzure { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class TambahBarangPage : ContentPage { private BarangManager _barangManager = new BarangManager(); private bool _isNew = false; public TambahBarangPage() { InitializeComponent(); } private void ClearAll() { foreach (var ctr in gvBarang.Children) { if (ctr is Entry) { var item = ctr as Entry; item.Text = string.Empty; } } } public TambahBarangPage(bool isNew) { InitializeComponent(); _isNew = isNew; if (_isNew) { txtKodeBarang.Focus(); } } private async void BtnSave_OnClicked(object sender, EventArgs e) { if (_isNew) { var barang = new Barang() { KodeBarang = txtKodeBarang.Text, NamaBarang = txtNamaBarang.Text, Stok = Convert.ToInt32(txtStok.Text), HargaBeli = Convert.ToDecimal(txtHargaBeli.Text), HargaJual = Convert.ToDecimal(txtHargaJual.Text) }; await _barangManager.SaveTaskAsync(barang); ClearAll(); await DisplayAlert("Keterangan", "Data Barang berhasil ditambah !", "OK"); } else { var barang = (Barang) this.BindingContext; await _barangManager.SaveTaskAsync(barang); await DisplayAlert("Keterangan", "Data Barang berhasil diupdate !", "OK"); } } } }
11. Jalankan aplikasi untuk melihat hasilnya pada Android emulator.
using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace SampleMobileAzure { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class TambahBarangPage : ContentPage { private BarangManager _barangManager = new BarangManager(); private bool _isNew = false; public TambahBarangPage() { InitializeComponent(); } private void ClearAll() { foreach (var ctr in gvBarang.Children) { if (ctr is Entry) { var item = ctr as Entry; item.Text = string.Empty; } } } public TambahBarangPage(bool isNew) { InitializeComponent(); _isNew = isNew; if (_isNew) { txtKodeBarang.Focus(); } } private async void BtnSave_OnClicked(object sender, EventArgs e) { if (_isNew) { var barang = new Barang() { KodeBarang = txtKodeBarang.Text, NamaBarang = txtNamaBarang.Text, Stok = Convert.ToInt32(txtStok.Text), HargaBeli = Convert.ToDecimal(txtHargaBeli.Text), HargaJual = Convert.ToDecimal(txtHargaJual.Text) }; await _barangManager.SaveTaskAsync(barang); ClearAll(); await DisplayAlert("Keterangan", "Data Barang berhasil ditambah !", "OK"); } else { var barang = (Barang) this.BindingContext; await _barangManager.SaveTaskAsync(barang); await DisplayAlert("Keterangan", "Data Barang berhasil diupdate !", "OK"); } } } }
using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json; namespace SampleMobileAzure { public class Barang { private string _id; [JsonProperty(PropertyName = "id")] public string Id { get { return _id; } set { _id = value; } } private string _kodeBarang; [JsonProperty(PropertyName = "KodeBarang")] public string KodeBarang { get { return _kodeBarang; } set { _kodeBarang = value; } } private string _namaBarang; [JsonProperty(PropertyName = "NamaBarang")] public string NamaBarang { get { return _namaBarang; } set { _namaBarang = value; } } private int _stok; [JsonProperty(PropertyName = "Stok")] public int Stok { get { return _stok; } set { _stok = value; } } private decimal _hargaBeli; [JsonProperty(PropertyName = "HargaBeli")] public decimal HargaBeli { get { return _hargaBeli; } set { _hargaBeli = value; } } private decimal _hargaJual; [JsonProperty(PropertyName = "HargaJual")] public decimal HargaJual { get { return _hargaJual; } set { _hargaJual = value; } } [Version] public string Version { get; set; } } }