Creați un widget personalizat pentru ceas Implementarea configurării utilizatorilor

Dezvoltarea widget-urilor pentru platforma Android implică un set de sarcini ușor diferit de dezvoltarea standard a aplicațiilor. În această serie de tutoriale, vom lucra prin procesul de dezvoltare a unui widget personalizabil de ceas analogic. Ceasul va fi bazat pe clasa Android AnalogClock și personalizat cu grafica proprie.

Până acum, în această serie, am proiectat și implementat widgetul în XML și Java și avem un widget ceas de funcționare pe care utilizatorul îl poate adăuga la ecranul lor inițial. În această parte finală a seriei, vom implementa configurația de bază a utilizatorului. În Partea 2 am creat mai multe desene de ceas, așa că acum vom permite utilizatorului să aleagă între ele.

Acesta este Partea 4 din 4 dintr-o serie despre construirea unui widget personalizabil de ceas Android analogic în patru tutoriale:

  • Android Widget Configurare proiect
  • Proiectarea ceasului
  • Primirea actualizărilor și lansarea
  • Implementarea configurării utilizatorilor

Crearea de configurare a utilizatorilor în aplicația noastră widget va implica o nouă clasă de activitate Java, prezentând selecția utilizatorilor. Când utilizatorul selectează un design, vom actualiza aspectul widget-ului și vom stoca alegerea utilizatorului în preferințele partajate ale aplicației. Vom extinde, de asemenea, clasa widget pentru a manipula clicurile utilizatorilor pe widget și pentru a citi din Preferințele partajate pentru alegerea utilizatorului. Pe lângă lucrul cu aceste două fișiere Java, vom crea un nou fișier de valori și un fișier de aspect XML pentru alegerea Activității împreună cu unele imagini care să fie afișate în cadrul acesteia.


Pasul 1: Faceți clic pe clicurile widget

Mai întâi, să adăugăm un anumit cod la clasa widget pentru a detecta clicurile utilizatorilor. În clasa "ClockWidget", în interiorul instrucțiunii "if" din metoda "onReceive", după linia în care am preluat obiectul Remote Views, adăugați următorul cod pentru a crea intenția pentru selectator Activitatea pe care o vom folosi:

 Intenție choiceIntent = intenție nouă (context, ClockChoice.class);

Nu vă faceți griji pentru erorile Eclipse pentru moment, acestea vor dispărea atunci când vom crea noua clasă de activitate în pasul următor. După această linie, creați o intenție în așteptare după cum urmează:

 PendingIntent clickPendIntent = PendingIntent.getActivity (context, 0, choiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Activitățile de lansare pe clicurile widget-urilor sunt puțin diferite, după cum puteți vedea. Observați că trecem obiectul Context și o referință la noul intenție. Acum, adăugați următorul cod care specifică faptul că interogarea în așteptare ar trebui lansată când se face clic pe widget-ul:

 views.setOnClickPendingIntent (R.id.custom_clock_widget, clickPendIntent);

Specificăm widget-ul referindu-ne la ID-ul structurii părinte în fișierul XML "clock_widget_layout". Trebuie să folosim Vizualizările la distanță pentru a face referire la elementele interfeței cu utilizatorul ca și cum ne aflăm într-o clasă de widgeturi, nu ca o clasă de activitate. Vom adăuga mai mult cod la această clasă mai târziu.


Pasul 2: Creați o activitate de selectare

Acum, pentru activitatea în care am lăsat utilizatorilor să aleagă un design. Creați o nouă clasă în proiect făcând clic dreapta sau selectând folderul sursă și selectând "Fișier" - apoi selectați "Nou", "Clasă" și introduceți "ClockChoice" ca nume de clasă. Eclipse va deschide noua clasă când faceți clic pe Finalizare. Amintiți-vă că am inclus această activitate în fișierul Manifest al proiectului din Partea 1.

Creați noua clasă o Activitate și una care va gestiona clicurile utilizatorilor prin extinderea liniei de deschidere după cum urmează:

 clasa publică ClockChoice extinde Activitatea implementează OnClickListener 

Din nou, ignorați toate mesajele de eroare, acestea vor apărea până când vom furniza metoda "onClick". Veți avea nevoie de următoarele declarații de import:

 importă android.app.Activity; importă android.view.View.OnClickListener;

Furnizați metoda "onCreate" a activității în interiorul clasei după cum urmează:

 public void onCreate (bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.clock_choice); 

Vom crea fișierul de aspect în pasul următor. Veți avea nevoie de un alt import:

 import android.os.Bundle;

Vom adăuga mai mult cod la această clasă mai târziu.


Pasul 3: Designul activității de selectare

Să creați aspectul specificat în clasa de activitate de mai sus. Creați un nou fișier de aspect prin clic-dreapta sau selectând folderul "res / layout" și selectând "File", apoi făcând clic pe "New", "File" și introducând "clock_choice.xml".

Când Eclipse deschide fișierul, selectați fila "clock_choice.xml" pentru a edita codul. Introduceți următoarea schiță de dispunere în fișierul dvs.:

    

Designul include o dispunere liniară în interiorul unei vizualizări scroll. În interiorul Aspectului liniar, adăugați mai întâi un text informativ după cum urmează:

 

Adăugați resursa String indicată aici în fișierul dvs. "strings.xml" - asigurați-vă că îl includeți în ambele copii ale fișierului cu șiruri de caractere, în "valori" și "valori-v14":

 Alege o opțiune:

Acum vom afișa o imagine care să reprezinte fiecare design de ceas. Aceste imagini vor funcționa ca butoane pe care utilizatorii să le apese atunci când selectează un design. Creați-vă imaginile acum, amintiți-vă să includeți diferite versiuni pentru fiecare densitate. Dacă nu doriți să creați propriul dvs. încă, puteți utiliza imaginile din link-ul de descărcare din partea de jos a tutorialului - aici sunt versiunile cu densitate medie ale fiecăruia:

Salvați fiecare versiune a imaginilor dvs. în folderele desenate pentru aplicația dvs., amintiți-vă că utilizați aceleași nume în fiecare folder densitate.

Acum mergeți înapoi la fișierul XML "layout clock_choice". Adăugați un buton de imagine pentru fiecare design pe care îl utilizați, cu următoarele pentru cele trei exemple de modele pe care le-am utilizat, după textul de vizualizare:

   

Există mai multe puncte de reținut aici. Mai intai, observati ca fiecare buton de imagini are un ID cu aceeasi sintaxa, dar un numar incrementant la sfarsit - vom folosi aceasta pentru a itera prin desenele din Java, asa ca daca includeti mai mult de trei desene, asigurati-va ca le asignati iterating numere, cum ar fi "design_3", etc. În afară de atributele de proiectare, fiecare element indică, de asemenea, resursa de tragere relevantă, astfel încât să le modificați dacă fișierele imagine pe care tocmai le-ați creat au nume diferite. În cele din urmă, atributele de descriere a conținutului se referă la resursele de șir, deci adăugați-le în fișierele "strings.xml" din folderele "values" și "values-v14" după cum urmează:

 Implicit Design de piatră Proiectare metalică

Modificați aceste descrieri, dacă este necesar, pentru a vă potrivi propriilor desene sau modele.

Să facem uz de temele Android pentru a automatiza anumite aspecte ale aspectului Activator. Deschideți fișierul Manifest al proiectului și extindeți elementul care reprezintă selectorul de ceas Activitate după cum urmează:

  

Adăugarea temei de dialog face ca activitatea să apară suprapusă pe ecranul de start - acesta este aspectul său cu modelele de mostre pe care le-am utilizat în această serie de tutori:


Aceasta este ceea ce va apărea când utilizatorul face clic pe widget. Dacă afișajul dispozitivului este prea mic pentru a se potrivi cu toate cele trei modele, acestea vor derula după ce aspectul utilizează o vizualizare Scroll. Când utilizatorul selectează un design, aspectul widgetului se va actualiza și această opțiune Activitate va dispărea.

Este de la sine înțeles că ați putea dori să modificați numărul de desene sau modele posibile din aplicația widget ceas. Pentru a face acest proces mai ușor, vom face din codul nostru Java să citească dinamic numărul de modele. În acest scop, vom folosi o valoare numerică pentru a urmări numărul de modele pe care le folosim. Creați un fișier nou în fiecare din cele două dosare de valori, făcând clic dreapta sau selectând fiecare dosar la rândul său și selectând "Fișier", apoi "Nou", "Fișier" și introduceți "numere.xml" ca nume de fișier.


Selectați fila "numere.xml" și introduceți următorul cod în noul fișier:

  3 

Modificați numărul dacă ați utilizat un număr diferit de modele, asigurându-vă că valoarea corespunde numărului de butoane de imagine pe care le-ați inclus în aspect și numărului de elemente de ceas analogice pe care le aveți în aspectul dvs. widget. Amintiți-vă că aveți nevoie de o copie a fișierului "numere.xml" în ambele dosare de valori, deci copiați-l și lipiți-l, dacă este necesar.

Dacă modificați numărul de modele pe care le utilizați în orice moment, trebuie să modificați valoarea în fișierele "numere.xml", adăugați fiecare desen sau model ca element Analog Clock în fișierul "clock_widget_layout" al aplicației și un Butonul Imagine pentru fiecare design din fișierul de aranjare a activității.


Pasul 4: Alegeți alegerea utilizatorului

Să analizăm interacțiunea utilizatorului cu selectarea desenelor ceasului. Deschideți fișierul de activitate "ClockChoice". În interiorul clasei, înainte de metoda "onCreate", adăugați următoarele variabile de instanță:

 // numărul de desene și modele private private numDesigns; // butoane de imagine pentru fiecare design privat ImageButton [] designBtns; // identificatori pentru fiecare element de ceas private int [];

Vom folosi aceste variabile pentru a repeta diferitele modele. Adăugați un alt import:

 import șiroid.widget.ImageButton;

În cadrul metodei "onCreate", după codul existent, instanțiați variabila pentru a ține evidența numărului de desene ceas, după cum urmează:

 numDesigns = this.getResurse () getInteger (R.integer.num_clocks);

Aici extragem valoarea din fișierul numerelor XML pe care l-am creat mai devreme - vom putea folosi această valoare ca referință atunci când iterăm prin desene sau modele. Apoi instanțiați matricea pentru butoanele de design și elementele ceasului:

 designBtns = new ImageButton [numDesigns]; desene = noi int [numDesigns];

Prima matrice se va referi la butoanele de imagine pe care le folosim în cadrul acestei activități de selecție pentru a detecta alegerea utilizatorului. Cea de-a doua matrice va stoca referințe la elementele ceasului Analog pentru fiecare design în fișierul de aspect widget propriu-zis.

Acum adăugați o buclă pentru a itera prin desene:

 pentru (int d = 0; d 

În bucla, extrageți o referință la fiecare element Analog Clock din aspectul widget:

 desenele [d] = this.getResources (). getIdentifier ("AnalogClock" + d, "id", getPackageName ());

Dacă vă uitați înapoi la fișierul "clock_widget_layout", veți vedea că fiecare element Analog Clock are un ID care cuprinde "AnalogClock" urmat de un întreg incrementant - folosim aici pentru a obține o referință la fiecare folosind contorul de buclă. Apoi, încă în interiorul bucla, extrageți valorile ID pentru butoanele Imagine din selectorul de activitate:

 designBtns [d] = (ImageButton) findViewById (acest.getResurse (). getIdentifier ("design _" + d, "id", getPackageName ()));

Aici folosim "findViewById" pentru a obține o referință la elementul relevant Butonul Imagine, trecând ID-ul, care cuprinde "design_" urmat de întregul incrementant. Acum setați ascultătorul de clic pentru fiecare dintre aceste butoane astfel încât să putem gestiona clicurile din această clasă de activitate. În timp ce încă în interiorul bucla:

 designBtns [d] .setOnClickListener (aceasta);

Acum putem continua cu metoda de clic pentru butoanele de design. După metoda "onCreate" din clasa "ClockChoice", adăugați o metodă "onClick" după cum urmează:

 public void onClick (Vizualizare v) 

Adăugați următorul import:

 import șiroid.view.View;

În metoda "onClick", trebuie mai întâi să determinăm ce buton a apăsat utilizatorul. Adăugați următoarea bucla în interiorul metodei în acest scop:

 int picked = -1; pentru (int c = 0; 

Aici verificăm ID-ul de vizualizare clicat pe ID-urile pe care le-am stocat în matricea de butoane pentru imagini. Când ieșim din buclă, avem indicele ales stocat într-o variabilă locală. După ce buclă stochează o referință la ID-ul pentru elementul Analog Clock ales:

 int pickedClock = desene [selectate];

Acum avem nevoie de o referință la elementele de aspect widget, pentru care avem nevoie de vizualizările la distanță, trecând aspectul widget-ului ca referință:

 RemoteViews remoteViews = noi RemoteViews (this.getApplicationContext (). GetPackageName (), R.layout.clock_widget_layout);

Pentru aceasta aveți nevoie de o altă declarație de import:

 importă android.widget.RemoteViews;

Amintiți-vă că am inclus fiecare proiectare analogică în fișierul de aspect widget - aceasta deoarece nu putem modifica dinamic atributele unui ceas analogic cum ar fi drawable-urile pentru cadran și mâini, deci includem toate modelele și setați toate dar una să fie invizibilă. Înainte de a seta proiectarea ceasului ales pentru a fi vizibilă, vom seta pe celelalte să fie invizibile, pe care le putem face într-o buclă după cum urmează:

 pentru (int d = 0; d 

Utilizăm matricea în care am stocat valorile ID-ului elementului Analog Clock pentru a seta fiecare invizibil, atâta timp cât nu este cel ales. Acum putem seta designul ales să fie vizibil, după această buclă:

 remoteViews.setViewVisibility (pickedClock, View.VISIBLE);

Acum, deoarece aceasta este o aplicație widget, trebuie să actualizăm aspectul widgetului după cum urmează:

 // obține numele componentei pentru clasa widget ComponentName comp = nume Component nou (acest lucru, ClockWidget.class); // primiți AppWidgetManager AppWidgetManager appWidgetManager = AppWidgetManager.getInstance (this.getApplicationContext ()); // actualizați appWidgetManager.updateAppWidget (comp, remoteViews);

Acest lucru este similar cu modul în care am actualizat widget-ul în clasa de furnizori widget, dar cu câțiva pași suplimentari de procesare, deoarece suntem într-o clasă de activitate aici. Va trebui să adăugați aceste importuri:

 import șiroid.appwidget.AppWidgetManager; importați android.content.ComponentName;

Acum aspectul widget-ului se va actualiza în funcție de alegerea utilizatorului.


Pasul 5: Actualizați preferințele partajate

Apoi, vom folosi aplicația Preferințe partajate pentru a stoca alegerea utilizatorului. Faceți o copie de siguranță în partea de sus a clasei de activitate Activitate, adăugați o altă variabilă de instanță:

 private SharedPreferences clockPrefs;

Acum, la sfârșitul metodei "onCreate", după codul existent adăugați următoarele pentru a instanțiza variabila Preferințe partajate:

 clockPrefs = getSharedPreferences ("CustomClockPrefs", 0);

Vom folosi același nume de preferințe de fiecare dată când accesăm datele privind alegerea utilizatorului. Acum deplasați-vă până la capătul metodei "onClick", după codul în care am actualizat widget-ul. Obțineți editorul de preferințe după cum urmează:

 SharedPreferences.Editor custClockEdit = clockPrefs.edit ();

Transmite acum datele privind alegerea utilizatorului către editor și îl obligați:

 custClockEdit.putInt ("design-ul ceasului", selectat); custClockEdit.commit ();

Specificăm un nume pentru valoarea datelor și ID-ul designului ales. În cele din urmă, încă în "onClick" adăugați următoarele lucruri pe măsură ce lucrarea Activității sa terminat:

 finalizarea();

Pasul 6: Verificați preferințele partajate

Acum putem folosi datele Preferințe partajate din cadrul clasei widget. Deschideți clasa "ClockWidget", care extinde aplicația AppWidgetProvider. Algoritmii pe care îi folosim aici vor fi asemănători cu cei utilizați mai sus pentru gestionarea modelelor de ceasuri. Adăugați următoarele variabile de instanță suplimentare în partea de sus:

 // preferințe private SharedPreferences custClockPrefs; // numărul de desene posibile private int numClocks; // ID-urile elementelor ceasului analogic int [] clockDesigns;

Veți avea nevoie de următorul import:

 import android.content.SharedPreferences;

În metoda "onReceive", inainte de codul existent, regăsiți numărul de modele din resursele noastre de valoare:

 numClocks = context.getResurse () getInteger (R.integer.num_clocks);

Apoi instanțiați matricea de identificare a ceasului după cum urmează:

 clockDesigns = int int [numClocks];

Acum buclei prin această matrice, setând fiecare element ca ID-ul pentru elementul analogic ceas relevant în aspectul widget-ului:

 pentru (int d = 0; d 

Acum, treceți la conținutul instrucțiunii "if" din metoda "onReceive", după linia în care am preluat vizionările la distanță și înainte de linia în care am creat clasa Intenția pentru alegerea ceasului, obțineți Preferințele partajate și verificați pentru valoarea de date pe care o stabilim pentru alegerea utilizatorului:

 custClockPrefs = context.getSharedPreferences ("CustomClockPrefs", 0); int selectDesign = custClockPrefs.getInt ("clockdesign", -1);

Numele Preferințelor partajate și numele valorilor datelor trebuie să se potrivească cu ceea ce ați inclus atunci când stabiliți alegerea utilizatorului în Activitatea de selecție de mai sus. Este posibil ca utilizatorul să nu fi ales încă un design, deci includeți o declarație "if" pentru a verifica:

 dacă (selectDesign> = 0) 

În interiorul instrucțiunii "if", prima bucla prin desene sau modele, stabilind fiecare invizibil dacă nu este cel ales:

 pentru (int d = 0; d 

Veți avea nevoie de un alt import:

 import șiroid.view.View;

Acum setați designul ales vizibil:

 views.setViewVisibility (ceasDesignuri [selectDesign], View.VISIBLE);

Acum când widget-ul este actualizat, dacă utilizatorul a ales un design, acel design va fi afișat.


Concluzie

Acesta este widget-ul ceasului! Puteți rula pe un emulator sau pe un dispozitiv pentru al testa. Ar trebui să ruleze continuu, actualizând timpul și reflectând alegerea utilizatorului de proiectare.


Luați ceva timp să vă uitați înapoi la diferitele elemente de aplicație și asigurați-vă că înțelegeți cum funcționează împreună cu ceilalți. Procesul de dezvoltare a oricărei alte aplicații widget va implica o mulțime de aceiași pași. Elementele vitale ale unei aplicații widget sunt: ​​elementul XML "appwidget-provider", fișierul Manifest, clasa care extinde AppWidgetProvider și, desigur, elementele vizuale, inclusiv layout-urile și resursele.

Dacă doriți să dezvoltați în continuare abilitățile pe care le-ați învățat în această serie, există o serie de opțiuni. Dacă doriți să furnizați o configurație avansată a utilizatorilor pentru widget-urile dvs., puteți utiliza o activitate de preferință împreună cu acțiunea APPWIDGET_CONFIGURE. Dacă doriți să includeți afișaje ceas digital împreună cu opțiunile analogice, procesul este puțin mai complex. Puteți include clasa prestabilită a ceasurilor digitale într-o aplicație standard, dar nu într-o aplicație widget, deci trebuie să implementați afișarea timpului digital și să vă actualizați, utilizând componente suplimentare, cum ar fi serviciile și managerii de alarmă.

Simțiți-vă liber să utilizați codul sursă complet și imaginile pentru acest tutorial furnizat în link-ul de descărcare.

Cod