Fragment en Android

Blog >Lista Soluciones > Fragment I


Hola developers!! vamos hoy a ver un tema sobre un tipo de componentes relativamente nuevos: los Fragments.




Fragment 

Los fragments los podemos explicar diciendo que son trozos de vista que se pueden mostrar o no dependiendo de nuestros intereses, ya sea porque nos interesen distintas dimensiones de pantalla o en la orientación del dispositvo, podemos añadirlos cuando queramos. 

Recientemente los podemos ver en múltiples aplicaciones que hay subidas en Google Play, de hecho el menú que tiene Outlook o Gmail se componen de ellos. En Android usamos varias librerias para su implementación , no obstante antes de describir ninguna, vamos a ver el ciclo de vida de los Fragments :



Un Fragment depende de FragmentActivity y siempre descansa o puede pasar varias veces en FragmentActivity. 

Entonces se puede decir que su ciclo de vida depende del ciclo de vida de FragmentActivity. Para crear un fragment deberemos extender la clase "Fragment" y sobreescribir el método "onCreateView()" en el que devolveremos la vista de dicho fragment.En el sitio oficial de Android podreis curiosear todo lo que querais, os lo dejo aquí.

  • onCreate() : El sistema llama a este método a la hora de crear el fragmento, normalmente iniciaremos los componentes esenciales del fragmento.
  • onCreateView() : Se llamará al método cuando haya que crear la interface de usuario o vista, normalmente se devuelve la View del fragmento.
  • onPause() : Se llama método en el momento que el usuario abandone el fragmento, es un buen momento para guardar información.

public class FragmentOne extends Fragment{
 
    public static final String TAG = "ExampleFragment";
    private FragmentIterationListener mCallback = null;
 
    public interface FragmentIterationListener{
        public void onFragmentIteration(Bundle parameters);
    }
     
    public static ExampleFragment newInstance(Bundle arguments){
        ExampleFragment f = new ExampleFragment();
        if(arguments != null){
            f.setArguments(arguments);
        }
        return f;
    }
     //CONSTRUCTOR
    public FragmentOne(){
     
    }
     
    //El fragment se ha adjuntado al Activity
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }
     
    //El Fragment ha sido creado       
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
     
    //La vista de layout ha sido creada y ya está disponible
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
     
    //La vista ha sido creada y cualquier configuración guardada está cargada
    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
    }
     
     
    //El Fragment ha sido quitado de su Activity y ya no está disponible
    @Override
    public void onDetach() {
        super.onDetach();
    }
     //El Fragment va a cargar su layout, el cual debemos especificar
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);      
  View v =  inflater.inflate(R.layout.examplefragment_view, container, false);  
    }
}


El LayoutInflater lo usaremos para inflar el layout de nuestro fragment. inflate recoge tres parámetros.

En el primero indicamos la id del layout de nuestro fragment,el view padre de nuestro fragment y un booleano que nos servirá para indicar si el inflado del layout debe ser insertado en el ViewGroup (En este caso es false porque se esta insertando directamente el layout en el ViewGroup).

El ViewGroup sera el "padre" donde se insertara el layout de nuestro fragment. El Bundle podremos utilizarlo para recuperar datos de una instancia anterior de nuestro fragment.
Incluyo ahora el método onActivityCreated, que nos vale para declarar las variables que tengan que ver con el Activity en onActivityCreated()

    //El Activity que contiene el Fragment ha terminado su creación
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }


Se deben instanciar los elementos que no sean vistas en el método onCreateView(), como botones, TextViews etc, el layout se carga también en ese método.


Agregar un fragment
 
Se pueden agregar mediante XML o Java :
XML

 <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  
    <fragment
        android:name="com.fragments.fragmentOne"
        android:id="@+id/fragmentOne"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

Es necesario asignarle un identificador único para cada fragment, hay 3 maneras de declarar un fragment : 

  • android:id
  • android:tag
  • Recogida automática mediante la id de la vista 
 Java :

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragmentTwo);
  
    FragmentManager FM = getSupportFragmentManager();
    FragmentTransaction FT = FM.beginTransaction();
  
    Fragment fragment = new FragmentOne();
    FT.add(R.id.fragmentOne_container, fragment);
    FT.commit();
}


Bueno, una vez que ya está mas o menos explicado, vamos con un ejemplo que es como mejor se entiende, en este caso he de recalcar que voy a hacerlo sobre fragments estáticos.

Antes de liarlos con el código, quiero que veais el aspecto que va a tener :




Es un activitymain.xml que tiene 3 fragmentos, asociados cada uno a su correspondiente clase, el java de la clase principal es super sencillo, únicamente hay que indicarle que extienda de FragmentActivity :

Este es el aspecto de nuestro main.xml :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/contenedorPrincipal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context="com.example.fragments.MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

            <fragment
                android:id="@+id/fragmentLista"
                android:name="com.example.fragments.Fragment_Lista"
                android:layout_width="150dp"
                android:layout_height="fill_parent" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

            <fragment
                android:id="@+id/fragmentFoto"
                android:name="com.example.fragments.FragmentFoto"
                android:layout_width="wrap_content"
                android:layout_height="180dp" />

            <fragment
                android:id="@+id/fragmentDetalle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="70"
                android:name="com.example.fragments.FragmentDetalle" />
        </LinearLayout>

</LinearLayout>

</FrameLayout>








public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}


Y ahora vamos con los 3 fragments; cada uno está enfocado a una cosa distinta, uno a un TextView otro a un ImageView y otro a un ListView






public class FragmentDetalle extends Fragment{
 @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
 
        return inflater.inflate(R.layout.fragment_detalle, container, false);
    }
    public void cambiarTexto(String t) {
        TextView f =(TextView)getView().findViewById(R.id.Txt_d);
        f.setText(t);
    }

}






public class FragmentFoto  extends Fragment{
 @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
 
        return inflater.inflate(R.layout.fragment_foto, container, false);
    }
 
    public void cambiarFoto(Drawable foto) {
        ImageView f =(ImageView)getView().findViewById(R.id.fotito);
        f.setImageDrawable(foto);
    }
}


Ahora vamos con el listview, además del xml y de la clase java, usaremos el adapter y el item_list correspondiente, si quereis saber un poquito más sobre cómo van los adapters podeis verlo en este post.



list_item
item

package com.example.fragments;

public class item {
 private String name;
 private String apellidos;
 private String descripcion;
 
 
 
 public item(String name, String apellidos, String descripcion) {
  super();
  this.name = name;
  this.apellidos = apellidos;
  this.descripcion = descripcion;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getApellidos() {
  return apellidos;
 }
 public void setApellidos(String apellidos) {
  this.apellidos = apellidos;
 }
 public String getDescripcion() {
  return descripcion;
 }
 public void setDescripcion(String descripcion) {
  this.descripcion = descripcion;
 }
}


Este es el xml y la clase para el fragment list


public class Fragment_Lista extends Fragment{
 
@Override
 public void onStart() {
  // TODO Auto-generated method stub
  super.onStart();
 }

private ListView listado;
 
 private item[] datos =new item[]{
                new item("Paquito", "Rapper Boy", "Badajoz rules"),
                new item("Alisa", "Cuadros", "Ramstad compañera de trabajo"),
                new item("Felipe´s", "Fiestas", "Ojo tuerto"),
                new item("Lunares", "Romero Redondo", "Mi habibi")};
 
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
 
        return inflater.inflate(R.layout.listado, container, false);
    }
    
    public void onActivityCreated(Bundle state) {
        super.onActivityCreated(state);
 
        listado = (ListView)getView().findViewById(R.id.lista);
        listado.setAdapter(new AdapterList(this,datos));
        
        listado.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView list, View view, int pos, long id) {
               /* if (listener!=null) {
                    listener.onCorreoSeleccionado(
                        (Correo)lstListado.getAdapter().getItem(pos));
                }*/
            }
        });
    }

public class AdapterList extends ArrayAdapter {
        Activity context;
        item[] lista;

        AdapterList(Fragment context,item[] lista) {
            super(context.getActivity(), R.layout.list_item, lista);
            this.context = context.getActivity();
            this.lista=lista;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
         LayoutInflater inflater = context.getLayoutInflater();
         View item = inflater.inflate(R.layout.list_item, null);

         TextView name = (TextView)item.findViewById(R.id.nombre);
         name.setText(lista[position].getName());

         TextView ape = (TextView)item.findViewById(R.id.apellidos);
         ape.setText(lista[position].getApellidos());
         
        return(item);
        }
    }
}




Ya tenemos bastante verdad¿? Vamos ahora a ver la comunicación entre los fragments, estaría chulo que viésemos como al clickar en un item de la lista, cambiase la foto y el texto a mostrar... podremos verlo en el siguiente post.

Podeis descargar el código fuente de thebestandroide con sólo compartir en facebook,twitter,linkedin o suscribirte a nuestro canal RSS más abajo. 



Compartir Compartir Compartir Compartir



0 comentarios:

Publicar un comentario