Calendario en ventana Popup

Tras la implementación que hice del DatePickerDialog no acabe del todo convencido. El problema principal era que únicamente tenia una interacción posible que era aceptar la fecha introducida. Es por ello que he decidido crear una ventana modal e introducir el calendario con los botones que considere necesarios. Para ello utilizaré el componente LayoutInflater
Este componente nos permitirá utilizar un layout creado por nosotros como una ventana modal.
Para ello crearemos dos layouts, el primero será el layout llamante y el segundo el layout que utilizaremos como popup.
El layout main_layout tendrá un botón Calendario que servirá para llamar a la ventana popup y el campo donde se mostrará la fecha. El código es el siguiente:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
        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:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:orientation="vertical">

    <Button
            android:id="@+id/btnCalendarLI"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/calendar" />

    <LinearLayout android:orientation="horizontal"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
        <TextView
                android:id="@+id/lblDateLI"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/currentDate"
                android:textAppearance="?android:attr/textAppearanceLarge" />

        <TextView
                android:id="@+id/dateValueLI"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>
</LinearLayout>

La pantalla se parece mucho a la del ejemplo anterior:
Pantalla_2_01

Ahora creamos un nuevo layout layoutinflater que contendrá un DatePicker , un TimePicker y dos Button uno para aceptar la fecha introducida y otro para borrar la información seleccionada.

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
               android:id="@+id/popup_element"
               android:layout_width="fill_parent"
               android:layout_height="fill_parent"
               android:background="#444444"
               android:orientation="vertical"
               android:paddingLeft="@dimen/activity_horizontal_margin"
               android:paddingRight="@dimen/activity_horizontal_margin"
               android:paddingTop="@dimen/activity_vertical_margin"
               android:paddingBottom="@dimen/activity_vertical_margin">

    <LinearLayout  android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:background="#444444"
                   android:padding="5dp"
                   android:orientation="horizontal" android:layout_gravity="center_horizontal">
        <DatePicker
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/datePickerLI"
                android:layout_gravity="left|center_vertical"
                android:calendarViewShown="false"
                android:spinnersShown="true"/>
        <TimePicker
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/timePickerLI"
                android:layout_gravity="center_horizontal"/>
    </LinearLayout>
    <LinearLayout  android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:background="#444444"
                   android:padding="5dp"
                   android:orientation="horizontal" android:layout_gravity="center_horizontal">
        <Button
                android:id="@+id/aceptarLI"
                android:layout_width="100dp"
                android:layout_height="40dp"
                android:text="@string/calendar_aceptar" />

        <Button
                android:id="@+id/limpiarLI"
                android:layout_width="100dp"
                android:layout_height="40dp"
                android:text="@string/calendar_limpiar" />
    </LinearLayout>
</LinearLayout>

Actualizaremos los ficheros strings.xml, dimens.xml y styles.xml para que los layouts se vean correctamente:
strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">LayoutInflaterTutorial</string>
    <string name="action_settings">Settings</string>

    <string name="calendar_limpiar">Limpiar</string>
    <string name="calendar_aceptar">Aceptar</string>

    <string name="currentDate" >Fecha actual(M-D-AAAA):
    </string>
    <string name="calendar" >Calendario</string>

</resources>

dimens.xml

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>

styles.xml

<resources>
    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>
</resources>

Finalmente creamos la actividad LayoutInflaterActivity que controlará todo el flujo de la aplicación.
En el control del onClick del Button Calendario se abre la ventana popup y se le pasa la información que hay en la ventana para actualizar el calendario con la última fecha seleccionada.

package com.example.layoutinflatertutorial;

import android.os.Bundle;
import android.app.Activity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.TimePicker;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class LayoutInflaterActivity extends Activity {
    private DatePicker calendar;
    private TimePicker time;
    private TextView tvDateValue;

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

        tvDateValue = (TextView) findViewById(R.id.dateValueLI);

        /**
         * Control del evento Click del Button Calendario
         */
        final Button btnOpenPopup = (Button)findViewById(R.id.btnCalendarLI);
        btnOpenPopup.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View arg0) {

                LayoutInflater layoutInflater
                            = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

                View popupView = layoutInflater.inflate(R.layout.layoutinflater, (ViewGroup) arg0.findViewById(R.id.popup_element));

                final PopupWindow popupWindow = new PopupWindow(
                        popupView,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT, true);
                popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);

                calendar = (DatePicker)popupView.findViewById(R.id.datePickerLI);

                time = (TimePicker)popupView.findViewById(R.id.timePickerLI);

                SimpleDateFormat formatoDelTexto = new SimpleDateFormat ("yyyy-MM-dd HH:mm");

                Calendar c = Calendar.getInstance();
                try {
                    Date fecha = formatoDelTexto.parse(String.valueOf(tvDateValue.getText()));
                    c.setTime(fecha);

                } catch (ParseException ex) {

                    ex.printStackTrace();

                }

                time.setCurrentHour(c.get(Calendar.HOUR_OF_DAY));
                time.setCurrentMinute(c.get(Calendar.MINUTE));
                calendar.updateDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));

                time.setIs24HourView(true);

                /**
                 * Control del evento Click del Button Limpiar
                 */

                Button btnLimpiar = (Button)popupView.findViewById(R.id.limpiarLI);
                btnLimpiar.setOnClickListener(new Button.OnClickListener(){
                    @Override
                    public void onClick(View v) {
                        tvDateValue.setText("");
                        popupWindow.dismiss();
                    }
                });

                /**
                 * Control del evento Click del Button Aceptar
                 */

                Button btnAceptar = (Button)popupView.findViewById(R.id.aceptarLI);
                btnAceptar.setOnClickListener(new Button.OnClickListener(){
                    @Override
                    public void onClick(View v) {
                        try {
                            String format = "yyyy-MM-dd HH:mm";
                            SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
                            int hour = time.getCurrentHour();
                            int minute = time.getCurrentMinute();
                            int year = calendar.getYear();
                            int month = calendar.getMonth();
                            int day = calendar.getDayOfMonth();

                            final Calendar c = Calendar.getInstance();
                            c.set(year, month, day, hour, minute);
                            tvDateValue.setText(sdf.format(c.getTime()));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        popupWindow.dismiss();
                    }
                });
            };
        });

    }
}

Al pulsar el botón calendar, se mostrará la ventana modal con el calendario para seleccionar la fecha y y los botones para interactuar con la ventana:

Pantalla_2_02

Al pulsar el botón Aceptar, la fecha seleccionada se enviará a la pantalla inicial:
Pantalla_2_03

Y al pulsar el botón Limpiar, la fecha se borrará de la pantalla:
Pantalla_2_04

Gracias al LayoutInflater tenemos control sobre la ventana popup.

Anuncios
  1. 7/06/14

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: