Programar en Android sin acabar siendo un mono que teclea (V): Creación de Actividad Base y de Card UI

1

Esta vez con un poco más de retraso, pero por fin damos comienzo a este nuevo artículo sobre creación de una App en Android. Para este artículo, voy a cambiar el método de trabajo. Abajo tenéis el código fuente del proyecto, que os recomiendo que  lo bajéis y lo aprovechéis para ir siguiendo las explicaciones. La forma de importarlo a Eclipse, es la misma que como hacíamos con las librerías, con la única diferencia, que ahora no hace falta marcar la casilla de Is Library.
En este artículo haremos lo siguiente:

  • Creación de una actividad que nos sirva de base.
  • Uso de la Card Interface para crear una lista de productos.

 

Este será el aspecto de nuestra App al terminar:

capturamitiendaandroid

Vamos a empezar creando una nueva clase que llamaré ActividadBase y le pondré el siguiente código:

 

package com.example.mitiendaandroid;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;




public abstract class ActividadBase extends SherlockActivity {

	SlidingMenu menu;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(getLayoutResourceId());
		
		Display display = getWindowManager().getDefaultDisplay();
		@SuppressWarnings("deprecation")
		int width = display.getWidth();
		
		
		
		
		menu = new SlidingMenu(this);
		    menu.setMode(SlidingMenu.LEFT);
		    menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
		   
		    menu.setShadowWidth(20);
		    menu.setBehindOffset(30);
		    menu.setFadeDegree(0.25f);
		    menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
		    menu.setBehindWidth(width-60);
		    menu.setMenu(R.layout.menulateral);
		
	    
	    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
  
	}	
	
	 protected abstract int getLayoutResourceId();

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
    }
	@Override
	public boolean onOptionsItemSelected(MenuItem item) 
	{    
	   switch (item.getItemId()) 
	   {        
	      case android.R.id.home:            
	    	  if(!menu.isMenuShowing()){menu.toggle();
	    	  getSupportActionBar().setDisplayHomeAsUpEnabled(false);
	    	  
			  }
			else {menu.toggle();
			  getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
			}
			     
	      default:            
	         return super.onOptionsItemSelected(item);    
	   }

	
	}
	
	
	
	@Override
	public void onBackPressed() {
		if(menu.isMenuShowing()){menu.toggle();
		 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		  }
		else {
			
			finish();
			
			
		}
		
		
		
		
		}
		
	
	
	
	
	
	
	public void Inicio (View view){
		Intent i = new Intent(this, MainActivity.class );
        startActivity(i);
	}
	
	public void Ofertas (View view){
		Intent i = new Intent(this, Ofertas.class );
		finish();
        startActivity(i);
	}
	
	public void Productos (View view){
		Intent i = new Intent(this, Productos.class );
		finish();
        startActivity(i);
	}
	
	public void Contacto (View view){
		Intent i = new Intent(this, Contacto.class );
		finish();
        startActivity(i);
	}

	
	
	
}

 

Este tipo de actividades suelen ser muy útiles. Nos permiten escribir código que necesito en muchas de mis otras actividades, sin tenerlo que repetir en cada una. Vamos a desglosarlo un poco.

Al principio creamos la clase onCreate. Esta clase es la primera que se ejecuta al abrirse una nueva Actividad en Android. Os recomiendo leer algo más sobre el “Ciclo de vida” de las actividades en Android.  Dentro de esta clase hemos añadido tres elementos. El primero es el setContentView, que indica qué layout deberá mostrar esta actividad. Recordad que en Android cada “pantalla” equivale a una Actividad y que a su vez, ésta lleva asociada un Layout, un archivo XML con el diseño. En este caso el setContentView hace referencia a esto: getLayoutResourceId(). Esto nos permite que luego podamos pasarle desde cada una de las actividades, el layout que queremos. Más tarde explicaré esto mejor.  Posteriormente añadimos el menú lateral, como ya hicimos en el artículo anterior.  Ya fuera del onCreate destacamos el onCreateOptionsMenu, que nos permitirá más tarde añadir botones a la ActionBar, el onOptionsItemSelected, que nos permite definir, qué se ejecutará al pulsar el icono de la ActionBar y el onBackPressed() que nos permitirá definir, qué hacer cuando se pulse el botón atrás de nuestro móvil. Analicemos más a fondo estas clases.  Dentro de onOptionsItemSelected podemos ver un If-else. Este código comprueba  si el menú está, o no abierto. En caso afirmativo, cierra el menú,  y activa el pequeño triángulo que podéis ver junto al icono de la ActionBar.  Si nuestro menú está cerrado, lo que hace es abrirlo, y desactivar el triángulo del que hablaba antes.

El onBackPressed tiene un funcionamiento parecido al anterior, con la diferencia de que si el menú no está desplegado, lo que hace es finalizar la actividad.

Por último en esta actividad, hemos creado las clases Inicio, Ofertas,  Productos y Contacto. Recordar que cuando creamos el layout del menú lateral, le añadimos varios atributos onClick, que definían la clase que se ejecutaría al pinchar en ese elemento. Estas clases las hemos definido aquí, y lo que hacen es abrir las diferentes  Actividades,  que deberemos crear de la misma forma que hemos hecho anteriormente. De momento no les añadiremos código.

Ahora vamos a tener que añadir lo siguiente al AndroidManifest.

 

<activity
            android:name="com.example.mitiendaandroid.Productos"
            android:label="Productos" >
         
        </activity>
        
         <activity
            android:name="com.example.mitiendaandroid.Ofertas"
            android:label="Ofertas" >
         
        </activity>
        
         <activity
            android:name="com.example.mitiendaandroid.Contacto"
            android:label="Contacto" >
         
        </activity>

 

Cada una de las Actividades que correspondan a lo que venimos llamando una “pantalla de la aplicación” deberán siempre ser definidas en el Android Manifest.

Lo siguiente que vamos a hacer es añadir una lista de productos disponibles. Para comenzar añadiremos este código al archivo styles:
 

</style>

      <style name="nowCardStyle" parent="android:Widget.TextView">
        <item name="android:background">@drawable/search_bg_shadow</item>
      
        <item name="android:minHeight">200dp</item>
        <item name="android:minWidth">200dp</item>
        <item name="android:textColor">#707070</item>
    </style>

 
Después, en la carpeta res, crearemos la carpeta anim. Dentro de ella crearemos los archivos slide_up_left y slide_up_right. Que tendrán respectivamente el siguiente código:
 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="1600"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

    <alpha
        android:duration="1600"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

    <rotate
        android:duration="1600"
        android:fromDegrees="25"
        android:pivotX="0"
        android:pivotY="0"
        android:toDegrees="0" />

</set>

 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="1600"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

    <alpha
        android:duration="1600"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

    <rotate
        android:duration="1600"
        android:fromDegrees="-25"
        android:pivotX="100%"
        android:pivotY="0"
        android:toDegrees="0" />

</set>

 

Estos archivos definen la animación de nuestro layout.

Crearemos también una nueva clase llamada NowLayout con este código:
 

package com.example.mitiendaandroid;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;

public class NowLayout extends LinearLayout implements OnGlobalLayoutListener {

	public NowLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		initLayoutObserver();

	}

	public NowLayout(Context context) {
		super(context);
		initLayoutObserver();
	}

	private void initLayoutObserver() {
		setOrientation(LinearLayout.VERTICAL);
		getViewTreeObserver().addOnGlobalLayoutListener(this);
	}

	@Override
	public void onGlobalLayout() {
		getViewTreeObserver().removeGlobalOnLayoutListener(this);

		final int heightPx = getContext().getResources().getDisplayMetrics().heightPixels;

		boolean inversed = false;
		final int childCount = getChildCount();

		for (int i = 0; i < childCount; i++) {
			View child = getChildAt(i);

			int[] location = new int[2];

			child.getLocationOnScreen(location);

			if (location[1] > heightPx) {
				break;
			}

			if (!inversed) {
				child.startAnimation(AnimationUtils.loadAnimation(getContext(),
						R.anim.slide_up_left));
			} else {
				child.startAnimation(AnimationUtils.loadAnimation(getContext(),
						R.anim.slide_up_right));
			}

			inversed = !inversed;
		}

	}

}

 

De esta no explicaré nada porque se complica bastante, y no es necesario modificarla para modificar nuestros prodcutos. Posteriormente añadiremos el archivo productos.xml, en la carpeta layout, con este código:
 

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true" >

    <com.example.mitiendaandroid.NowLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#e3e3e3"
        android:orientation="vertical" >

        <RelativeLayout
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/TextView08"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/ImageView03"
                android:layout_marginLeft="28dp"
                android:layout_marginTop="20dp"
                android:layout_toRightOf="@+id/ImageView03"
                android:text="Photoshop"
                android:textColor="#240B3B"
                android:textSize="20sp"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/ImageView03"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="36dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/photoshop" />

            <TextView
                android:id="@+id/TextView07"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/ImageView03"
                android:layout_below="@+id/ImageView03"
                android:text="99€"
                android:textColor="#1B0A2A"
                android:textSize="30sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/TextView09"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/TextView08"
                android:layout_below="@+id/TextView08"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="10dp"
                android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh."
                android:textColor="#585858"
                android:textSize="13sp" />
        </RelativeLayout>

        <RelativeLayout
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/TextView05"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/ImageView02"
                android:layout_marginLeft="28dp"
                android:layout_marginTop="20dp"
                android:layout_toRightOf="@+id/ImageView02"
                android:text="Sony VAIO"
                android:textColor="#240B3B"
                android:textSize="20sp"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/ImageView02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="36dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/vaio" />

            <TextView
                android:id="@+id/TextView04"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/ImageView02"
                android:layout_below="@+id/ImageView02"
                android:text="600€"
                android:textColor="#1B0A2A"
                android:textSize="30sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/TextView06"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/TextView05"
                android:layout_below="@+id/TextView05"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="10dp"
                android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh."
                android:textColor="#585858"
                android:textSize="13sp" />
        </RelativeLayout>

        <RelativeLayout
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/TextView02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/ImageView01"
                android:layout_marginLeft="28dp"
                android:layout_marginTop="20dp"
                android:layout_toRightOf="@+id/ImageView01"
                android:text="Impresora HP"
                android:textColor="#240B3B"
                android:textSize="20sp"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/ImageView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="36dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/impresora" />

            <TextView
                android:id="@+id/TextView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/ImageView01"
                android:layout_below="@+id/ImageView01"
                android:text="300€"
                android:textColor="#1B0A2A"
                android:textSize="30sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/TextView03"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/TextView02"
                android:layout_below="@+id/TextView02"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="10dp"
                android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh."
                android:textColor="#585858"
                android:textSize="13sp" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            style="@style/nowCardStyle">

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/imageView1"
                android:layout_marginLeft="28dp"
                android:layout_marginTop="20dp"
                android:layout_toRightOf="@+id/imageView1"
                android:text="iPhone 5"
                android:textColor="#240B3B"
                android:textSize="20sp"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="36dp"
                android:layout_marginTop="8dp"
                android:src="@drawable/iphone" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/imageView1"
                android:layout_below="@+id/imageView1"
                android:text="600€"
                android:textSize="30sp"
                android:textStyle="bold"
                android:textColor="#1B0A2A"/>

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView1"
                android:layout_below="@+id/textView1"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="20dp"
                android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh." 
                android:textSize="13sp"
                android:textColor="#585858"
                />
				
        </RelativeLayout></com.example.mitiendaandroid.NowLayout>

    

</ScrollView>

 

Cada producto va en un Relative Layout, que contiene una imagen, el título, precio y descripción. Por cierto,  si veis la nueva app de Youtube se basa en este tipo de diseño, cada vez más utilizado por Google.


Por último solo nos queda añadir este código a la clase Productos:
 

package com.example.mitiendaandroid;

import android.os.Bundle;

public class Productos extends ActividadBase {
	
	
	 @Override
	    protected int getLayoutResourceId() {
	        return R.layout.productos;
	    }
	 
	 

}

 
Vemos que extiende de BaseActivity. Por lo tanto, hace uso de todo lo que hemos comentado anteriormente sobre ella. Además le decimos que en nuestro caso, el layout que vamos a usar es el llamado “productos“. Solo nos faltaría ahora añadir este código a MainActivity:
 

package com.example.mitiendaandroid;

import android.os.Bundle;
 
import android.view.Display;
import android.view.View;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;





public  class MainActivity extends ActividadBase {

	SlidingMenu menu;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);


	    
	    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
  
	}
	 @Override
	    protected int getLayoutResourceId() {
	        return R.layout.activity_main;
	 }
}

 
Por último, decir que para la interfaz de los productos me he inspirado en este artículo:

 

Google Now Cards Layout

 

Y como siempre recordad, que tenéis varias vías de comunicación  (Twitter, Comentarios, web) conmigo para preguntarme todo lo que queráis. Además, en mi web: unmonoqueteclea.es tenéis un sericio de chat con el que contactar conmigo. Aquí tenéis el código fuente del proyecto. Pinchad en la imagen para ir al repositorio

 

github_icon-390x250

Share.

About Author

Mi nombre es Pablo González Carrizo, aunque mi seudónimo en este mundo sea Un mono que teclea. Mis estudios de Imagen y Sonido en Telecomunicaciones me permiten estar informado de todas las novedades en tecnología, que intento siempre compartir.

1 comentario

  1. a mi no me funciona bien el proyecto!! le pongo las librerías de los pasos anteriores y me las pilla, pero luego en muchos archivos tengo problemas al acceder a los elementos del Layout del tipo: R.menu

    Tampoco me reconoce el tema que tomamos de la librería ActionBar, sin embargo cuando lo hice yo no tuve problemas. Probaré a ir creando los archivos paso a paso…Tiene q ser cualquier tontería al importar, pero estoy un poco pez en esto

Leave A Reply

Uso de cookies

Este sitio web utiliza cookies para una mejor experiencia de usuario. Si continúas navegando estás dando tu consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

CERRAR