Crear widgets personalizables

Featured image

Con esta entrada completaremos un widget básico que creamos anteriormente. Sera un widget personalizable, en el que añadiremos la hora en la que se creó y un texto personalizable.

Comenzaré por la pantalla de “configuración” del widget. Contendrá un espacio para introducir el texto y 2 botones: aceptar y cancelar. La llamo widget_config.xml y tiene el código:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView android:id="@+id/LblMensaje"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Introduce tu mensaje personalizado" />

    <EditText android:id="@+id/TxtMensaje"
        android:layout_height="wrap_content"
        android:layout_width="match_parent" />

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

        <Button android:id="@+id/BtnAceptar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Aceptar" />

        <Button android:id="@+id/BtnCancelar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cancelar" />
    </LinearLayout>
</LinearLayout>

Ahora definiremos su funcionalidad, con una clase asociada a este layout, WidgetConfig.java:

public class WidgetConfig extends Activity{
 private int widgetId = 0;
 private Button btnAceptar;
 private Button btnCancelar;
 private EditText txtMensaje;
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.widget_config);
 //Obtenemos el Intent que ha lanzado esta ventana y recuperamos sus parámetros
 Intent intentOrigen = getIntent();
 Bundle params = intentOrigen.getExtras();
 //Obtenemos el ID del widget que se está configurando
 widgetId = params.getInt(
 AppWidgetManager.EXTRA_APPWIDGET_ID,
 AppWidgetManager.INVALID_APPWIDGET_ID);
 //Establecemos el resultado por defecto (si se pulsa 'Atrás' éste será el resultado)
 setResult(RESULT_CANCELED);
 //Obtenemos la referencia a los controles de la pantalla
 btnAceptar = (Button)findViewById(R.id.BtnAceptar);
 btnCancelar = (Button)findViewById(R.id.BtnCancelar);
 txtMensaje = (EditText)findViewById(R.id.TxtMensaje);
 //Implementación del botón "Cancelar"
 btnCancelar.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View arg0) {
 //Devolvemos como resultado: CANCELAR (RESULT_CANCELED)
 finish();
 }
 });
 //Implementación del botón "Aceptar"
 btnAceptar.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View arg0) {
 //Guardamos el mensaje personalizado en las preferencias
 SharedPreferences prefs =
 getSharedPreferences("WidgetPrefs", Context.MODE_PRIVATE);
 SharedPreferences.Editor editor = prefs.edit();
 editor.putString("msg_" + widgetId, txtMensaje.getText().toString());
 editor.commit();
 //Actualizamos el widget tras la configuración
 AppWidgetManager appWidgetManager =
 AppWidgetManager.getInstance(WidgetConfig.this);
 MiWidget.actualizarWidget(WidgetConfig.this, appWidgetManager, widgetId);
 //Devolvemos como resultado: ACEPTAR (RESULT_OK)
 Intent resultado = new Intent();
 resultado.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
 setResult(RESULT_OK, resultado);
 finish();
 }
 });
 }
 }

Por defecto definiremos CANCELED, por lo que si nos salimos o pulsamos el botón de cancelar, éste finalizará la actividad y con ese valor saldremos sin hacer nada.

Si pulsamos aceptar sí crearemos el texto personalizado y actualizaremos el widget con éste.

Ya está creada la pantalla de configuración y su funcionalidad, quedaría declararla en el manifest. Para ello añadimos las líneas:

<activity android:name=".WidgetConfig">
 <intent-filter>
  <action android:name="android.apwidget.action.APPWIDGET_CONFIGURE"/>
 </intent-filter>
</activity>

Y donde definimos las propiedades de nuestro widget, el fichero widget_provider.xml tendremos que añadir la referencia a nuestra pantalla de configuración. También modificaremos el tamaño de éste, para que se queda 3×2 celdas y un periodo de 30 minutos de actualización. Para ello añadimos (o modificamos) las líneas:

android:minWidth="180dip"
 android:minHeight="110dip"
 android:updatePeriodMillis="3600000"
 android:configure="com.example.jcristobal.myapplication.WidgetConfig"

La referencia a la pantalla de configuración se define con “android:configure”. Tendrá como parámetro el nombre de nuestro paquete seguido del nombre de la clase asociada a la pantalla de configuración.

Una vez arrastremos el widget al escritorio, antes de crearse aparecerá ésta pantalla para introducir nuestro texto:

Ahora modificaremos el layout del widget, para que contenga nuestro texto personalizado y la hora de creación.

Para ello sólo tenemos que sustituir el “TextView” de nuestro antiguo texto estático por el del personalizable mas la otro que contendrá la hora:

<TextView android:id="@+id/LblMensaje"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:textColor="#000000"
android:text="" />
<TextView android:id="@+id/LblHora"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:textColor="#000000"
android:text="" />

Y ahora implementaremos las nuevas funcionalidades. Para ello nos vamos a la clase asociada al widget widget.java y vamos añadiendo el código (funcionalidades comentadas en las líneas del código):

@Override
 public void onUpdate(Context context,
 AppWidgetManager appWidgetManager,
 int[] appWidgetIds) {
 //Iteramos la lista de widgets en ejecución
 for (int i = 0; i < appWidgetIds.length; i++){
 //ID del widget actual
 int widgetId = appWidgetIds[i];
 //Actualizamos el widget actual
 actualizarWidget(context, appWidgetManager, widgetId);
 }
 }
 public static void actualizarWidget(Context context,
 AppWidgetManager appWidgetManager, int widgetId){
 //Recuperamos el mensaje personalizado para el widget actual, con el patrón “msg_IdWidget”
 // para poder distinguir las distintas instancias de los widget del escritorio
 SharedPreferences prefs =
 context.getSharedPreferences("WidgetPrefs", Context.MODE_PRIVATE);
 String mensaje = prefs.getString("msg_" + widgetId, "Hora actual:");
 //Obtenemos la lista de controles del widget actual
 RemoteViews controles =
 new RemoteViews(context.getPackageName(), R.layout.miwidget);
 //Actualizamos el mensaje en el control del widget
 controles.setTextViewText(R.id.LblMensaje, mensaje);
 //Obtenemos la hora actual
 Calendar calendario = new GregorianCalendar();
 String hora = calendario.getTime().toLocaleString();
 //Actualizamos la hora en el control del widget
 controles.setTextViewText(R.id.LblHora, hora);
 //Notificamos al manager de la actualización del widget actual
 appWidgetManager.updateAppWidget(widgetId, controles);
 //si pulsamos el widget se abra automáticamente la actividad principal
 Intent intent2 = new Intent(context, MainActivity.class);
 PendingIntent pendingIntent2 =
 PendingIntent.getActivity(context, widgetId,
 intent2, PendingIntent.FLAG_UPDATE_CURRENT);
 controles.setOnClickPendingIntent(R.id.FrmWidget, pendingIntent2);
 }
 }

Ya tenemos nuestro widget con texto personalizable, a continuación puedes ver imágenes de éste:

Anuncios

Un comentario en “Crear widgets personalizables

  1. En esta versión se actualiza la fecha cada media hora (ésto corresponde a versiones de prueba de la aplicación).
    Para que se mantenga la fecha de creación sólo tienes que borrar o comentar del fichero “widget.java” la línea:

    actualizarWidget(context, appWidgetManager, widgetId);

    Me gusta

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