Comment font-ils ? #1
Ce tutoriel est le premier d'une série qui va vous montrer comment reproduire certaines interfaces utilisateur (IU) avec les classes et les bibliothèques disponibles avec B4A. Le but principal est de vous montrer comment exploiter au mieux les outils mis à votre disposition. Je n'ai pas la prétention de vous apprendre à concevoir des interfaces utilisateur et je vous épargnerai toute théorie sur le sujet. Je ne suis pas designer professionnel. Il y a probablement des méthodes alternatives à celles présentées ici qui sont tout aussi bien.
J'ai choisi les interfaces à reproduire pour des raisons diverses. Leur point commun est d'être de qualité professionnelle. J'ai volontairement écarté les interfaces des jeux, qui sont un cas à part, et je ne discuterai pas de la qualité, de l'efficacité ou de l'attrait visuel de ces interfaces.
Je précise que je n'ai pas fait de reverse engineering; j'ignore donc la méthode exacte qu'ont employée les auteurs de ces IU, et j'ai reproduit les graphismes à partir des copies d'écran (merci à l'inventeur du copier/coller). Pour des raisons de droits d'auteur, il n'y aura rien à télécharger dans cet article.
Nous allons commencer par Hotmail de Microsoft et, plus précisément, sa liste de messages. C'est une interface sobre et classique:
Nous voyons que l'interface est composée d'une liste qui n'est pas un Listview (un Listview ne nous permet pas d'ajouter une case à cocher et est limité à deux Labels) et qu'au-dessus de cette liste il y a une barre d'onglets. Nous sommes donc face à un TabHost hébergeant un Scrollview. Juste en dessous de la barre d'onglets, il y a un en-tête indiquant quel dossier de la messagerie est actuellement affiché. C'est un Label qui ne fait pas partie du Scrollview. Dans les autres pages, par contre, il y est incorporé. Je montrerai cette variante à la fin. Pour l'instant, j'ouvre le désigner de B4A et je crée mon TabHost. Je crée par dessus un Panel composé d'un Label et d'un Scrollview:
Dans l'éditeur de script, je tape le code plaçant et dimensionnant les objets. Le TabHost occupe tout l'écran. Le Label et le ScrollView se partagent le Panel. Le Label est de hauteur fixe.
B4X:
'All variants script
TabHost1.Height = 100%y
TabHost1.Width = 100%x
'Vues du Panel1
Label1.Top = 0
Label1.Left = 0
Label1.Width = 100%x
Label1.Height = 30dip
ScrollView1.Top = Label1.Height
ScrollView1.Height = 100%y - ScrollView1.Top
ScrollView1.Width = 100%x
Je sauvegarde cet écran sous le nom TabMsg.bal.
Dans la sub Activity_Create, je charge l'écran dans l'activité et j'insère le Panel dans le TabHost:
B4X:
Sub Globals
Dim TabHost1 As TabHost
Dim Panel1 As Panel
Dim Label1 As Label
Dim ScrollView1 As ScrollView
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("TabMsg.bal")
Dim bmpDefault, bmpSelected As Bitmap
bmpDefault = LoadBitmap(File.DirAssets, "envel_orange.png")
bmpSelected = bmpDefault
Panel1.RemoveView
TabHost1.AddTabWithIcon2("Hotmail", bmpDefault, bmpSelected, Panel1)
End Sub
Pour ajouter une icône dans l'onglet, j'utilise la fonction AddTabWithIcon2. Comme l'icône est la même quel que soit l'état de l'onglet, je la charge une seule fois en mémoire (bmpSelected pointe sur bmpDefault).
Je rajoute maintenant les autres onglets. Comme je n'ai pas créé de contenu pour ces onglets, je crée un Panel colorié en blanc pour les remplir: DummyPanel. Dans cet exemple, je ne me soucie pas des icônes.
B4X:
Dim DummyPanel As Panel
DummyPanel.Initialize("")
DummyPanel.Color = Colors.White
TabHost1.AddTab2("Home", DummyPanel)
TabHost1.AddTab2("All emails", DummyPanel)
Dim bmpDefault, bmpSelected As Bitmap
bmpDefault = LoadBitmap(File.DirAssets, "envel_orange.png")
bmpSelected = bmpDefault
Panel1.RemoveView
TabHost1.AddTabWithIcon2("Hotmail", bmpDefault, bmpSelected, Panel1)
TabHost1.AddTab2("School", DummyPanel)
TabHost1.AddTab2("Search", DummyPanel)
B4X:
Label1.Text = " Hotmail - Inbox"
Label1.Typeface = Typeface.DEFAULT_BOLD
Label1.Color = Colors.RGB(124, 133, 148) 'Bluish gray
Je vais utiliser la bibliothèque TabHostExtras pour modifier tout ça. Je la coche dans les Libs de B4A et j'ajoute dans Globals:
B4X:
Dim THExtras As TabHostExtras
B4X:
THExtras.setTabHeight(TabHost1, 62dip)
THExtras.setTabHostPadding(TabHost1, 0, 0, 0, 0)
THExtras.setTabContentViewPadding(TabHost1, 0, 0, 0, 0)
THExtras.setTabTextColorStateList(TabHost1, "tab_widget_text_colors")
B4X:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="#FFFFFF" />
<item android:state_selected="false"
android:color="#606060" />
</selector>
Reste à colorier le fond de l'onglet. Là, les choses se compliquent car TabHostExtras v2.0 n'a pas de fonction adéquate. Je dois donc soit écrire une bibliothèque pour combler le manque, soit faire appel à l'API d'Android avec la bibliothèque Reflection. Je choisis cette deuxième solution. J'ajoute dans Activity_Create:
B4X:
Dim cdEnabled, cdSelected As ColorDrawable
cdEnabled.Initialize(Colors.Black, 0)
cdSelected.Initialize(Colors.Gray, 0)
Dim r As Reflector
r.Target = TabHost1
r.Target = r.RunMethod("getTabWidget")
For t = 0 To TabHost1.TabCount - 1
Dim TabPanel As Panel
TabPanel = r.RunMethod2("getChildAt", t, "java.lang.int")
Dim sd As StateListDrawable
sd.Initialize
sd.AddState(sd.State_Selected, cdSelected)
sd.AddState(sd.State_Pressed, LoadDrawable("highlight_pressed"))
sd.AddState(sd.State_Enabled, cdEnabled)
TabPanel.Background = sd
Next
B4X:
Sub LoadDrawable(Name As String) As Object
Dim r As Reflector
r.Target = r.GetContext
r.Target = r.RunMethod("getResources")
r.Target = r.RunMethod("getSystem")
Dim ID_Drawable As Int
ID_Drawable = r.RunMethod4("getIdentifier", Array As Object(Name, "drawable", "android"), _
Array As String("java.lang.String", "java.lang.String", "java.lang.String"))
r.Target = r.GetContext
r.Target = r.RunMethod("getResources")
Return r.RunMethod2("getDrawable", ID_Drawable, "java.lang.int")
End Sub
B4X:
Dim ivShadow As ImageView
ivShadow.Initialize("")
ivShadow.Background = LoadDrawable("code_lock_bottom")
Panel1.AddView(ivShadow, 0, 0, 100%x, 5dip)
Occupons-nous du ScrollView. Pour créer la liste, je vais utiliser la classe CheckList. Je copie son fichier bas dans le répertoire du projet et je la déclare dans Globals:
B4X:
Dim MsgList As ClsCheckList
B4X:
MsgList.Initialize(Me, ScrollView1, "", "Msg_Click", "", 2dip)
Script du masque:
B4X:
'All variants script
Label1.Width = 100%x - 85dip
Label2.Width = 100%x - 130dip
Label3.Left = 100%x - Label3.Width - 5dip
ImageView1.Left = 100%x - ImageView1.Width – 5dip
B4X:
Sub FillItem(MsgSender As String, MsgSubject As String, MsgDate As String, MsgRead As Boolean, MsgAttached As Boolean) As Panel
Dim pnl As Panel
pnl.Initialize("")
pnl.LoadLayout("item.bal")
If MsgRead Then
pnl.Color = Colors.Black
Else
pnl.Color = Colors.DarkGray 'Unread messages have a gray background
End If
Dim lblSender, lblSubject, lblDate As Label
lblSender = pnl.GetView(1)
lblSender.Text = MsgSender
lblSubject = pnl.GetView(2)
lblSubject.Text = MsgSubject
lblDate = pnl.GetView(3)
lblDate.Text = MsgDate
Dim ivAttached As ImageView
ivAttached = pnl.GetView(4)
ivAttached.Visible = MsgAttached
Return pnl
End Sub
B4X:
Dim pnl As Panel
pnl = FillItem("John Smith", "Hello Fred", "22:26", True, False)
MsgList.AddCustomItem("ID#100", pnl, 60dip)
pnl = FillItem("Lisa Gray", "I'm still loving you", "22:26", False, False)
MsgList.AddCustomItem("ID#101", pnl, 60dip)
pnl = FillItem("Darth Vador", "I'm your father", "09/08/2011", False, False)
MsgList.AddCustomItem("ID#102", pnl, 60dip)
pnl = FillItem("Pamela Rose", "FW: Class ChkList", "09/08/2011", True, True)
MsgList.AddCustomItem("ID#103", pnl, 60dip)
MsgList.ResizePanel
Variante:
Dans la page All Emails, le Label d'en-tête n'est pas fixe. Il fait partie du Scrollview et défile avec lui. Pour faire cela, il faut retirer le Label du Panel dans le designer et donner l'espace libéré au Scrollview. Ensuite, avant de remplir la liste, il faut créer un Panel d'en-tête, mettre le Label dedans et ajouter ce Panel à la liste avec AddCustomItem (hauteur 30dip).
Comment font-ils ? #2 >>>
L'auteur: Frédéric Leneuf-Magaud. Je suis développeur professionnel depuis le début des années 90 et j'ai conçu ou participé à une centaine d'applications. Je travaille actuellement pour l'administration française dans une équipe de supervision de serveurs. Le développement sous Android fait partie de mes loisirs.
Attachments
Last edited: