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)

Especificacions del programa

Informació de la que es disposa

  • Captures de pantalla realitzades a classe de l'aplicació actual de faltes
  • Apunts del professor a aquesta wiki
  • Suport a classe

Objectius:

  • Crear una pàgina inicial després del login de tipus Dashboard. Cal utilitzar al menys un recurs drawable que s'adapti a les diferents mides de pantalla. Vegeu Android resources
  • Linkar la pàgina de Login amb el Dashboard utilitzant intents
  • Crear una interfície utilitzant Action Bars.
  • Fer algun canvi a l'estil de l'Action Bar
  • Cal definir dos fragments:

Opcional

Breu explicació i justificació dels objectius assolits i dels no assolits

Implementació d'una aplicació per passar llista i posar faltes d'assistencia, amb una pantalla de login, un dashboard i una barra de navegació.

Codi Font

Pàgina de Login

package com.iesebre.dam22012.hugolucas.webfaltes;

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;

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);
        
        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

<?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">
        <!--  Header  Starts-->

        <LinearLayout
            android:id="@+id/header"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/banner"
            android:paddingBottom="5dip"
            android:paddingTop="5dip">

        </LinearLayout>
        <!--  Header Ends -->
 
        <!-- Login Form -->
        <LinearLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:padding="10dip"
          android:layout_below="@id/header">
          <!--  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

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.*;


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.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowTitleEnabled(true);	
        
        Tab tabs = actionBar.newTab().setText("Inici");
        tabs.setTabListener(new TabbListener<PassarLlista>(
        		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tabs);
        
        Tab tab = actionBar.newTab().setText("Passar llista");
                tab.setTabListener(new TabbListener<PassarLlista>(
                		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tab);

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

	WindowManager wm = getWindowManager();
	Display d = wm.getDefaultDisplay();
	
	if (d.getRotation() == Surface.ROTATION_90){
		FragmentH fragmentv = new FragmentH();
		fragmentTransaction.replace(android.R.id.content, fragmentv)
				.commit();
	}else {
		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;
        }
         
        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 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 layout 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, body 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>

Utilitzar el logo per navegar

A la pàgina de passar llista 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);
   	  }
	}

Opcions de menú

Arxiu xml de les opcions que mostro al dashboard:

<?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>


Navigation tabs

Classe java per implementar les tabs:

package com.iesebre.dam22012.hugolucas.webfaltes;

import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.*;

public class TabbListener<T extends Fragment> implements TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /** Constructor used each time a new tab is created.
      * @param activity  The host Activity, used to instantiate the fragment
      * @param tag  The identifier tag for the fragment
      * @param clz  The fragment's Class, used to instantiate the fragment
      */
    public TabbListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    /* The following are each of the ActionBar.TabListener callbacks */

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

Al dashboard es criden de la següent manera:

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.*;


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.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowTitleEnabled(true);	
        
        Tab tabs = actionBar.newTab().setText("Inici");
        tabs.setTabListener(new TabbListener<PassarLlista>(
        		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tabs);
        
        Tab tab = actionBar.newTab().setText("Passar llista");
                tab.setTabListener(new TabbListener<PassarLlista>(
                		this, "passarllista", PassarLlista.class));
        actionBar.addTab(tab);

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

	WindowManager wm = getWindowManager();
	Display d = wm.getDefaultDisplay();
	
	if (d.getRotation() == Surface.ROTATION_90){
		FragmentH fragmentv = new FragmentH();
		fragmentTransaction.replace(android.R.id.content, fragmentv)
				.commit();
	}else {
		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;
        }
         
        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);
      	  }
        }

}

Implementant passar llista

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

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;

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:

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;

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]sebre.com");
		alumne2.setPhotoId("3");
		llistaAlumnes.add(alumne2);
		
		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:

<?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">
 
    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp"
        />
 
</LinearLayout>

Layout per organitzar les dades d'aquesta llista:

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

Gitorious

Enllaç al projecte gitorious

[Projecte al Gitorious]

Programa final

Enllaç al APK

Hugolucas apkqpr.png

Captures de pantalla

Vegeu també

Enllaços externs