sábado, 28 de noviembre de 2015

Usando SQLite .NET multiplataforma en Xamarin Android, Xamarin IOS, Windows Phone y Windows Store (Parte 3 Android)

En este tercera publicación el turno es para Xamarin Android al igual que la parte anterior no voy a entrar a fondo a los pasos que ya se hicieron anteriormente (Parte 1 y Parte 2).
El primer paso igual que en ocasiones anteriores es crear un proyecto para Xamarin Android
3CreandoDroid
El paso siguiente es enlazar Core mediante el project linker, como lo explique en la primer publicación.
Utilizando SQLite .NET en el proyecto de Android
Con Xamarin Android no hay que agregar referencias extra para hacer funcionar SQLite, por lo cual podemos pasar a desarrollar la interfaz y funcionalidad con solo enlazar Core que contiene los archivos de SQLite .Net.
La interfaz va a contener los mismos campos que las aplicaciones de WP y WS.
image
<?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">
    <TextView
        android:text="Nombre"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView4" />
    <EditText
        android:inputType="textPersonName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtName" />
    <TextView
        android:text="Edad"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView3" />
    <EditText
        android:inputType="number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtAge" />
    <TextView
        android:text="Correo Electrónico"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView2" />
    <EditText
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtMail" />
    <TextView
        android:text="Teléfono"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView1" />
    <EditText
        android:inputType="phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtPhone" />
    <Button
        android:id="@+id/btnSave"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Guardar" />
    <Button
        android:text="Búsqueda"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnSearch" />
</LinearLayout>
El código de la funcionalidad es muy parecido, lo único que es diferente es lo referente a la interacción con la interfaz de usuario.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using SQL.Core.Core;
using System.IO;

namespace SQL.Droid
{
    [Activity(Label = "SQL.Droid", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button btnSave = FindViewById<Button>(Resource.Id.btnSave);
            btnSave.Click += btnSave_Click;
            
            Button btnSearch = FindViewById<Button>(Resource.Id.btnSearch);
            btnSearch.Click += btnSearch_Click;

            InitializateDB();
        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this,typeof(SearchActivity));
            StartActivity(intent);
        }
       
        void btnSave_Click(object sender, EventArgs e)
        {
            var edtName = FindViewById<EditText>(Resource.Id.edtName);
            var edtAge = FindViewById<EditText>(Resource.Id.edtAge);
            var edtPhone = FindViewById<EditText>(Resource.Id.edtPhone);
            var edtMail = FindViewById<EditText>(Resource.Id.edtMail);

            Contact contact = new Contact(edtName.Text,int.Parse(edtAge.Text), edtPhone.Text, edtMail.Text);
            crud.SaveValue<Contact>(contact);

        }

        CRUDManager crud;
        void InitializateDB()
        {
            var sqliteFilename = "ContactsDb";
            var path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), sqliteFilename); ;

            crud = new CRUDManager(path);

           

        }

    }
}

Para la segunda pantalla la cual muestra los resultados, voy a agregar el código de dos componentes uno es la plantilla xml con la que se mostraran los diferentes campos en la lista de resultados.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:orientation="horizontal"
           android:minWidth="25px"
           android:minHeight="25px"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:id="@+id/Container"
           android:layout_marginTop="15dp"
           
           android:paddingLeft="20dp">
  <LinearLayout
      android:orientation="vertical"
      android:minWidth="25px"
      android:minHeight="25px"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/linearLayout28">
    <TextView
        android:text="Text"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:id="@+id/txvName"
        android:textSize="20sp"
        android:textColor="#005DAA" />
    <TextView
        android:text="Text"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:id="@+id/txvAge" />
    <TextView
      android:text="Text"
      android:layout_height="match_parent"
      android:layout_width="wrap_content"
      android:id="@+id/txvMail" />
    <TextView
        android:text="Text"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:id="@+id/txvPhone" />
  </LinearLayout>

</LinearLayout>

El otro es la clase “Adapter” que va a funcionar como fuente de datos de la lista que mostrara los resultados.
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 SQL.Core.Core;

namespace SQL.Droid
{
    class ContactAdapter : BaseAdapter
    {

        private Activity activity;
        private List<Contact> data;
        private static LayoutInflater inflater = null;


        public ContactAdapter(Activity activity, List<Contact> data)
        {
            this.activity = activity;
            this.data = data;
            inflater = (LayoutInflater)activity.GetSystemService(Context.LayoutInflaterService);

        }

        public Contact GetContact(int position)
        {
            return data[position];
        }


        public override int Count
        {
            get { return data.Count; }
        }

        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)
        {
            View vi = convertView;
            if (convertView == null)
                vi = inflater.Inflate(Resource.Layout.ContactRow, null);

            TextView name = (TextView)vi.FindViewById(Resource.Id.txvName);
            TextView age = (TextView)vi.FindViewById(Resource.Id.txvAge);
            TextView mail = (TextView)vi.FindViewById(Resource.Id.txvMail);
            TextView phone = (TextView)vi.FindViewById(Resource.Id.txvPhone);
            

            name.Text = data[position].Name;
            age.Text = data[position].Age.ToString();
            mail.Text = data[position].Mail;
            phone.Text = data[position].PhoneNumber;
          

            return vi;
        }
    }
}

Finalmente la pantalla creada es la siguiente:
image
<?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:inputType="textPersonName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtName" />
    <Button
        android:text="Buscar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnSearch" />
    <Button
        android:text="Mostrar Todos"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnAllItems" />
    <ListView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="350dp"
        android:id="@+id/lvResults" />
    <Button
        android:text="Eliminar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnDelete" />
</LinearLayout>
Y su respectiva clase C# para la funcionalidad, al igual que con la primer pantalla la mayoría de los cambios son relativos a la interfaz de usuario
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 SQL.Core.Core;
using System.IO;

namespace SQL.Droid
{
    [Activity(Label = "SearchActivity")]
    public class SearchActivity : Activity
    {
        ListView lvResults;
        Contact selected;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.Search);
            Button btnSearch = FindViewById<Button>(Resource.Id.btnSearch);
            btnSearch.Click += btnSearch_Click;

            Button btnAllItems = FindViewById<Button>(Resource.Id.btnAllItems);
            btnAllItems.Click += btnAllItems_Click;

            Button btnDelete = FindViewById<Button>(Resource.Id.btnDelete);
            btnDelete.Click += btnDelete_Click;

            lvResults = FindViewById<ListView>(Resource.Id.lvResults);
            lvResults.ItemClick += lvResults_ItemClick;

            InitializateDB();
        }

        void lvResults_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            selected = ((ContactAdapter)lvResults.Adapter).GetContact(e.Position);
        }

        

        void btnDelete_Click(object sender, EventArgs e)
        {
            if (selected != null)
            {
                crud.DeleteValue<Contact>(selected);
                lvResults.Adapter = new ContactAdapter(this, crud.GetAllItems<Contact>());

            }
        }

        


        void btnAllItems_Click(object sender, EventArgs e)
        {

            lvResults.Adapter = new ContactAdapter(this,crud.GetAllItems<Contact>());
        }

        CRUDManager crud;
        void InitializateDB()
        {
            var sqliteFilename = "ContactsDb";
            var path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), sqliteFilename); ;

            crud = new CRUDManager(path);



        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            var lvResults = FindViewById<ListView>(Resource.Id.lvResults);

            lvResults.Adapter = new ContactAdapter(this,
                new List<Contact>() { crud.GetItem<Contact>(FindViewById<EditText>(Resource.Id.edtName).Text) });
        }
    }
}
Con esto queda concluido el proyecto, al igual que en los casos anteriores dejo el proyecto de Visual Studio http://1drv.ms/1aS1dTL