Xamarin iOS – Using UITableView with Custom Cell

Xamarin iOS – Using UITableView with Custom Cell

Salah satu control yang cukup sering digunakan pada pengembangan aplikasi adalah table. Pada iOS table sering ditampilkan dengan menggunakan sebuah control bernama UITableView (bagi anda yang familiar dengan Android, control ini mirip dengan ListView). Bagaimana menggunakan UITableView pada Xamarin?

Anda dapat menambahkan UITableView yang dipilih dari “toolbox” dan memasukkannya ke dalam UIViewController. Pada tulisan ini saya akan menambahkan UITableView ke dalam WelcomeController yang sudah dibuat pada tulisan sebelumnya. Tampilan design storyboard setelah penambahan UITableView adalah sebagai berikut :

screen-shot-2016-11-02-at-12-30-37-pm

Beri initial pada UITableView yang sudah ditambahkan dengan nama “My_Table”. UITableView akan menampilkan sekumpulan data dimana setiap row data akan diletakkan pada sebuah UITableViewCell. UITableViewCell sendiri secara default sudah include di dalam UITableView seperti gambar berikut :

screen-shot-2016-11-02-at-12-49-20-pm

Setiap UITableView dapat memiliki beberapa jenis UITableViewCell yang memiliki tampilan berbeda-beda sesuai kebutuhan. Pastikan anda memberi identitas “identifier” pada setiap UITableViewCell agar dapat dikenali oleh aplikasi, pada contoh ini saya akan berikan identifier  pada cell saya dengan nama “Simple_Cell”.

UITableViewCell memiliki beberapa jenis tampilan untuk dipilih :

screen-shot-2016-11-02-at-12-52-36-pm

Jika anda memilih jenis selain “Custom” maka UITableViewCell akan memiliki tampilan simple  yang sudah memiliki format default dari iOS seperti berikut :

pizap-com14780667820401

Berikut adalah contoh membuat UITableView dengan tampilan “Right Detail”. Pertama-tama silahkan atur property UITableViewCell style anda dengan style “Right Detail”. Aplikasi yang kita buat akan membuat screen dengan sebuah UITableView yang akan menampilkan daftar nama football player beserta club-nya. Buat terlebih dahulu class model untuk Player, tambahkan sebuah class dengan nama “Player.cs” dan masukkan code berikut :

namespace ios_playground
{
   public class Player
   {
      private string name;
      private string club;

      public Player(string name,string club)
      {
          this.name = name;
          this.club = club;
      }

      public string Name
      {
           get { return this.name; }
      }

      public string Club
      {
           get { return this.club; }
      }
   }
}

UITableView akan menampilkan data source yang berasal dari class “UITableViewSource”. Class yang meng-extend UITableViewSource inilah yang akan mengeksuksi tampilan yang muncul pada setiap row data beserta event yang dilaksanakan pada setiap row. Buatlah sebuah class “SimpleSource” yang akan meng-extend class UITableViewSource dan masukkan code seperti berikut :

using System;
using System.Collections.Generic;
using Foundation;
using UIKit;

namespace ios_playground
{
   public class SimpleSource : UITableViewSource
   {
       //variable yang menyimpan list data
       List<Player> datas;
       //identifier cell yang akan ditampilkan
       string CellIdentifier = "Simple_Cell";

       public SimpleSource(List<Player> datas)
       {
           this.datas = datas;
       }

       public override nint RowsInSection(UITableView tableview, nint section)
       {
            return datas.Count;
       }

       public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
       {
            UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
            Player single_data = this.datas[indexPath.Row];

            if (cell == null)
            { 
                cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); 
            }

            //konfigurasi data.Name ke textLabel sedangkan data.Club ditampilkan pada detailTextLabel
            cell.TextLabel.Text = single_data.Name;
            cell.DetailTextLabel.Text = single_data.Club;

            return cell;
        }
    }
}

Class di atas menampilkan row data class Player yang dikirim dari parameter constructor. Untuk menampilkan data tersebut pada UITableView WelcomeController, masukkan code berikut pada class “WelcomeController”.

        //definisikan variabel datas untuk menyimpan kumpulan data “Player”
        private List<Player> datas;

        public WelcomeController (IntPtr handle) : base (handle)
        {
           this.datas = new List<Player>();
        }

Pada class ViewDidLoad(), masukkan code berikut :

 this.datas.Add(new Player("Christiano Ronaldo", "Real Madrid"));
 this.datas.Add(new Player("Lionel Messi", "Barcelona"));
 this.datas.Add(new Player("Gareth Bale", "Real Madrid"));
 this.datas.Add(new Player("Zlatan Ibrahimovic", "Manchester United"));
 this.datas.Add(new Player("Mesut Ozil", "Arsenal"));

 //konfigurasi source table dengan class SimpleSource
 this.My_Table.Source = new SimpleSource(this.datas);

Code di atas menambahkan data Player ke dalam list, list yang sudah ada akan dilempar kedalam class “SimpleSource”. Tampilan berikut akan muncul setelah anda menjalankan aplikasi :

screen-shot-2016-11-02-at-2-08-02-pm

Custom UITableViewCell

Ada banyak kebutuhan dimana kita diharuskan menampilkan UITableViewCell dengan tampilan yang kompleks dan sering digunakan di berbagai tabel. Untuk mengatasi permasalahan tersebut kita dapat membuat sebuah custom UITableViewCell, berikut caranya.

Buatlah sebuah file “TableViewCell” baru :

screen-shot-2016-11-02-at-9-21-57-pm

Berilah nama “SimpleCustomCell” pada file tersebut. Setelah membuat SimpleCustomCell, maka akan terbentuk dua buah file yaitu “SimpleCustomCell.cs” sebagai class dari TableViewCell dan “SimpleCustomCell.xib” yang merupakan file UI dari TableViewCell. Buka data .xib dan buat UI seperti berikut:

screen-shot-2016-11-02-at-9-29-05-pm

TableViewCell terdiri dari tiga buah UILabel. Silahkan beri identitas nama pada masing-masing label: “label name” bernama “name”, “label club” bernama “club dan “label country” bernama “country”. Setelah memberi identitas masing-masing UILabel, berikan identitas “identifier” untuk UITableViewCell dengan nama “Custom_Cell”. Buka class “SimpleCustomCell.cs” dan masukkan code berikut :

using System;
using Foundation;
using UIKit;

namespace ios_playground
{
   public partial class SimpleCustomCell : UITableViewCell
   {
      protected SimpleCustomCell(IntPtr handle) : base(handle)
      {}

      public SimpleCustomCell() : base()
      {}

      //update row with current data
      public void UpdateCell(Player data)
      {
         Name.Text = data.Name;
         Club.Text = data.Club;
         Country.Text = data.Country;
       }
    }
}

Karena data player bertambah satu buah field yaitu field “Negara” maka tambahkan code berikut pada class Player:

 private string country;

 //lakukan perubahan pada constuctor
 public Player(string name,string club, string country)
 {
   this.name = name;
   this.club = club;
   this.country = country;
 }

 public string Country 
 { 
    get { return this.country; }
 }

Masukkan code berikut pada class “SimpleSource” :

using System;
using System.Collections.Generic;
using ObjCRuntime;
using Foundation;
using UIKit;

namespace ios_playground
{

  public class SimpleSource : UITableViewSource
  {
     List<Player> datas;
     NSString CellIdentifier = new NSString("Custom_Cell");

     public SimpleSource(List<Player> datas)
     {
        this.datas = datas;
     }

     public override nint RowsInSection(UITableView tableview, nint section)
     {
       return datas.Count;
     }

     public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
     {
        Player single_data = this.datas[indexPath.Row];
        SimpleCustomCell cell = tableView.DequeueReusableCell(CellIdentifier) as SimpleCustomCell;

        if (cell == null)
        {
           cell = new SimpleCustomCell();
           var views = NSBundle.MainBundle.LoadNib("SimpleCustomCell", cell, null);
           cell = Runtime.GetNSObject(views.ValueAt(0)) as SimpleCustomCell;
        }

        //update data cell
        cell.UpdateCell(single_data);
        return cell;
      }
   }
}

Berikut tampilan aplikasi setelah dijalankan :

screen-shot-2016-11-02-at-9-51-28-pm

Selamat mencoba.. Happy coding..

[Xamarin iOS] Understanding Navigation

Xamarin iOS Navigation

Salah satu tantangan dalam pengembangan aplikasi mobile adalah ukuran screen yang terbatas sehingga memaksa developer untuk berpikir keras untuk menampilkan konten aplikasinya dalam beberapa screen dengan navigasi yang tepat. Pada bahasan kali ini kita akan mempelajari navigasi pada iOS yang melibatkan lebih dari satu screen.

UINavigationController

Silahkan buka Main.storyboard dan tambahkan UINavigationController pada storyboard anda.

screen-shot-2016-10-31-at-10-29-01-am

UINavigationController adalah controller yang mengelola navigasi dari hirarki konten. Jika anda menambahkan UINavigationController pada storyboard anda, maka akan muncul dua Controller yang terdiri dari UINavigationController dan sebuah Controller yang terhubung ke UINavigationController oleh sebuah garis yang disebut seague. Pada gambar di atas UINavigationController terhubung dengan UITableViewController sedangkan yang akan kita buat UINavigationController akan terhubung dengan UIViewController.

Menghubungkan UINavigationController dengan Controller

Karena kita ingin menghubungkan UINavigationController dengan UIViewController, hapus UITableViewController yang ada pada storyboard. Bagaimana cara menghapusnya? Click pada kotak berwarna putih pada bagian bawah controller, kemudian tekan tombol “delete” pada keyboard. Tambahkan UIViewController baru pada storyboard, beri identitas pada Class dengan nama “WelcomeController”. Setelah diberikan identitas maka project secara otomatis membuat class “WelcomeController”. Hubungkan UINavigationController dengan seague ke WelcomeController dengan menekan “Ctrl”+drag dari UINavagationController ke WelcomeController, berikan Relationship “Root” pada keterangan relation. Pindahkan default controller dari “ViewController” ke “UINavigationController” yang baru kita buat.

screen-shot-2016-10-30-at-7-49-27-am

(Catatan : jika anda mengalami kesulitan membuat seague pada Xamarin Studio, lakukan dengan menggunakan Xcode Interface Builder. Lakukan secondary click pada file storyboard pilih “Open With” kemudian pilih Xcode Interface Builder)

screen-shot-2016-10-30-at-8-14-12-am

Tambahkan sebuah UIButton pada WelcomeController seperti gambar diatas dan berikan UIButton identitas nama “Btn_nav”. UINavigationController dan WelcomeController sudah terhubung, hubungkan juga “ViewController” dari “WelcomeController. Anda tidak bisa menghubungkan controller dari WelcomeController ke ViewController layaknya dari UINavigationController. Anda harus memilih UIButton pada “WelcomeController” terlebih dahulu kemudian lakukan “Ctrl” + drag ke ViewController, pilih Action Seague “Show”.

screen-shot-2016-10-30-at-10-24-18-am

Ketika aplikasi dijalankan akan muncul pada halaman utama seperti berikut : 

screen-shot-2016-10-31-at-8-19-36-am

Jika anda menekan tombol “Go To Dashboard”, akan muncul halaman berikut :

screen-shot-2016-10-31-at-8-21-27-am

Pada contoh diatas perubahan halaman akan terjadi dengan action seague “Show”. Pada Xamarin anda dapat memilih beberapa jenis action seague, untuk merubah jenis seague silahkan click pada garis seague pada storyboard dan pada boks property akan muncul pilhan  seperti berikut :

screen-shot-2016-10-31-at-8-26-21-am

Setiap jenis seagues memiliki perlakuan berbeda-beda ketika menjalankan proses transisi navigasi. Berikut kegunaan masing-masing seagues :

  • Show : menampilkan screen baru pada aplikasi.
  • Show Detail : digunakan pada aplikasi yang menampilkan master detail view yang biasanya aplikasi ditampilkan dalam dua frame view, frame master dan detail. Ketika proses transisi terjadi, maka aplikasi hanya akan merubah tampilan pada frame detail.
  • Present Modally : menampilkan halaman penuh dan menyediakan pilhan untuk mengatur jenis transisi halaman.
  • Present As Popover : pilihan ini akan menampilkan konten dalam bentuk popover.

Silahkan langsung mencoba menggunakan berbagai macam seagues.

Parameter

Penggunaan parameter adalah suatu hal yang sering dilakukan dalam proses transisi halaman. Dengan menggunakan aplikasi yang telah kita buat sebelumnya, kita akan mencoba menerapkan penggunaan parameter. Pada ViewController, tambahkan sebuah label dengan nama “Txt_param”

screen-shot-2016-10-31-at-10-12-19-am

Pada class ViewController masukkan code berikut :

 //definisikan variabel public dengan nama “Param1”
 public string Param1; 

 public override void ViewDidLoad()
 {
    base.ViewDidLoad();
    //tambahkan code ini agar text diambil dari variabel Param1
    this.Txt_param.Text = Param1;
    this.Txt_Name.EditingChanged += (sender, ea) =>{
        this.Label_count.Text = "Count of character : " + ((UITextField)sender).Text.Length;
    }; 
 }

Pada class WelcomeController, tambahkan code berikut :

 public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
 {
    base.PrepareForSegue(segue, sender);
    var viewContoller = segue.DestinationViewController as ViewController;
    if (viewContoller != null)
    {
       viewContoller.Param1 = "I love you";
    }
 }

Code di atas memerintahkan program menjalankan suatu proses ketika proses transisi halaman akan dilakukan. Perintah yang dilakuakn adalah melakukan set nilai “Param1” dengan suatu string yang diinginkan.

screen-shot-2016-10-31-at-10-24-11-am

Gambar diatas adalah tampilan screen setelah kita lakukan modifikasi pada code. Happy coding..

[Xamarin iOS] Hello World

Xamarin… menghadirkan solusi pengembangkan aplikasi native mobile berbasis Windows Phone, Android dan iOS dengan bahasa pemrograman C#. Dari ketiga platform mobile yang dipenuhi oleh Xamarin  Android masih merajai tapi pengembangan aplikasi iOS juga sangat menjanjikan.  Windows Phone? walau pendapat saya pribadi OS WP powerfull dan enak digunakan plus perangkat nokia memang punya kualitas baik, tapi entah kenapa trendnya tidak terlalu baik. Kembali ke pengembangan aplikasi iOS, apa yang dibutuhkan untuk mengembangkan aplikasi iOS pada xamarin?

  1. Anda harus menggunakan PC / laptop Mac (karena xcode dan pasukannya cuma tersedia untuk OS Mac)
  2. Xamarin Studio (dapat diunduh di https://www.xamarin.com/)
  3. Xcode beserta komponen pendukungnya

Jika telah selesai menyiapkan semua kebutuhan, mari kita coba membuat sebuah aplikasi iOS dengan Xamarin.

Buka Xamarin Studio lalu buat aplikasi iOS dan pilih jenis project “Single View App”. Nama aplikasi? terserah anda, saya sendiri memberi nama aplikasinya “ios_playground”. Setelah membuat aplikasi maka akan terlihat sebuah iOS project dengan struktur direktori seperti berikut :

screen-shot-2016-10-27-at-12-00-03-pm

Berikut penjelasan masing-masing direktori dan file dari struktur di atas :

  • Reference : menyimpan kumpulan library/komponen yang akan digunakan.
  • Components : menyimpan components yang digunakan pada aplikasi, anda dapat melihat/mencari kumpulan components yang menarik dari direktori ini caranya secondary click pada direktori “components” kemudian klik “get more..”
  • Packages : menyimpan kumpulan package yang digunakan aplikasi. Secondary click pada direktori ini lalu pilih “Add package” agar anda bisa melihat dan mendapatkan package-package menarik dari nuget.org dan source lainnnya.
  • Assets.xcassets : direktori ini digunakan untuk menyimpan image assets.
  • Resource : digunakan untuk menyimpan berbagai resource yang digunakan aplikasi.
  • AppDelegate : file ini adalah file yang menentukan UI mana yang akan di launching saat pertama kali program dipanggil
  • Entitlements.plist : jika anda menginginkan kebutuhan khusus pada aplikasi, anda dapat melakukan konfigurasinya disini.
  • Info.plist : tempat dimana anda menyimpan informasi identitas aplikasi anda dan beberapa informasi general misal nama aplikasi, target deployment, dll.
  • LaunchScreen.storyboard dan Main.storyboard : Pada pengembangan aplikasi iOS, anda dapat melakukan design UI pada suatu tempat yang disebut storyboard. Jadi file-file yang memiliki extension “.storyboard” artinya file tempat anda meletakkan UI aplikasi anda. Dalam suatu storyboard bisa jadi terdapat beberapa UI yang saling terkait antara satu screen dengan screen yang lainnya.
  • Main.cs : class ini adalah class pertama yang akan dipanggil oleh aplikasi.
  • ViewController.cs : Pada pengembangan aplikasi iOS anda akan mengenal Controller. File ViewController.cs adalah controller default dari yang di generate saat pertama kali kita membuat aplikasi. Anda dapat menambahkan controller lain melalui storyboard.

Sekilas Tentang Storyboard

Dalam pengembangan iOS, storyboard digunakan untuk melakukan perancangan aplikasi dan UI dari aplikasi yang kita buat.

screen-shot-2016-10-28-at-9-55-45-am

Storyboard terdiri dari satu atau lebih controller dimana salah satu controller akan menjadi controller awal yang dijalankan ketika suatu storyboard dipanggil. Setiap controller yang masuk ke dalam storyboard harus diberikan identitas nama class-nya agar xamarin secara otomatis melakukan generate file class-class dari controller tersebut. Dimana class dari controller-nya di generate? pada direktori root aplikasi anda.

Secara default aplikasi yang telah kita buat akan menjalankan UI file Main.storyboard, dimana pengaturan yang menentukan Main.storyboard akan dijalankan di awal? Anda bisa lihat pada file Info.plist

screen-shot-2016-10-27-at-3-15-03-pm

Pada kolom “Main Interface” telah dijelaskan bahwa “Main” storyboard akan dijadikan sebagai interface utama.

Hello Xamarin Dev

Untuk melestarikan tradisi turun temurun, hal pertama yang perlu kita pelajari adalah membuat aplikasi “Hello World”. Kita akan membuat aplikasi seperti berikut :

screen-shot-2016-10-27-at-3-44-35-pm

Aplikasi tersebut adalah aplikasi hello world dan ditambah sebuah inputan yang harus diisi oleh pengguna. Ketika pengguna mengetikkan sesuatu pada textField yang disediakan, maka aplikasi secara otomatis menghitung jumlah karakter dari inputan tersebut dan menampilkan hasilnya pada label berwarna biru.

screen-shot-2016-10-27-at-4-02-45-pm

Okey, pertama-tama bukalah Main.storyboard kemudian tambahkan dua buah UILabel dan  sebuah UITextField pada UIViewController yang ada pada storyboard. Cara menambahkan control tersebut adalah dengan melakukan drag n drop control yang pada box toolbox. Jika selesai silahkan atur tata letak tampilan.

Properties

Kita dapat melakukan beberapa konfigurasi dan pengaturan sederhana pada setiap control seperti UILabel dan UITextField. Silahkan anda coba click salah satu control yang telah ditambahkan pada storyboard :

screen-shot-2016-10-27-at-7-20-14-pm

Control yang sudah terpilih akan terlihat seperti gambar di atas. Anda dapat melakukan pengaturan atau konfigurasi control tersebut pada boks “Properties”

screen-shot-2016-10-27-at-7-16-18-pm

Boks properties akan menyajikan beberapa pengaturan yang dapat dilakukan. Terdapat tiga buah tab pada boks properties :

    1. Widget : berisi konfigurasi general yang ada pada control seprti nama control, font, warna, label, dll.
    2. Layout : konfigurasi yang berkaitan dengan layout dan tata letak suatu control.
    3. Events : berkaitan dengan proses menangkap masukan dan memprosesnya. Sebagai contoh ketika pengguna melakukan click, double click, mengetik sesuatu, dll.

Contoh pengaturan properties :

screen-shot-2016-10-27-at-7-31-07-pm

Berilah sebuah identitas nama pada UITextField yang kita buat dan buat agar memiliki placeholder seperti tampilan di atas. Maka pengaturan property yang harus dilakukan adalah seperti berikut :

screen-shot-2016-10-27-at-7-33-29-pm

Buatlah identitas pada UILabel yang telah ditambahkan kemudian rubah warna hurufnya menjadi berwarna biru :

screen-shot-2016-10-27-at-7-34-57-pm

Pengaturan property-nya adalah seperti berikut :

screen-shot-2016-10-27-at-7-36-49-pm

Mengapa kita harus memberikan identitas nama pada suatu control? Pemberian nama berguna untuk menangkap control yang dimaksud melalui code program. Misal control Label_count semula memiliki label “Count of Character” dengan warna biru, kita menginginkan agar warna dari label “Count of Character” tersebut dapat diubah-ubah melalui code program. Setiap anda menambahkan sebuah nama pada suatu control, maka class dari controller tersebut akan men-generate code pendefinisian control tersebut. Sebelumnya kita telah memberikan identitas nama pada UILabel dan UITextField yang kita miliki, maka pada class controllernya :

screen-shot-2016-10-27-at-7-53-43-pm

Seperti terlihat pada gambar bahwa masing-masing class controller akan terdiri dari class aslinya dan class .designer. Silahkan buka class .designer dari controller tersebut.

screen-shot-2016-10-27-at-7-56-33-pm

Pada code tersebut sudah didefinisikan UILabel dengan nama Label_count dan UITextField dengan nama Txt_Name. Bukannya kita tadi menambahkan dua buah UILabel? Iya, tapi yang satu tidak kita beri identitas nama sehingga tidak di-generate.

Event

Setelah berhasil melakukan pengaturan tampilan, sekarang kita akan menampilkan jumlah karakter yang diketik pada Label_count. Buka class controller lalu masukkan code berikut pada fungsi “ViewDidLoad()”

 base.ViewDidLoad();
 this.Txt_Name.EditingChanged += (sender, ea) =>{
      this.Label_count.Text = "Count of character : " + ((UITextField)sender).Text.Length;
 }; 

Code di atas akan mengeksekusi setiap pengguna mengetik suatu nilai pata Txt_Name dimana setiap pengguna mengetikkan sesuatu maka tampilan pada Label_count akan menampilkan jumlah karakter yang telah dimasukkan.

Sekarang silahkan jalankan aplikasi anda.. berikut tampilannya :

screen-shot-2016-10-27-at-3-44-35-pm

Selesai, selamat mencoba.. happy coding.

[Xamarin – Android] Multi Select With Contextual Action Bar (CAB)

On the listview, sometimes we need an action that can select multi data to process it later. We can do it with CAB that you can see here http://developer.android.com/design/patterns/selection.html. This post will show you how to implement it in xamarin android.

Make new project on xamarin, make an activity with listview in the view. Make a view for mainactivity in main.xml and insert this code :

<?xml version=1.0” encoding=utf8?>
   <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
      android:orientation=vertical
      android:layout_width=fill_parent
      android:layout_height=fill_parent>
      <ListView
         android:id=@+id/mylistview
         android:layout_width=wrap_content
         android:layout_height=wrap_content/>
   </LinearLayout>

In that view we define a listview for show the list data. Before we make CAB, we need to make an application that can show list data in listview so custom your own mainactivity like this :

   public class MainActivity : Activity
  {
      ListView myListView;//define listview
      MyAdapter myAdapter;//definemyadapter(wewillmakethislater)
 
      protected override void OnCreate(Bundle bundle)
      {
        base.OnCreate(bundle);
 
        SetContentView(Resource.Layout.Main);//callmain.xmlforthe view
        myAdapter=new MyAdapter(this);//definemyadapter constructor
        myListView=FindViewById<ListView>(Resource.Id.mylistview);//definelistviewwithlistviewinthe xml
        myListView.Adapter=myAdapter;//setlistviewadapterwith myadapter
      }

You can see that, we have a MyAdapter class that use to make a data list in our listview. Make new class on your application an set the name with MyAdapter and insert this code :

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Android.App;
 using Android.Content;
 using Android.OS;
 using Android.Runtime;
 using Android.Views;
 using Android.Widget;
 
 using Android.Util;
 
 namespace yournamespace
 {
 class MyAdapter : BaseAdapter
 {
     private LayoutInflater mInflater;
     //itwillshowthe data
     private String[] my_data=new String[]{"This","Is","Sample","Multi","Select"}; //itwillusetoCAB(definethedatathathavebeenselected)
     private SparseBooleanArray mSelectedItemsIds;
     private Contextcontext;
 
     public MyAdapter(Contextcontext){
       mInflater=LayoutInflater.From(context);
       mSelectedItemsIds=new SparseBooleanArray();
       this.context=context;
     }
 
     public override int Count{
        get{return my_data.Length;}
     }
 
     public override Java.Lang.Object GetItem(int position){
        return position;
     }
 
     public override long GetItemId(int position){
        return position;
     }
 
     public override View GetView(int position,View convertView,ViewGroup parent){
         ViewHolder holder=null;
         if(convertView==null || holder==null){
           convertView=mInflater.Inflate(Resource.Layout.my_list,null);
            holder=new ViewHolder();
           //setholderlabelwithlabellistidinthe view
            holder.my_label=convertView.FindViewById<TextView>(Resource.Id.labellist);
            convertView.Tag=(holder);
         }else{
             holder=(ViewHolder)convertView.Tag;
         }
 
         holder.my_label.TextSize=30;//set textSize
         holder.my_label.Text=my_data[position];//setdata label
 
         return convertView;
     }
 
     public class ViewHolder: Java.Lang.Object{
        public TextView my_label;
     }
   }
 }

Dont forget to make a view for each of list data in the my_list.xml in your layout directory :

 <?xml version="1.0" encoding="utf-8"?>
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/labellist"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"/>

Try to run your code, you will she application like this :Screenshot_2014-07-03-14-09-18
Okey, now we will custom our application to make a CAB. In MyAdapter class, custom the “GetView” function like this :

   public override View GetView(int position,View convertView,ViewGroup parent){
      ViewHolder holder=null;
      if(convertView==null || holder==null){
          convertView=mInflater.Inflate(Resource.Layout.my_list,null);
          holder=new ViewHolder();
          //setholderlabelwithlabellistidinthe view
          holder.my_label=convertView.FindViewById<TextView>(Resource.Id.labellist);
          convertView.Tag=(holder);
       }else{
           holder=(ViewHolder)convertView.Tag;
       }
 
       holder.my_label.TextSize=30;//set textSize
       holder.my_label.Text=my_data[position];//setdata label
 
       //thiswillcheckifthere'sitemthathavebeen selected
       //ifthere'sanitemthatselect,itwillchangetextcolorwith grey
       if(mSelectedItemsIds.Size()>0){
         holder.my_label.SetTextColor(this.mInflater.Context.Resources.GetColor(Resource.Color.grey));
       }
 
       //checkifcurrentitemhavebeen checked
      //ifyes,changetextcolorwith green
       if(mSelectedItemsIds.Get(position)){
           holder.my_label.SetTextColor(this.mInflater.Context.Resources.GetColor(Resource.Color.green));
        }
 
       return convertView;
    }

Find the dirrerences with last code 😀 . After change that code, add some function in the MyAdapter class like this :

   public void toggleSelection(int position){
       selectView(position, !mSelectedItemsIds.Get(position));
   }
 
    public void removeSelection(){
        mSelectedItemsIds=new SparseBooleanArray();
        NotifyDataSetChanged();
    }
 
    public void selectView(int position,bool value){
       if(value)
          mSelectedItemsIds.Put(position,value);
       else
          mSelectedItemsIds.Delete(position);
 
       NotifyDataSetChanged();
    }
 
    public int getSelectedCount(){
        return mSelectedItemsIds.Size();
    }
 
    public SparseBooleanArray getSelectedIds(){
      returnmSelectedItemsIds;
    }

Make an xml file in “values” directory with name color.xml, and insert this code there :

 <?xmlversion="1.0"encoding="utf-8"?>
   <resources>
     <colorname="green">#00aa08</color>
     <colorname="grey">#666666</color>
   </resources>
 

Go to your MainActivity and custom your onCreate like this :

   protected override void OnCreate(Bundle bundle)
  {
      base.OnCreate(bundle);
 
      SetContentView(Resource.Layout.Main);//callmain.xmlforthe view
      myAdapter=new MyAdapter(this);//definemyadapter constructor
      myListView=FindViewById<ListView>(Resource.Id.mylistview);//definelistviewwithlistviewinthe xml
      myListView.Adapter=myAdapter;//setlistviewadapterwith myadapter
 
      this.myListView.ItemLongClick+=(sender,e)=>{
        //whenyoudolongclickontheitem,itwillrunthis action
        //wewillmakeit later
        OnListItemSelect(e.Position);
      };
 
      this.myListView.ChoiceMode=ChoiceMode.Multiple;
 }

Stay on you mainActivity, add this code there :

       private ActionMode mActionMode;
 
           private void OnListItemSelect(int position){
               myAdapter.toggleSelection(position);
               bool hasCheckedItems=myAdapter.getSelectedCount()>0;
 
               if(hasCheckedItems && mActionMode==null)
                   mActionMode=StartActionMode(new ActionModeCallback(this));
               elseif(!hasCheckedItems&&mActionMode !=null)
                  mActionMode.Finish();
 
               if(mActionMode !=null)
                   mActionMode.Title=(myAdapter.getSelectedCount().ToString()+"selected");
               }
 
      private class ActionModeCallback : Java.Lang.Object,ActionMode.ICallback
     {
         MainActivity parent;
 
          public ActionModeCallback(MainActivity parent)
         {
           this.parent=parent;
         }
 
         public bool OnCreateActionMode(ActionMode mode,IMenu menu){
            //wewillcallcab_menu.xmlforsetthe menu
            //wewillcreatecab_menu.xml later
            mode.MenuInflater.Inflate(Resource.Layout.cab_menu,menu);
            return true;
        }
 
         public bool OnPrepareActionMode(ActionMode mode,IMenu menu){
            returnfalse;
         }
 
         public bool OnActionItemClicked(ActionMode mode,IMenuItem item){
            switch(item.ItemId){
            //ifuserclickmenu print_me
            case Resource.Id.print_me:
            //createanalert dialog
            AlertDialog.Builder builder=new AlertDialog.Builder(parent);
            string msg="Are you sure you want to print items?";
            builder.SetMessage(msg)
              .SetCancelable(false)
              .SetPositiveButton("Yes",(or,er)=>{
 
                 SparseBooleanArray selected=parent.myAdapter.getSelectedIds();
                 List<string> list_item=new List<string>();
                 for(int i=(selected.Size()-1); i>=0; i--){
                    //checkisvaluecheckedby user
                    if(selected.ValueAt(i)){
                       int selectedItem=(int)parent.myAdapter.GetItem(selected.KeyAt(i));
                       list_item.Add(selectedItem.ToString());
                    }
                }
                //print message
                Toast.MakeText(parent,"YouSelect"+parent.myAdapter.getSelectedCount()+"Item:["+string.Join(",",list_item)+"]",ToastLength.Long).Show();
                mode.Finish();

            })
            .SetNegativeButton("No",(or,er)=>{
                ((Dialog)or).Cancel();
            });

            AlertDialogalert=builder.Create();
            alert.Show();
 
            return true;
          default:
             return false;
        }
     }
 
     public void OnDestroyActionMode(ActionMode mode){
       parent.myAdapter.removeSelection();
       parent.mActionMode=null;
     }
 }
 

Last, create a xml file in layout directory with name cab_menu.xml and insert this code :

   <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/print_me"
            android:showAsAction="always"
            android:title="PrintMe"
            android:visible="true"></item>
   </menu>
 

Okey, try to run our apps now. You will see this code :Untitled

Finish… hope it help..

Happy coding… 😀

 

[Xamarin – Android] How To Use Dialog (2)

From post : https://sabitlabscode.wordpress.com/2014/03/30/xamarin-android-how-to-use-dialog-1/ , we will learn how to make a dialog with multi choice item. Multi choice means we can choose more than one item from the list.  It will show as checkbox, not radio button. From previous project, call dialog with this code :

MultiChoiceItem Dialog

  protected override Dialog OnCreateDialog (int id)
 {
    switch (id) {
      case yourId:
      {
            string[] color_options = Resources.GetStringArray (Resource.Array.nameArray);
            
            bool[] check_list; // this use for make default check in list
            check_list = new bool[color_options.Length]; // it set the length of the list same with length options
            check_list [2] = true; // this is how we set the list,
            // you can set where list that you want to set with
            // set the index

          builder = new AlertDialog.Builder (this);
          builder.SetTitle ("Pick a color");
          builder.SetNegativeButton ("Cancel", CancelClicked);
          builder.SetPositiveButton ("OK", OkClicked);// make event ok separate in another event
          
          // it set the dialog with multi choice item, and if one of the item click/select
          // app will set check_list value
          builder.SetMultiChoiceItems (color_options, check_list, (o, e) => {
                check_list [e.Which] = e.IsChecked;
          });
          return builder.Create ();
       }
    }
    return null;
}

After that, we need to make “OkClicked” to run the event when user click “OK” button.

private void OkClicked (object sender, DialogClickEventArgs e)
{
    // insert your code here
    // you can get the value from check_list like "check_list[0]"
    ((Dialog)sender).Dismiss ();
}

Input Dialog

Input dialog is a dialog that you can input with a text not select an item. With input dilaog, get spesific value to process because it not only some options. To implement it, you just need to insert your code like this :

  protected override Dialog OnCreateDialog (int id)
 {
    switch (id) {
      case yourId:
      {
            EditText input = new EditText (this);            
            builder = new AlertDialog.Builder (this);
            builder.SetTitle ("Insert Value: ");
            builder.SetMessage ("Enter your text here");
            builder.SetView (input);
            builder.SetPositiveButton ("Ok", (o, e) => {
                // insert your code here
                ((Dialog)o).Dismiss ();
            });
            builder.SetNegativeButton ("Cancel", Cancelcancel);
            return builder.Create ();
      }
    }
    return null;
}

After insert that code, run your application and you will see input text on your dialog..

Finish… Hope it helps..

Happy coding…

[Xamarin – Android] How To Use Dialog (1)

There’s different style code between pure android and xamarin android while xamarin use a C#’s style and android use Java’s style. One of the different is how to use event and you will use event when use dialog. This is some sample to use dialog in xamarin.

List Dialog
dialog_list

image get from http://developer.android.com/guide/topics/ui/dialogs.html.  First, we must define data in resource value/array.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string-array name="nameArray">
     <item>Red</item>
     <item>Greeb</item>
     <item>Blue</item>
   </string-array>
</resources>

And this is how to make a list dialog :

protected override Dialog OnCreateDialog (int id)
{
   switch (id) {
       case yourId:
       {
           string[] color_options = Resources.GetStringArray (Resource.Array.nameArray);
           builder = new AlertDialog.Builder (this);
           builder.SetTitle ("Pick a color");
           // it will show a cancel button 
           //this is if you want make event separate
           builder.SetNegativeButton ("Cancel", CancelClicked); 
           builder.SetItems (color_options, (o, e) => {
               // do something here
               // to get position that click, use e.Which
            });
            return builder.Create ();
       }
   }
   return null;
}

Make an event for cancelClicked like this :

 private void CancelClicked (object sender, DialogClickEventArgs e)
 {
     ((Dialog)sender).Dismiss ();
 }

After that you will see the dialog that have the list and cancel button…

 

Single Choice Item

If you want to make the list be a single choice item (radio button list), your can do it with change dialog code like this :

 protected override Dialog OnCreateDialog (int id)
 {
    switch (id) {
      case yourId:
      {
          string[] color_options = Resources.GetStringArray (Resource.Array.nameArray);
          builder = new AlertDialog.Builder (this);
          builder.SetTitle ("Pick a color");
          builder.SetNegativeButton ("Cancel", CancelClicked); // this is if you want make event separate
          // color options for set the list, 0 set as default value will selected
          // the different between list is here
          builder.SetSingleChoiceItems (color_options, 0, (o, e) => {
             // do something here
             // to get position that click, use e.Which
          });
          return builder.Create ();
       }
    }
    return null;
}

Its just small different between list dialog..

Finish… we will post about dialog multi choice (you can select more that 1 list ) and input list ( you input it with text) later..

Hope it help.. sorry for my bad English.. happy coding..

[Xamarin – Android] Make CRUD Operation With Sqllite (2)

In the previous post https://sabitlabscode.wordpress.com/2014/01/15/xamarin-android-make-crud-operation-with-sqllite-1/, we have been learn about how to show list data from sqllite. In this post we will learn how to add new data and update data.

UPDATE DATE

From the same application (from previous post), we will make and update data activity. Update activity will show when user click one data in the listview. This is the step :

– create a code that will run when we select a list data. Insert this code on your activity :

         protected override void OnListItemClick (ListView l, View v, int position, long id)
         {
             var selected = (Note)ListAdapter.GetItem (position); // get data that we select
             var intent = new Intent (this, typeof (DetailActivity)); // call new activity "DetailActivity"
             intent.PutExtra ("id", selected.Id);  // sent data to "DetailActivity"
             StartActivityForResult (intent, 0); // start new activity
         }

– create new layout for “DetailActivity”, named it with “detail.axml”. Insert this code :

  <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent">
     <EditText
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:id="@+id/editText1" />
     <TextView
         android:text="Detail"
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:layout_width="match_parent"
         android:layout_height="41.6dp"
         android:id="@+id/textView1" />
     <EditText
         android:layout_width="match_parent"
         android:layout_height="328.0dp"
         android:id="@+id/editText2" />
     <Button
         android:text="Save"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:id="@+id/button1" />
 </LinearLayout>

– create new activity named it with “DetailActivity” and insert this code :

     public class DetailActivity : Activity
     {
         private Note current_data;  // define Note class to set data that we open
         private EditText ttitle;   // define EditText to set title text
         private EditText tbody;    // define EditText to set body text
         protected override async void OnCreate (Bundle bundle)
         {
             base.OnCreate (bundle);

             SetContentView (Resource.Layout.detail);  // set layout with detail.axml that we set before
             ttitle = FindViewById<EditText> (Resource.Id.editText1);   // set ttitle with EditText from editText1 field
             tbody = FindViewById<EditText> (Resource.Id.editText2);  // set tbody with EditText from editText2 field
             var tbutton = FindViewById<Button> (Resource.Id.button1);  // define tbutton to catch button1 from form

             var id = Intent.GetLongExtra ("id", -1);  // define id with get data that sent, if not exist set it with "-1"

             if (id < 0) // if id < 0 then define current data with empty Note
                 current_data = new Note ();
             else  // else set it by id with call function from SqlliteClass
                 current_data = await SqlLiteClass.GetNoteAsync (id);

             tbutton.Click += async (sender, e) => {  // when tbutton click
                 if (ttitle.Text.Length == 0)  // check if ttitle blank or no, if blank dont do execution
                     return;

                 // set current data from form value
                 current_data.Title = ttitle.Text;
                 current_data.Body = tbody.Text;

                 await SqlLiteClass.SaveNoteAsync (current_data); // save data
                 var listactivity=new Intent(this,typeof(MainActivity));  //after save data, call MainActivity
                 StartActivity(listactivity); // start main activity
             };
         }

         protected override void OnResume ()
         {
             base.OnResume ();
             ttitle.SetTextKeepState(current_data.Title);// set ttitle with current_data.Title
             tbody.SetTextKeepState (current_data.Body); // set tbody with current_data.Body
         }
     }

– You can see we call function from SqlLiteClass SaveNoteSync and GetNoteAsync, we will create that function in my SqlLiteClass. Insert this code in your sql lite class :

         public static async Task<Note> GetNoteAsync (long id)
         {
             var sql = string.Format ("SELECT * FROM MYNOTE WHERE Id = {0};", id);  // select a note by id
             using (var conn = GetConnection ()) {  // get connection 
                 await conn.OpenAsync ();

                 using (var cmd = conn.CreateCommand ()) {
                     cmd.CommandText = sql;

                     using (var reader =await cmd.ExecuteReaderAsync ()) {
                         if (await reader.ReadAsync ())
                             return new Note (reader.GetInt32 (0), reader.GetString (1),reader.GetString (2), reader.GetDateTime (3));
                         else
                             return null;
                     }
                 }
             }
         }

         public static async Task SaveNoteAsync (Note note) // save note
         {
             using (var conn = GetConnection ()) {
                 await conn.OpenAsync ();

                 using (var cmd = conn.CreateCommand ()) {

                     if (note.Id < 0) { // if id < 0 do insert, else do update
                         // command to insert data
                         cmd.CommandText = "INSERT INTO MYNOTE (Title, Body, Modified) VALUES (@Title, @Body, @Modified); SELECT last_insert_rowid();";
                         // define parameter
                         cmd.Parameters.AddWithValue ("@Title", note.Title);
                         cmd.Parameters.AddWithValue ("@Body", note.Body);
                         cmd.Parameters.AddWithValue ("@Modified", DateTime.Now);

                         note.Id = (long)await cmd.ExecuteScalarAsync ();
                     } else {
                         // define update command and set parameter
                         cmd.CommandText = "UPDATE MYNOTE SET Title=@Title, Body = @Body, Modified = @Modified WHERE Id = @Id";
                         cmd.Parameters.AddWithValue ("@Id", note.Id);
                         cmd.Parameters.AddWithValue ("@Title", note.Title);
                         cmd.Parameters.AddWithValue ("@Body", note.Body);
                         cmd.Parameters.AddWithValue ("@Modified", DateTime.Now);

                         await cmd.ExecuteNonQueryAsync ();
                     }
                 }
             }
         }

Okey, it finsih for update. Try to click one of the data and it will display like this :
Screenshot_2014-01-16-09-27-28

How about insert data?

Well, you can do insert data with update activity that we have create before. You can see in the code, i give some condition “if(id<0)”. Its use for check the activity that we run an update or insert data. But, even we can do it directly from previous form we create, we need to make a “menu” that link to “DetailActivity”. This is the step :

– create menu for insert data. Insert this code in MainActivity :

  
         public const int MENU_ITEM_DELETE = Menu.First; // will use for delete menu
         public const int MENU_ITEM_INSERT = Menu.First + 1; // set item insert

         public override bool OnCreateOptionsMenu (IMenu menu) // create options/menu in mainActivity
         {
             base.OnCreateOptionsMenu (menu);

             // add new menu insert
             menu.Add (0, MENU_ITEM_INSERT, 0, Resource.String.menu_insert)
                 .SetShortcut ('3', 'a');

             return true;
         }

         // set function will do when we select menu
         public override bool OnOptionsItemSelected (IMenuItem item)
         {
             // check what menu we select
             switch (item.ItemId) {
             // if we select menu for insert
             case MENU_ITEM_INSERT:
                 // call detailActivity
                 var intent = new Intent (this, typeof (DetailActivity));
                 // set id with "-1" value, it means "id < 0"
                 intent.PutExtra ("id", -1);

                 StartActivityForResult (intent, 0); call activity
                 return true;
             }

             return base.OnOptionsItemSelected (item);
         }
 

After do that, run your application and it will display this :

Screenshot_2014-01-16-09-53-07

Screenshot_2014-01-16-09-49-18

You can see “Insert” options on list menu. And when you click it, it will show a form with empty title and body.

Finish.. Hope it help..

Happy coding…

%d bloggers like this: