Master/Detail Flow
Autores
Álvaro Ánderson Gelpúd
Steven Hurtado Rivera
Uso básico de Activity Master-Detail
En este capítulo se va a explicar los pasos necesarios para crear una aplicación en Android Studio haciendo uso de la vista Maestro-Detalle de una manera sencilla
La aplicación consiste en tener una lista de personas que se mostraran en pantalla, al seleccionar una de ellas se mostrara en otra pantalla los datos detallados de esa persona como se muestra en la imagen.
- Crear el proyecto
El primer paso es crear un nuevo proyecto desde Android Studio podemos seleccionar el tipo de la Activity principal que va a iniciar la aplicación. En el asistente se selecciona el tipo Master /Detail Flow.
Luego nos preguntará sobre el nombre que deseamos asignar a los elementos que van a formar parte de la lista (en singular y en plural). Para el ejemplo que se está desarrollando se le ha puesto Persona y Gente: Esto simplemente afecta a los nombres que asignará a los archivos que crearán automáticamente (Activities y Layouts). Y damos clic en finalizar.
Android Studio carga la configuración del proyecto y como se ve en la siguiente imagen se ha creado la estructura de archivos para las clases Java y Layouts:
De manera predeterminada Android Studio crea la carpeta dummy , que contienen la clase DummyContents() que no es necesario dado que es solo un ejemplo de cómo usar este tipo de Activity . Pues en este proyecto esa clase será sustituida por dos clases que harán referencia al objeto Persona y a una lista de personas PersonContents, que se crearan dentro de una carpeta que crearemos y llamaremos person esto se hace para una organización en nuestro proyecto.
- Creación de la Clase Persona
La clase Persona describe el tipo de objetos que vamos a utilizar en la lista y para este ejemplo se definió algunas propiedades básicas como nombre, apellido, teléfono y email. En las últimas líneas de código de esta clase definimos el método toString() el cual se llamará para mostrar los elementos en la lista. Para este ejemplo como se puede ver retornara el nombre de la persona y su apellido.
public class Persona {
private int id;
private String nombre="";
private String apellido="";
private String telefono="";
private String correo="";
public Persona(){}
public Persona(int i,String n,String a, String t,String c){
this.id=i;
this.nombre=n;
this.apellido=a;
this.telefono=t;
this.correo=c;
}
public int getId(){return id;}
public void setId(int i){this.id=i;}
public String getNombre(){return nombre;}
public void setNombre(String n){this.nombre=n;}
public String getApellido(){return apellido;}
public void setApellido(String a){this.apellido=a;}
public String getTelefono(){return telefono;}
public void setTelefono(String t){this.telefono=t;}
public String getCorreo(){return correo;}
public void setCorreo(String c){this.correo=c;}
@Override
public String toString(){
return nombre+" "+apellido;
}
}
- Creación de clase PersonContents
Esta clase está conformada por tres elementos, la primera es una propiedad de tipo ArrayList que se encargara de almacenar la lista de personas que se utilizara en la aplicación. Luego está el método loadPersonList() el cual nos permite instanciar o llenar datos para cada persona , en este caso lo haremos para tres personas a manera de ejemplo. Personas que nos permitirán llenar la lista de personas. Y finalmente tenemos el método getPersonList () el cual nos permitirá retornar la lista de personas creada.
import java.util.ArrayList;
public class PersonaContent {
private static ArrayList<Persona> personList=new ArrayList();
public static ArrayList getPersonList(){
return personList;
}
public static void loadPersonList(){
Persona person;
person=new Persona();
person.setId(1);
person.setNombre("Alvaro");
person.setApellido("Gelpud");
person.setTelefono("123");
person.setCorreo("[email protected]");
personList.add(person);
person=new Persona();
person.setId(1);
person.setNombre("Steven");
person.setApellido("Hurtado");
person.setTelefono("123");
person.setCorreo("[email protected]");
personList.add(person);
person=new Persona();
person.setId(1);
person.setNombre("Juan");
person.setApellido("Bastidas");
person.setTelefono("123");
person.setCorreo("[email protected]");
personList.add(person);
}
}
- Modificación en la clase PersonListFragment.
Esta clase describe el funcionamiento del Fragment que se incluirá dentro de la Activity de la lista y dentro de ella se realizan algunos cambios. En el código que se ha modificado, se ejecuta el método loadPersonList() para cargar los datos de las personas en la lista, sólo en caso de que la lista estuviera vacía. Luego viene, la llamada a setListAdapter() que permite convertir el ArrayList de los datos para que pueda ser utilizada en la lista de la pantalla, mostrando el nombre de cada persona en el elemento android.R.id.text1.como se muestra en el siguiente código.
public class PersonaListActivity extends AppCompatActivity
implements PersonaListFragment.Callbacks {
private boolean mTwoPane;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_persona_app_bar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
if (findViewById(R.id.persona_detail_container) != null) {
mTwoPane = true;
((PersonaListFragment) getSupportFragmentManager()
.findFragmentById(R.id.persona_list))
.setActivateOnItemClick(true);
}
}
@Override
public void onItemSelected(String id) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(PersonaDetailFragment.ARG_ITEM_ID, id);
PersonaDetailFragment fragment = new PersonaDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().replace(R.id.persona_detail_container, fragment).commit();
} else {
Intent detailIntent = new Intent(this, PersonaDetailActivity.class);
detailIntent.putExtra(PersonaDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
}
- Cambios en la clase PersonDetailFragment
Esta es la clase que se encarga de mostrar en pantalla los datos detallados de la persona que previamente haya seleccionado el usuario en la lista.
Se declara en la clase una propiedad person donde se almacenará el objeto relacionado con la posición seleccionada en la lista. Durante el proceso de creación de este Fragment (onCreate), se obtendrá la posición seleccionada (index) de la lista, que viene como String desde la clase PersonListFragment, convirtiéndola a tipo int para utilizarla posteriormente.
Conociendo la posición seleccionada, se obtiene la persona correspondiente a esa posición almacenada dentro del ArrayList.
Luego en el método onCreateView() se asignan los datos de la persona a los elementos del layout del detalle, que serán los que se muestren en la pantalla de la aplicación.
public class PersonaDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
public PersonaDetailFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
int index = Integer.valueOf(getArguments().getString(ARG_ITEM_ID));
person=(Persona) PersonaContent.getPersonList().get(index);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_persona_detail, container, false);
if(person!=null){
((TextView)rootView.findViewById(R.id.textViewNombre)).setText(person.getNombre());
((TextView) rootView.findViewById(R.id.textViewApellido)).setText(person.getApellido());
((TextView) rootView.findViewById(R.id.textViewTelefono)).setText(person.getTelefono());
((TextView) rootView.findViewById(R.id.textViewCorreo)).setText(person.getCorreo());
}
return rootView;
}
}
- Estructura del layout de detalle fragment_person_detail.xml *
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nombre:"
android:id="@+id/textView"
android:textColor="#600c18"
android:textSize="17dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textViewNombre"
android:text="textViewName"
android:textColor="#070707" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Apellidos:"
android:id="@+id/textView3"
android:textColor="#600c18"
android:textSize="17dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textViewSurnames"
android:id="@+id/textViewApellido"
android:textColor="#070707" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Teléfono:"
android:id="@+id/textView5"
android:textColor="#600c18"
android:textSize="17dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textViewMobileNumber"
android:id="@+id/textViewTelefono"
android:textColor="#070707" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email:"
android:id="@+id/textView7"
android:textColor="#600c18"
android:textSize="17dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textViewEmail"
android:id="@+id/textViewCorreo"
android:textColor="#070707" />
</LinearLayout>
</LinearLayout>
</ScrollView>
Android Studio Master/Detail Flow Tutorial - Android 6
Pasos para construir una aplicación Master detail
Se abre un proyecto en Android Studio y colocamos como título del proyecto MasterDetail y damos siguiente.
Luego seleccionamos el dispositivo para el cual se va a desarrollar la aplicación.
Se selecciona la opción MasterDetail/flow.
Colocamos los nombres en plural y singular.
Se crean automáticamente los siguientes archivos:
Nos dirigimos al archivo DummyContent.java y realizaremos algunas modificaciones.
Y se modifica por el siguiente código :
En el mismo archivo DummyContent.java se comenta la siguientes líneas de códigos:
Y digitamos el siguiente código en su lugar:
Se comentan también las siguientes líneas:
Luego nos dirigimos al archivo persona_details.xml observamos el siguiente código:
Se define el contenedor general como un LinearLayout:
Se realiza el diseño general del detail en el archivo Persona_detail.xml.
El siguiente es el Código que va entre el LinearLayout contenedor:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nombre:"/>
<TextView
android:id="@+id/txtnombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="E-mail:"/>
<TextView
android:id="@+id/txtcorreo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Telefomo:"/>
<TextView
android:id="@+id/txttelefono"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Luego nos dirigimos al archivo PersonaDetailFragment.java:
Realizamos la modificación en 2 de las líneas del código. Nos ubicamos en la línea que se indica en la imagen.
Y lo sustituimos por el siguiente código:
Nos ubicamos en la segunda línea de código a modificar como se muestra en la imagen.
Ubicado aquí remplazamos e implementamos el siguiente código:
Nos dirigimos al siguiente archivo PersonaListActivity.java
En este archivo buscamos el método onBindViewHolder y nos ubicamos en donde muestra la imagen.
Y cambiamos con el código que se muestra en la imagen.
Si se ejecuta la aplicación podemos ver el siguiente resultado:
Implementación de Vector Asset
Damos click derecho en app->new->Vector Asset tal como se muestra en la imagen.
Nos abre la siguiente ventana y seleccionamos choose.
Seleccionamos el icono que necesitemos y damos ok.
Le asignamos un nombre al icono ic_nombre y demos siguiente.
Nos muestra la siguiente ventana y damos finalizar.
Este icono se almacena en la carpeta res -> drawable como una imagen de las que se trabaja normalmente pero con formato .xml y ya podemos hacer uso de ella.
Podemos configura el color de icono vectorial abriendo el archivo ic_nombre.xml.
Ahora definimos una etiqueta ImageView en el archivo persona_detail.xml para colocar el icono ic_nombre.
Código final de archivo persona_detail.xml para anexar los iconos.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/persona_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"
tools:context="com.example.anderson.masterdetail.PersonaDetailFragment"
android:orientation="vertical"
>
*************************************************
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:src="@drawable/ic_nombre"
android:layout_margin="5dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nombre:"
android:textSize="15sp"/>
<TextView
android:id="@+id/txtnombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"
android:textSize="15sp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:src="@drawable/ic_correo"
android:layout_margin="5dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="E-mail:"
android:textSize="15sp"
/>
<TextView
android:id="@+id/txtcorreo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"
android:textSize="15sp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:src="@drawable/ic_telefono"
android:layout_margin="5dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Teléfono:"
android:textSize="15sp"
/>
<TextView
android:id="@+id/txttelefono"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"
android:textSize="15sp"
/>
</LinearLayout>
******************************************************
</LinearLayout>
Se hace lo mismo con los demás botones con los nombres ic_correo, ic_telefono, ic_nombre y finalmente este es el resultado
Se realizara rápidamente la configuraciones del color de la aplicación en el archivo color.xml.
Y cambio de icono del detalle en el archivo activity_persona_detail.xml como se muestra en la imagen.
Logrando el siguiente resultado para nuestra aplicación.
Para decidir los colores que queremos aplicar a nuestra interfaz podemos hacer uso de algunos lugares en la web que nos facilitara mucho esto.