terça-feira, 17 de julho de 2018

Rumo ao Certificado Android: Widgets

Widgets são mini-aplicativos que ficam na tela principal do Android. Eles geralmente facilitam alguma funcionalidade do aplicativo, tornando-o disponível sem precisar iniciar o aplicativo principal.

Para criar um Widget, temos os seguintes passos:

1. Criar um Widget Provider, uma classe que herdará AppWidgetProvider.

2. Criar um Widget Provider Info, um arquivo xml que contém os metadados do Widget.

3. Criar um arquivo de Layout para Widget.

4. Widgets são Broadcast Receiver, portanto é necessário registrá-los como tal no manifesto.

Android Studio facilita a criação dos Widgets, clicando com o botão direito na pasta "app", você pode ir em "New > Widget > AppWidget". Na tela que abre, configure as características do seu Widget, como nome da classe (Class Name), posicionamento (Placement), se permite redimensionar (Resizable), a largura mínima em células da altura e largura. Clique em "Finish" e o Android Studio criará o Widget Provider, Widget Provider Info, o layout e registrará o mesmo.

Ok, não adianta ter os arquivos criados e não saber usá-los, portanto, vamos verificar como usar:

Widget Provider Info
Este é o arquivo mais simples, contendo as configurações do Widget. Veja o código abaixo:

<appwidget-provider 
    xmlns:android="http//schemas.android.com/apk/res/android"
    android:initialLayout="@layout/layout_widget"
    android:minHeight="48dp"
    android:minWidth="48dp"
    android:previewImage="@drawable/launcher_icon"
    android:resizeModel="horizontal|vertical"
    android:updatePeriodMillis="1800000"
    android:widgetCategory="home_screen" />       

os parâmetros são:

  • initialLayout: layout inicial do Widget;
  • minHeight/minWidth: tamanho mínimo para altura/largura. Uma célula na main screen tem 48dp tanto para altura, quanto para largura;
  • previewImage: ícone do Widget na lista de widgets;
  • resizeModel: permite alterar o tamanho;
  • updatePeriodMillis: tempo em milisegundos para cada atualização. O tempo mínimo é de 30 minutos (1800000 milisegundos);


Widget Provider
É aqui que programaremos o nosso Widget. O WidgetProvider, como dita anteriormente, herda da classe AppWidgetProvider e precisamos sobrescrever alguns métodos. No código abaixo temos um exemplo:

public class NameWidgetProvider extends AppWidgetProvider{

  @Override
  public void onUpdate(Context c, AppWidgetManager awm, int[] appWidgetIds){
     /*
     Este método executa a cada atualização ou quando o widget é iniciado
     */
  }



}

Os principais métodos sobrescrito são:

  • onUpdate: executado a cada atualização ou inicialização de um Widget. Recebe três parâmetros:
    • Context: uma instância do contexto do aplicativo;
    • AppWidgetManager: uma instância do WidgetManager, que contém informações dos Widgets disponíveis e seus status;
    • int[] appWidgetIds: um vetor contendo as IDs das instância do Widget em questão. Como é possível ter mais de uma instância do mesmo Widget, isso permite criar um controle individual para os mesmos;
  • onDelete:

Já para obter um WidgetManager e AppWidgetIds, você pode usar os respectivos métodos

AppWidgetManager wManager = AppWidgetManager.getInstance(context);
int[] widgetsID = wManager.getAppWidgetIds(
    new ComponentName(context, NameWidgetProvider.class)
);

Isso é útil caso precise atualizar o Widget depois que uma Atividade/Serviço/qualquer coisa tenha alterado algo que posso ter modificado o Widget. Outro método útil do AppWidgetManager é o
getAppWidgetOptions, que passando um WidgetID, ele retornará um Bundle com as propriedades do Widget em questão

Bundle config = wManager.getAppWidgetOptions(widgetsID[0]);



RemoteViews
Se a Views são os componentes gráficos das Atividades, os RemoteViews são o mesmo para os Widget. Embora, são semelhante, os RemotesViews não possui todos os componentes das Views, como RecyclerView ou ConstraintLayout, mas possui as mais comuns para poder ser usadas.
Também de forma diferente das Views, nas quais nós devemos buscar o elemento com o método FindViewByID, RemoteViews permite nós acessar diretamente essas views, como setTextViewText.
O método abaixo mostra como pode ser a manipulação de um RemoteView

01. public class NameWidgetProvider extends AppWidgetProvider{

02.   static void letsUpdateInstance(Context c, AppWidgetManager awm, int widgetID){
03.      //Instanciar a RemoteView
04.      RemoteViews views = new RemoteView(c.getPackageName(), R.layout.app_widget_layout);
     
05.      //Setar um texto em um textField
06.      views.setTextViewText(R.id.appWidgetTextField, "algo");
     
07.      //Criando um evento onClick e colocando em um RemoteView
08.      Intent intent = new Intent(c,MainActivity.class);
09.      PendingIntent pendingIntent = PendingIntent.getActivity(c,0, intent, 0);
10.      view.setOnClickPendingIntent(R.id.randomImage, pendingIntent); 

11.      //Esta ação faz com que a modificação do widget fique efetiva
12.      awm.updateAppWidget(widgetID,views);
13.   }

14. }

Aqui temos bastante coisas interessantes: nas linhas 03 e 04 nós obtemos um RemoteViews, na linha 05 e 06 nós atualizamos o texto de um textView. Na linha 07 até 10, nós programamos uma View para quando ela for clicada, ela abra uma atividade (usando um PendingIntent). e na linha 12, nós atualizamos a instancia com a view modificada. Tenha em mente que não precisa necessariamente ser uma Activity a ser chamada, podendo ser um serviço ou um broadcast.

Notas Importantes:
Layout: A partir do API 14, o sistema já cria uma margem para os widgets, entretanto, para versões anteriores é necessário setar a margem manualmente.

Nenhum comentário:

Postar um comentário