IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Introducció

L'objectiu és desenvolupar una aplicació sense model que només tingui entorn GUI (Gràfic User Interface). L'aplicació ha de tenir:

  • Pàgina del login
  • Dashboard
  • Un tema a mida (Customitzat )
  • Action bar
  • Navegació per pestanyes i per gests amb la llibreria de suport i els fragments
  • Una ViewList

Aquesta és l'aplicació web de faltes que haviem de fer al segon trimestre.

Codi font

Pàgina de Login

Aquesta es la clase java del login que utilitzo per fer el login:

package com.iesebre.dam22012.hugolucas.webfaltes;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.*;
import android.widget.Button;
import android.widget.EditText;

//activitat de login
public class Login extends Activity {

	EditText user;
	EditText pass;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setting default screen to login.xml
        setContentView(R.layout.login);
        ActionBar actionBar = getActionBar();
        actionBar.setTitle("Examen");
        
        user = (EditText) findViewById(R.id.Username);
        pass = (EditText) findViewById(R.id.Pass);
        Button btnLogin = (Button) findViewById(R.id.btnLogin);
 
        // Listening to login new account link
        btnLogin.setOnClickListener(new View.OnClickListener() {
 
            public void onClick(View v) {
                // Switching to dashboard
                Intent i = new Intent(Login.this, mainDashboard.class);
                startActivity(i);
            }
        });
    }	
}

Layout del login

Aquest es el layout del login que fa que es mostren els textos, camps de text i botons.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:fillViewport="true">
  <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:background="#ffffff">
         
        <!-- Login Form -->
        <LinearLayout
          
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:padding="10dip">
          <!--  Email Label -->
          <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="#372c24"
                android:text="Usuari"/>
          <EditText android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dip"
                android:layout_marginBottom="20dip"
                android:singleLine="true"
                android:id="@+id/Username"/>
          <!--  Password Label -->
          <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="#372c24"
                android:text="Password"/>
          <EditText android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dip"
                android:singleLine="true"
                android:password="true"
                android:id="@+id/Pass"/>
          <!-- Login button -->
          <Button android:id="@+id/btnLogin"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dip"
                android:text="Login"/>
 
        </LinearLayout>
        <!-- Login Form Ends -->
  </RelativeLayout>
</ScrollView>

Dashboard

Aquesta classe java és on es mostra el dashboard de la meva aplicació just desprès de fer login.

package com.iesebre.dam22012.hugolucas.webfaltes;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.app.FragmentTransaction;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.app.*;

//es el fragment del dashboard que alhora tambe crea les pestanyes
public class mainDashboard extends FragmentActivity {
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_layout);
 
        // Notice that setContentView() is not used, because we use the root
        // android.R.id.content as the container for each fragment

        // setup action bar for tabs
        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle("Examen");
        
        Tab tabs = actionBar.newTab().setText("Inici");
        tabs.setTabListener(new TabbListner<PassarLlista>(
        		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tabs);
        
//        Tab tab = actionBar.newTab().setText("Passar llista");
//                tab.setTabListener(new TabbListner<PassarLlista>(
//                		this, "passarllista", PassarLlista.class));
//        actionBar.addTab(tab);

        Tab tab = actionBar.newTab().setText("Alumnes");
            	tab.setTabListener(new TabbListner<AlumnesGrups>(
                this, "alumnes", AlumnesGrups.class));
        actionBar.addTab(tab);
        
        tab = actionBar.newTab().setText("Tutoria");
                tab.setTabListener(new TabbListner<Tutoria>(
                this, "tutoria", Tutoria.class));
            actionBar.addTab(tab);
            
        tab = actionBar.newTab().setText("Informes");
                tab.setTabListener(new TabbListner<Informes>(
                this, "informes", Informes.class));
                actionBar.addTab(tab);
                
	
	//Aqui cridem al Fragment
	FragmentManager fragmentManager = getFragmentManager();
	FragmentTransaction fragmentTransaction = fragmentManager
			.beginTransaction();

	FragmentV fragmenth = new FragmentV();
	fragmentTransaction.replace(android.R.id.content, fragmenth).commit();
	
}
		
        public boolean onCreateOptionsMenu (Menu menu) {
        	MenuInflater inflater = getMenuInflater();
        	inflater.inflate(R.menu.dashboard_layout, menu);
        	return true;
        }

}

Layout del header

<?xml version="1.0" encoding="utf-8"?>
    
    <!--  Header  Starts-->
        <LinearLayout 
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/header"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:background="@drawable/banner"
            android:paddingTop="5dip"
            android:paddingBottom="5dip">
        </LinearLayout>

Layout del footer

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/FooterBar" 
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true" >
    
    <TextView android:text="IES Ebre"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#606060"
            android:gravity="center"
            android:paddingTop="10dip" />
    
</LinearLayout>

Layout del dashboard

<?xml version="1.0" encoding="utf-8"?>
 
<com.iesebre.dam22012.hugolucas.webfaltes.DashboardLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:background="#f8f9fe" >
    <!--  Passar llista Button -->
    <Button
        android:id="@+id/btn_passar_llista"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_llista"
        android:text="Passar llista" />
 
    <!--  Tutoria Button -->
    <Button
        android:id="@+id/btn_tutoria"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_tuto"
        android:text="Tutoria" />
 
    <!--  Alumnmes-grups Button -->
    <Button
        android:id="@+id/btn_alumnes_grups"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_grups"
        android:text="Alumnes - grups" />
 
    <!--  Informes Button -->
    <Button
        android:id="@+id/btn_informes"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_info"
        android:text="Informes" />
    
    <!--  Informes Button -->
    <Button
        android:id="@+id/btn_invi"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_info"
        android:text=""
        android:visibility="invisible" />
 
    <!--  Tancar Button -->
    <Button
        android:id="@+id/btn_tanca"
        style="@style/DashboardButton"
        android:drawableTop="@drawable/btn_tanca"
        android:text="Tancar" />
 
</com.iesebre.dam22012.hugolucas.webfaltes.DashboardLayout>

Header, cos i footer tots junts:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ScrollView 
	 xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
     >
<RelativeLayout
	android:layout_width="fill_parent"
    android:layout_height="fill_parent"
     >
     
    <!-- Include Header -->
    <include layout="@layout/header"/>
     
<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="350dip"
    android:layout_below="@+id/header" >

    <!--  Include Fragmented dashboard -->
    <include layout="@layout/fragment_layout"/>   
</LinearLayout>
    <!--  Include Footer -->
    <include layout="@layout/footer_layout"/>
</RelativeLayout>
</ScrollView>
</LinearLayout>

Un tema a mida (Customitzat)

Aqui el que he fet és agafar unes quantes icones de la pàgina Icones Android i les he guardat projecte.

Al igual que el header de l'aplicació que és el banner de l'IES Ebre o el footer on posa IES Ebre.

Utilitzar el logo per navegar

A totes les pàgines menys al dashboard habilito el logo de l'aplicació per tornar al dashboard:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pag_passar_llista);
		 ActionBar actionBar = getActionBar();
	        actionBar.setDisplayHomeAsUpEnabled(true);
	        actionBar.setDisplayShowTitleEnabled(true);	

I més a baix ho cridem:

public boolean onOptionsItemSelected(MenuItem item){
   	  switch (item.getItemId()){
   	  case android.R.id.home:
   		  Intent i =new Intent(this,mainDashboard.class);
   		  startActivity(i);
   		  return true;
   		  default:
   			  return super.onOptionsItemSelected(item);
   	  }
	}

Action bar

Layout dels botons que es mostren al action bar

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/opcions"
       	  android:orderInCategory="100"
          android:icon="@drawable/ic_opcions"
          android:title="Opcions"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/ajuda"
          android:orderInCategory="101"
          android:icon="@drawable/ic_help"
          android:title="Ajuda"
          android:showAsAction="ifRoom" />
    <item android:id="@+id/actualitza"
          android:orderInCategory="102"
          android:icon="@drawable/ic_refresh"
          android:title="Actualitza"
          android:showAsAction="ifRoom" />
</menu>

Aqui veiem com hem de crear el menu per a que aparegui l'action bar a la nostra pàgina. El codi es posa al final de tot de la classe.

public boolean onCreateOptionsMenu (Menu menu) {
        	MenuInflater inflater = getMenuInflater();
        	inflater.inflate(R.menu.dashboard_layout, menu);
        	return true;
        }

Navigation tabs

Dintre el mainDashboard creem les pestanyes afegint el codi..

// setup action bar for tabs
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

Al dashboard es criden de la següent manera:

        Tab tabs = actionBar.newTab().setText("Inici");
        tabs.setTabListener(new TabbListner<PassarLlista>(
        		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tabs);
        
        Tab tab = actionBar.newTab().setText("Alumnes");
            	tab.setTabListener(new TabbListner<AlumnesGrups>(
                this, "alumnes", AlumnesGrups.class));
        actionBar.addTab(tab);
        
        tab = actionBar.newTab().setText("Tutoria");
                tab.setTabListener(new TabbListner<Tutoria>(
                this, "tutoria", Tutoria.class));
        actionBar.addTab(tab);
            
        tab = actionBar.newTab().setText("Informes");
                tab.setTabListener(new TabbListner<Informes>(
                this, "informes", Informes.class));
        actionBar.addTab(tab);

Implementant passar llista amb ViewList

Primer creem la classe adaptador que conté l'ArrayAdapter:

Adaptador.java

package com.iesebre.dam22012.hugolucas.webfaltes;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

//esta classe s'encarrega de crear les files de la llista
public class Adaptador extends ArrayAdapter<Alumne> {
	private ArrayList<Alumne> items;
    private int rsrc;
      
    public Adaptador(Context ctx, int rsrcId, int txtId, ArrayList<Alumne> data) {
    	super(ctx, rsrcId, txtId, data);
        this.items = data;
        this.rsrc = rsrcId;
    }
       
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    	View v = convertView;
        if (v == null) {
        	LayoutInflater li = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = li.inflate(rsrc, null);
        }
        Alumne e = items.get(position);
        if (e != null) {
        	((TextView)v.findViewById(R.id.eNom)).setText(e.getNom());
            ((TextView)v.findViewById(R.id.eEmail)).setText(e.getEmailpropi());
            if (e.getPhotoId() != null) {
            	if(e.getPhotoId().equals("1")){
            		((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.hugo);
            	}
            	if(e.getPhotoId().equals("2")){
            		((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.jose);
            	}
            	if(e.getPhotoId().equals("3")){
            		((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.andres);
            	}
            } 
            /*else {
            	((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.nophoto); 
            }*/
        }
        return v;
    }
  
}

A continuació creem la classe java de passar llista on apareixerà la llista amb la gent de la classe:

PagPassarLlista.java

package com.iesebre.dam22012.hugolucas.webfaltes;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

//es la activitat on apareix la llista d'alumnes
public class PagPassarLlista extends Activity {

	ListView llista;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pag_passar_llista);
		 ActionBar actionBar = getActionBar();
	        actionBar.setDisplayHomeAsUpEnabled(true);
	        actionBar.setDisplayShowTitleEnabled(true);	
	        
		ArrayList<Alumne> llistaAlumnes = new ArrayList<Alumne>();
		Alumne alumne = new Alumne();
		
		alumne.setNom("Hugo");
		alumne.setEmailpropi("[email protected]");
		alumne.setPhotoId("1");
		llistaAlumnes.add(alumne);
		
		Alumne alumne1 = new Alumne();
		alumne1.setNom("Jose");
		alumne1.setEmailpropi("[email protected]");
		alumne1.setPhotoId("2");
		llistaAlumnes.add(alumne1);
		
		Alumne alumne2 = new Alumne();
		alumne2.setNom("Andres");
		alumne2.setEmailpropi("[email protected]");
		alumne2.setPhotoId("3");
		llistaAlumnes.add(alumne2);
		
		//listview		
		llista = (ListView) findViewById(R.id.list);
		Adaptador adp = new Adaptador(getApplicationContext(), R.layout.list_fila, R.id.eEmail, llistaAlumnes);
		llista.setAdapter(adp);
		/*ArrayAdapter<Alumne> adpA = new ArrayAdapter<Alumne>(getApplicationContext(), android.R.layout.simple_list_item_1);
		llista.setAdapter(adpA);*/
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_pag_passar_llista, menu);
		return true;
	}
	 
	public boolean onOptionsItemSelected(MenuItem item){
   	  switch (item.getItemId()){
   	  case android.R.id.home:
   		  Intent i =new Intent(this,mainDashboard.class);
   		  startActivity(i);
   		  return true;
   		  default:
   			  return super.onOptionsItemSelected(item);
   	  }
	}
}

Layout per mostrar les dades amb una llista:

activity_pag_passar_llista.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#FFFFFF">
 
    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp"
        android:background="#FFFFFF"
        />
 
</LinearLayout>

Layout per organitzar les dades d'aquesta llista:

list_fila.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FFFFFF"
    android:orientation="horizontal"
    android:paddingBottom="5dp"
    android:paddingTop="5dp" >

    <LinearLayout
        android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:background="#ffffff" >

        <ImageView
            android:id="@+id/ePhoto"
            android:layout_width="48dp"
            android:layout_height="48dp" />
    </LinearLayout>

    <TextView
        android:id="@+id/eNom"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/thumbnail"
        android:layout_toRightOf="@+id/thumbnail"
        android:textSize="22sp" />

    <TextView
        android:id="@+id/eEmail"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/eNom"
        android:layout_toRightOf="@+id/thumbnail"
        android:textSize="16sp" />

</RelativeLayout>

Executable

Aqui està l'executable .apk de l'aplicació:

Hugolucas qrcode.png

I aqui el projecte a gitorious:

Projecte Git

També el projecte en .zip desde el meu Dropbox:

Projecte al Dropbox

Documentació

Tots els canvis realitzats estan explicats a dalt.

IMPORTANT: S'ha de tenir en compte que per a que funcione l'aplicació s'ha d'importar la llibreria externa android-support-v4.jar per a que funcione l'aplicació correctament, sinó ens sortirà un error. En Linux sembla ser que no cal posar-la però amb Windows he tingut problemes i l'he hagut de posar.


Hugolucas importarJAR.png

La primera vegada que entrem al dashboard si fem clic a passar llista es possible que l'aplicació done error, però si tornem a accedir acte seguit ja no ho fa.

Aqui 3 fotos de com és l'aplicació per si sorgeix algun error i no funciona, jo l'he testejat i va tot.

Hugolucas foto1.png
Hugolucas foto2.png
Hugolucas foto3.png

Vegeu també

Android_Development

Enllaços externs

Els enllaços externs utilitzats són:

http://www.androidhive.info/2011/10/android-login-and-registration-screen-design

http://www.lucazanini.eu/2012/android/tab-layout-in-android-with-actionbar-and-fragment/?lang=en

http://www.androidhive.info/2011/12/android-dashboard-design-tutorial

http://arsviator.blogspot.com.es/2010_09_01_archive.html