B4A en español - Juan Antonio Villalpando
(BASIC4Android)
-- Tutorial de B4A --
Volver al índice del tutorial
____________________________
58- Calentario + SQLite = Agenda.
Este calendario está basado en el código público llamado DataPicker que podemos encontrar en los tutoriales de Basci4Android.
La aplicación DatePicker es un calendario, donde al pulsar sobre un día, podemos obtener una variable con su fecha.
Además he añadido un base de datos SQLite, de manera que al pulsar sobre un día, entramos en otra Activity donde podemos escribir una anotación para ese día. La anotación se podrá guardar en una base de datos SQLite.
Se mostrará en un ListView los días que tengan anotaciones.
Para volver al calendario pulsamos el botón "Atrás" del móvil.
- Bajar: agenda.zip
Activity: Main
Pulsamos sobre una fecha. |
Activity: basedatos
Podemos Añadir una anotación a la base de datos, Borrarlo o Modificarlo.
En el ListView se observa los días con anotaciones. |
_____________________________________________________________
- Creación de la base de datos con una herramienta externa.
Como vimos en el tutorial anterior de SQLite, vamos a crear una base de datos con la aplicación: sqlitebrowser_200_b1_win.zip
Vamos a crear una base de datos llamada: basedatos.sql
con una tabla llamada: agenda
con dos campos de textos: fecha y comentario
Más adelante copiaremos esta base de datos en la carpeta Files de nuestro proyecto. |
- También podemos ponerle datos iniciales (pero no es necesario)
|
_________________
- Designer.
Ahora mediante el Designer creamos un Layout para el Activity Main, lo llamaremos "calendar" y contendrá:
|
También crearemos un Layout para el Activity basedatos, llamado "Layout"
Contendrá: dos Label, un EditText, un ListView y tres Botones.
|
_________________
- Código.
El proyecto necesita las librerías AHLocale (facilita la configuración de la fecha y hora local) y SQL.
Consta de dos Activity: Main y basedatos.
Copia y pega este código en un nuevo proyecto.
Activity: Main |
'Activity module
Sub Process_Globals
Dim trans As AHTranslator
Dim locale As AHLocale
'TimeValue holds a random day in the month to be displayed
'On start, this must be set accordingly to which month to be displayed
'In this demo it is set to DateTime.Now which is todays date
'and the calendar shows the current month
Dim TimeValue, FirstDayOfMonth, LastDayOfMonth As Long
Dim DaySelected As Long 'Return value to the calling Activity
Dim Day(), Month() As String
Dim FirstDayOfWeek As Int
DaySelected = 0
'***********************************************************************************************
Dim ScaleFactor As Float 'Scale Factor of the whole calendar
Dim DPTextSize As Int
ScaleFactor = 1.0 '--------------- CHANGE CALENDAR SCALE FACTOR HERE ----------
DPTextSize = 12 ' You can change the base size of all the text here too Default: 14
'***********************************************************************************************
Dim btnDateSize As Int
btnDateSize = 40dip 'Smallest size of the Date button at ScaleFactor = 1.0
btnDateSize = btnDateSize * ScaleFactor 'Scale the button
Dim xa, xdiffa As Int
Dim fecha, txt1 As String
End Sub
Sub Globals
Dim Panel1 As Panel
Dim lblMonthYear As Label 'Month and year at the top of the calendar
Dim lblDay1 As Label 'Day header column 1 (option base 1)
Dim lblDay2 As Label 'Day header column 2
Dim lblDay3 As Label 'Day header column 3
Dim lblDay4 As Label 'Day header column 4
Dim lblDay5 As Label 'Day header column 5
Dim lblDay6 As Label 'Day header column 6
Dim lblDay7 As Label 'Day header column 7
Dim oldDateFormat As String
Dim NextMonth, PrevMonth, Cancel, CurrentMonth, NextYear, PrevYear, btnDefaultDate As Button
Dim lblDesYear As Label
Dim txtYear As EditText
End Sub
Sub Activity_Create(FirstTime As Boolean)
trans.Initialize(File.DirAssets, "datepicker") ' trans.Initialize(File.DirDefaultExternal, "datepicker")
locale.Initialize
DateTime.DateFormat = "dd/MM/yyyy" ' "MM/dd/yyyy"
Dim i As Int
'Set which day is the first day of the week : 1 = Sunday - 2 = Monday
FirstDayOfWeek = locale.FirstDayOfWeek
Day = locale.ShortWeekDays
Month = locale.Months
oldDateFormat=DateTime.DateFormat
' DaySelected = 0
' TimeValue = DateTime.Now
If DaySelected=0 Then
TimeValue = DateTime.Now
Else
TimeValue = DaySelected
End If
Activity.LoadLayout("calendar")
Activity.Title = "Agenda"
Cancel.Text = trans.GetText("Salir")
CurrentMonth.Text = trans.GetText("Hoy")
lblDesYear.Text= trans.GetText("Año")
txtYear.Text=""
txtYear.ForceDoneButton=True
txtYear.InputType=txtYear.INPUT_TYPE_PHONE
Panel1.Width = Panel1.Width * ScaleFactor
Panel1.Height = Panel1.Height * ScaleFactor
Panel1.Left = (100%x - Panel1.Width) / 2
If FirstDayOfWeek = 2 Then
lblDay1.Text = Day(2)
lblDay2.Text = Day(3)
lblDay3.Text = Day(4)
lblDay4.Text = Day(5)
lblDay5.Text = Day(6)
lblDay6.Text = Day(7)
lblDay7.Text = Day(1)
Else
lblDay1.Text = Day(1)
lblDay2.Text = Day(2)
lblDay3.Text = Day(3)
lblDay4.Text = Day(4)
lblDay5.Text = Day(5)
lblDay6.Text = Day(6)
lblDay7.Text = Day(7)
End If
lblDay1.Width = btnDateSize
lblDay2.Width = btnDateSize
lblDay3.Width = btnDateSize
lblDay4.Width = btnDateSize
lblDay5.Width = btnDateSize
lblDay6.Width = btnDateSize
lblDay7.Width = btnDateSize
lblDay1.TextSize = DPTextSize * ScaleFactor
lblDay2.TextSize = DPTextSize * ScaleFactor
lblDay3.TextSize = DPTextSize * ScaleFactor
lblDay4.TextSize = DPTextSize * ScaleFactor
lblDay5.TextSize = DPTextSize * ScaleFactor
lblDay6.TextSize = DPTextSize * ScaleFactor
lblDay7.TextSize = DPTextSize * ScaleFactor
'DoEvents
i = 10dip
lblDay1.Left = i
i = i + btnDateSize
lblDay2.Left = i
i = i + btnDateSize
lblDay3.Left = i
i = i + btnDateSize
lblDay4.Left = i
i = i + btnDateSize
lblDay5.Left = i
i = i + btnDateSize
lblDay6.Left = i
i = i + btnDateSize
lblDay7.Left = i
lblDay1.Top = 75dip 'btnDateSize
lblDay2.Top = 75dip 'btnDateSize
lblDay3.Top = 75dip 'btnDateSize
lblDay4.Top = 75dip 'btnDateSize
lblDay5.Top = 75dip 'btnDateSize
lblDay6.Top = 75dip 'btnDateSize
lblDay7.Top = 75dip 'btnDateSize
Cancel.Height = 50dip * ScaleFactor
Cancel.Width = 90dip * ScaleFactor
Cancel.Top = 380dip
Cancel.TextSize = DPTextSize * ScaleFactor
Cancel.Left = 220dip
CurrentMonth.Height = 50dip * ScaleFactor
CurrentMonth.Width = 90dip * ScaleFactor
CurrentMonth.Top = 380dip
CurrentMonth.TextSize = DPTextSize * ScaleFactor
CurrentMonth.Left = 10dip
btnDefaultDate.Height = 50dip * ScaleFactor
btnDefaultDate.Width = 90dip * ScaleFactor
btnDefaultDate.Top = 380dip
btnDefaultDate.TextSize = DPTextSize * ScaleFactor
btnDefaultDate.Left = 115dip
CreateCalendar
End Sub
Sub Activity_Resume
'Get and show the day selected
If DaySelected > 0 Then
DateTime.DateFormat = "dd/MMM/yyyy" ' "MM/dd/yyyy"
fecha = DateTime.Date(DaySelected)
End If
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub CreateCalendar
Dim i, OffsetX, OffsetY As Int
Dim TempDay, StartDate, EndDate, bDay, Today As Long
Today = DateTime.Now
DateTime.DateFormat="ddMMyyyy"
'Calculate the first day of the month according
FirstDayOfMonth = DateTime.DateParse("01" & DateTime.Date(TimeValue).SubString(2))
'Calculate the last day of the month
TempDay = DateTime.Add(TimeValue,0,1,0)
TempDay = DateTime.DateParse("01" & DateTime.Date(TempDay).SubString(2))
LastDayOfMonth = DateTime.Add(TempDay,0,0,-1)
lblMonthYear.Text = Month(DateTime.GetMonth(TimeValue) - 1) & " " & DateTime.GetYear(TimeValue)
txtYear.Text=DateTime.GetYear(TimeValue)
'Format the Top Section of the Calendar
lblMonthYear.TextSize = DPTextSize * ScaleFactor
lblMonthYear.Left = 60dip * ScaleFactor
lblMonthYear.Width = 180dip * ScaleFactor
lblMonthYear.Height = 40dip * ScaleFactor
NextMonth.Left = 240dip * ScaleFactor
NextMonth.Width = 60dip * ScaleFactor
NextMonth.Height = 40dip * ScaleFactor
NextMonth.TextSize = DPTextSize * ScaleFactor
PrevMonth.Width = 60dip * ScaleFactor
PrevMonth.Height = 40dip * ScaleFactor
PrevMonth.TextSize = DPTextSize * ScaleFactor
lblDesYear.TextSize = DPTextSize * ScaleFactor
lblDesYear.Left = 95dip * ScaleFactor
lblDesYear.Width = 55dip * ScaleFactor
lblDesYear.Height = 40dip * ScaleFactor
txtYear.TextSize = DPTextSize * ScaleFactor
txtYear.Left = 155dip * ScaleFactor
txtYear.Width = 65dip * ScaleFactor
txtYear.Height = 40dip * ScaleFactor
NextYear.Left = 215dip * ScaleFactor
NextYear.Width = 60dip * ScaleFactor
NextYear.Height = 40dip * ScaleFactor
NextYear.TextSize = DPTextSize * ScaleFactor
PrevYear.Left = 25dip * ScaleFactor
PrevYear.Width = 60dip * ScaleFactor
PrevYear.Height = 40dip * ScaleFactor
PrevYear.TextSize = DPTextSize * ScaleFactor
OffsetX = 10dip 'Top Left of date grid
' OffsetY = 70dip * ScaleFactor
OffsetY = 100dip * ScaleFactor
'Calculate the first day to be displayed in the calendar
If FirstDayOfWeek = 2 Then
If (DateTime.GetDayOfWeek(FirstDayOfMonth) - 1) = 0 Then
StartDate = DateTime.Add(FirstDayOfMonth,0,0,-6)
Else
StartDate = DateTime.Add(FirstDayOfMonth,0,0, 0-(DateTime.GetDayOfWeek(FirstDayOfMonth) - 2))
End If
Else
StartDate = DateTime.Add(FirstDayOfMonth,0,0, 0-(DateTime.GetDayOfWeek(FirstDayOfMonth) - 1))
End If
bDay = StartDate
'Calculate the last day to be displayed in the calendar
If FirstDayOfWeek = 2 Then
If (DateTime.GetDayOfWeek(LastDayOfMonth) - 1) = 0 Then
EndDate = LastDayOfMonth
Else
EndDate = DateTime.Add(LastDayOfMonth,0,0, 8 - DateTime.GetDayOfWeek(LastDayOfMonth))
End If
Else
EndDate = DateTime.Add(LastDayOfMonth,0,0, 7 - DateTime.GetDayOfWeek(LastDayOfMonth))
End If
'Place a button for each day to be displayed.
'Days in the previous and next month are grayed out and cannot be selected
'Todays date is shown with a red bold text
'Each buttons tag holds the day of the button
For i = 1 To 42
If bDay <= EndDate Then
Dim bn As Button
bn.Initialize("ButtonPress")
bn.Text = DateTime.GetDayOfMonth(bDay)
If DateTime.GetMonth(bDay) <> DateTime.GetMonth(TimeValue) Then
bn.Enabled = False
bn.Tag = 0
Else
bn.Enabled = True
bn.Tag = bDay
End If
If DaySelected<>0 Then
If DateTime.Date(bDay) = DateTime.Date(DaySelected) Then
bn.TextColor = Colors.Blue
bn.Typeface = Typeface.DEFAULT_BOLD
End If
End If
If DateTime.Date(bDay) = DateTime.Date(Today) Then
bn.TextColor = Colors.Red
bn.Typeface = Typeface.DEFAULT_BOLD
End If
'All buttons are placed on a panel
Panel1.AddView(bn, OffsetX, OffsetY, btnDateSize, btnDateSize)
bn.TextSize = DPTextSize
bn.TextSize = bn.TextSize * ScaleFactor
OffsetX = OffsetX + btnDateSize
If OffsetX > (10dip + (btnDateSize * 6)) Then
OffsetX = 10dip
OffsetY = OffsetY + btnDateSize
End If
bDay = DateTime.Add(bDay,0,0,1)
End If
Next
End Sub
Sub RemovePanelViews
Dim i As Int
Dim v As View
Dim ii As Long
For i=Panel1.NumberOfViews-1 To 0 Step -1
v = Panel1.GetView(i)
Try
ii = v.Tag
If ii >= 0 Then
Panel1.RemoveViewAt(i)
End If
Catch
'
End Try
Next
End Sub
Sub PrevMonth_Click
'Show previous month
RemovePanelViews
TimeValue = DateTime.Add(FirstDayOfMonth,0,-1,0)
CreateCalendar
End Sub
Sub NextMonth_Click
'Show next month
RemovePanelViews
TimeValue = DateTime.Add(FirstDayOfMonth,0,1,0)
CreateCalendar
End Sub
Sub CurrentMonth_Click
'Show current month
RemovePanelViews
TimeValue = DateTime.Now
CreateCalendar
End Sub
Sub btnDefaultDate_Click
'Show default date
RemovePanelViews
If DaySelected=0 Then
TimeValue = DateTime.Now
Else
TimeValue = DaySelected
End If
CreateCalendar
End Sub
Sub PrevYear_Click
'Show previous year
RemovePanelViews
TimeValue = DateTime.Add(FirstDayOfMonth, -1, 0,0)
CreateCalendar
End Sub
Sub NextYear_Click
'Show next year
RemovePanelViews
TimeValue = DateTime.Add(FirstDayOfMonth, 1, 0, 0)
CreateCalendar
End Sub
Sub calcYear
Dim fdom As Long
If txtYear.Text="" Then
xa=0
Else
xa=txtYear.Text
End If
xa=Abs(Ceil(xa))
' anno scritto - anno attuale
xdiffa=xa-DateTime.GetYear(DateTime.Now)
RemovePanelViews
fdom = DateTime.Now
TimeValue = DateTime.Add(fdom, xdiffa, 0, 0)
CreateCalendar
End Sub
Sub txtYear_EnterPressed
calcYear
End Sub
Sub txtYear_FocusChanged (HasFocus As Boolean)
calcYear
End Sub
Sub txtYear_GotFocus
txt1=txtYear.Text
txtYear.SelectionStart=txt1.Length
End Sub
Sub ButtonPress_Click
'Update DaySelected with the selected day and return to the calling activity
Dim b As Button
b = Sender
DaySelected = b.Tag
DateTime.DateFormat=oldDateFormat
fecha = DateTime.Date(DaySelected)
CallSubDelayed(basedatos, "Buscar")
' Activity.Finish
End Sub
Sub Cancel_Click
'Return to calling activity without selecting a day
DateTime.DateFormat=oldDateFormat
DaySelected = 0
Activity.Finish
End Sub
|
Copia y pega este código en un nuevo proyecto.
Activity: basedatos |
Sub Process_Globals
' Juan Antonio Villalpando
' juana1991@yahoo.com
' febrero 2013
' Dim SQL1 As SQL
End Sub
Sub Globals
Dim SQL1 As SQL
Dim registro As Cursor
Dim EditText1 As EditText
Dim Label1, Label2 As Label
Dim fecha, comentario As String
Dim ListView1 As ListView
Dim Button1, Button2, Button3 As Button
Dim existe As Boolean
End Sub
Sub Activity_Create(FirstTime As Boolean)
existe = False
Activity.LoadLayout("Layout")
If File.Exists(File.DirInternal,"basedatos.sql") = False Then
' Ponemos una base inicial de datos en la carpeta Files.
' Luego la copiamos a la SD Card
File.Copy(File.DirAssets,"basedatos.sql",File.DirInternal,"basedatos.sql")
End If
If SQL1.IsInitialized = False Then
SQL1.Initialize(File.DirInternal, "basedatos.sql", False)
End If
' Llama a la Subrutina para cargar la base de datos en el ListView1
Carga_BD_en_ListView
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub Carga_BD_en_ListView
' Limpia el ListView1
ListView1.Clear
' Carga la tabla agenda de la basedatos.sql ordenado por fecha
registro = SQL1.ExecQuery("SELECT * FROM agenda order BY SUBSTR(fecha, 7, 4), SUBSTR(fecha, 4, 2), SUBSTR(fecha, 1, 2)")
For n = 0 To registro.RowCount - 1
registro.Position = n
ListView1.AddSingleLine(registro.GetString("fecha")& " - " & registro.GetString("comentario"))
ListView1.SingleLineLayout.ItemHeight = 40
ListView1.SingleLineLayout.Label.TextSize = 20
ListView1.SingleLineLayout.Label.TextColor = Colors.Black
ListView1.SingleLineLayout.Label.Color = Colors.White
Next
End Sub
Sub Button1_Click
' Añadir al Registro
fecha = Label2.Text
comentario = EditText1.Text
If fecha = "" OR comentario = "" Then
Msgbox("Debes escribir una anotación.","Faltan datos.")
Else
registro = SQL1.ExecQuery("SELECT fecha FROM agenda")
For n = 0 To registro.RowCount - 1
If existe = True Then Return ' Si el día existe, no se podrá añadir otro día igual
Next
SQL1.ExecNonQuery("INSERT INTO agenda VALUES('" & fecha & "','" & comentario & "')")
Label2.Text = ""
EditText1.Text = ""
EditText1.RequestFocus
End If
End Sub
Sub Button2_Click
' Borrar del Registro
fecha = Label2.Text
SQL1.ExecNonQuery("DELETE FROM agenda WHERE fecha = '"& fecha &"'")
Label2.Text = ""
EditText1.Text = ""
EditText1.RequestFocus
End Sub
Sub Button3_Click
' Modificar el Registro
fecha = Label2.Text
comentario = EditText1.Text
If fecha = "" OR comentario = "" Then
Msgbox("Debes escribir una anotación.","Faltan datos.")
Else
SQL1.ExecNonQuery("UPDATE agenda set comentario ='"& comentario &"' WHERE fecha = '"& fecha &"'")
End If
End Sub
Sub Buscar
registro = SQL1.ExecQuery("SELECT * FROM agenda where fecha = '" & Main.fecha & "' ")
For n = 0 To registro.RowCount - 1
registro.Position = n
If Label2.Text= fecha Then existe = True ' Si el día existe, luego no se podrá añadir otro día igual
Label2.text=registro.getString("fecha")
EditText1.text=registro.getString("comentario")
Next
If Label2.Text="" Then Label2.Text = DateTime.Date(Main.DaySelected)
EditText1.RequestFocus
End Sub |
________________
- Comentarios.
- En el Activity Main la siguiente línea es la que llama a la Subrutina Buscar del Activity basedatos:
CallSubDelayed(basedatos, "Buscar")
- Grabamos en la carpeta Files la base de datos: basedatos.sql
- La carpeta Files (DirAssets) es de solo lectura cuando se ejecuta el proyecto, así que lo primero que hace es copiar la base de datos en una carpeta de lectura/escritura (DirInternal).
- Las fechas están en formato dd/mm/aaaa, para que se presenten ordenadas en el ListView utilizo esta línea:
registro = SQL1.ExecQuery("SELECT * FROM agenda order BY SUBSTR(fecha, 7, 4), SUBSTR(fecha, 4, 2), SUBSTR(fecha, 1, 2)")
________________
- Sugerencias.
- Modificar el código para que los días con anotaciones aparezcan de color azul.
- Lanzar la aplicación como servicio y cuando el día actual tenga anotación, salga una notificación.
________________________________
|