Dificultate: BeginnerLength: LongLanguages:
Widgeturile pentru aplicatii ofera utilizatorilor dvs. acces usor la cele mai utilizate functii ale aplicatiei dvs., oferind in acelasi timp aplicatiei dvs. o prezenta pe ecranul de pornire al utilizatorului. Prin adaugarea unui widget la proiectul dvs., puteti oferi o experienta de utilizator mai buna, incurajand in acelasi timp utilizatorii sa ramana angajati cu aplicatia dvs., deoarece de fiecare data cand se uita la ecranul lor de pornire, va vor vedea widgetul, afisand unele dintre cele mai utile aplicatii ale dvs. continut interesant.
In aceasta serie de trei parti, construim un widget de aplicatii care are toate functionalitatile pe care le veti gasi in aproape fiecare widget de aplicatii Android.
In prima postare, am creat un widget care preia si afiseaza date si realizeaza o actiune unica ca raspuns la evenimentele onClick. Cu toate acestea, widget-ului nostru lipseste inca o componenta cruciala: nu se actualizeaza niciodata cu informatii noi. Un widget care nu are niciodata ceva nou de oferit nu este atat de util, asa ca vom oferi widget-ului nostru doua moduri diferite de actualizare.
Pana la sfarsitul acestei serii, vom extinde widget-ul nostru pentru a prelua si afisa date noi automat pe baza unui program si ca raspuns la interactiunea utilizatorului.
Ridicam exact locul unde ne-am lasat, asa ca daca nu aveti o copie a widgetului creat de noi in prima postare, atunci il puteti descarca de pe GitHub.
Actualizarea machetei
Primul pas este actualizarea machetei noastre pentru a afisa unele date care se schimba in timp. Pentru a ne ajuta sa vedem exact cand widget-ul nostru primeste fiecare actualizare, voi instrui widget-ul sa recupereze si sa afiseze ora curenta, ori de cate ori efectueaza o actualizare.
Voi adauga urmatoarele la aspectul widgetului:
- TextView care afiseaza o eticheta de ultima actualizare.
- Un TextView care va afisa ora ultimei actualizari.
In timp ce lucram la noul fisier_app_widget.xml, voi adauga si TextView care va permite utilizatorului sa declanseze manual o actualizare:
id = “@ + id / id_value” android: layout_width = “wrap_content” android: layout_height = “wrap_content” android: text = “.” style = “@ style / widget_text” /> </LinearLayout> <TextView android: id = “@ + id / launch_url” style = “@ style / widget_views” android: layout_width = “wrap_content” android: layout_height = “wrap_content” android : text = “@ string / URL” android: background = “@ drawable / tvbackground” /> // Adaugati un „Apasati pentru a actualiza” TextView // <TextView android: id = “@ + id / actualizare” style = “@ style / widget_views “android: layout_width = android” wrap_content “: layout_height =” wrap_content “android: text =” @ string / actualizare “android: background =” @ drawable / tvbackground “/> <
Apoi, definiti noile resurse sir la care facem referinta in aspectul nostru:
<string name = “update”> Apasati pentru actualizare </string> <string name = “last_update”> Ultima actualizare </string> <string name = “time”>% 1 $ s </string>
@ String / ora arata diferit de sirul dvs. tipic, deoarece este doar un marcator de locatie care va fi inlocuit la runtime.
Acest lucru ne ofera aspectul finalizat:
Actualizarea widgetului pe baza unei planificari
Intrucat este cea mai usoara metoda de implementat, voi incepe prin actualizarea automata a widgetului, dupa ce a trecut o perioada stabilita.
La crearea acestui tip de program de actualizare automata, 1800000 milisecunde (30 minute) este cel mai mic interval pe care il puteti utiliza. Chiar daca setati actualizarea proiectului dvs.PeriodMillis la mai putin de 30 de minute, widgetul va fi actualizat inca o data la fiecare jumatate de ora.
Decizia cat de frecvent ar trebui sa actualizeze widget-ul dvs. nu este niciodata simpla. Actualizarile frecvente reprezinta o scurgere mai mare pe bateria dispozitivului, dar setati aceste actualizari prea departe si este posibil ca widgetul dvs. sa se afiseze in mod semnificativ invechit utilizatorului.
Pentru a gasi un echilibru care sa functioneze pentru proiectul dvs. particular, va trebui sa va testati widgetul intr-o gama de frecvente de actualizare si sa masurati impactul pe care fiecare frecventa il are asupra duratei de viata a bateriei, urmarind in acelasi timp daca continutul widgetului devine vreodata demodat.
Intrucat cat de frecventa este prea frecventa este una dintre acele intrebari subiective frustrante in care nu exista un raspuns „corect”, poate ajuta la obtinerea unei a doua opinii prin aranjarea unor teste ale utilizatorilor. Ati putea chiar configura unele teste A / B pentru a verifica daca anumite frecvente de actualizare sunt primite mai pozitiv decat altele.
Deschideti fisierul AppWidgetProviderInfo al proiectului (res / xml / new_app_widget_info.xml) si veti vedea ca acesta defineste deja un interval de actualizare implicit de 86400000 milisecunde (24 ore).
Android: updatePeriodMillis = “86400000”
Exista o multime de widget-uri care se actualizeaza doar o data la 24 de ore, de exemplu, un widget care afiseaza prognoza meteo ar putea avea nevoie doar de a prelua informatii noi o data pe zi. Cu toate acestea, chiar daca widgetul trebuie doar sa se actualizeze o data pe zi, acest lucru nu este ideal atunci cand testati aplicatia. Nimeni nu vrea sa astepte 24 de ore doar pentru a vedea daca metoda onUpdate () se declanseaza corect, asa ca, de obicei, veti utiliza cel mai scurt interval posibil atunci cand efectuati testarea initiala, apoi modificati aceasta valoare mai tarziu, daca este necesar.
Pentru a facilita testarea aplicatiei noastre, voi folosi cel mai mic interval posibil:
Android: updatePeriodMillis = “1800000”
Regasirea si afisarea orei curente
Metoda onUpdate () este responsabila pentru actualizarea Vizualizarilor widgetului dvs. cu informatii noi. Daca deschideti furnizorul de widget al proiectului (java / valori / NewAppWidget.java), atunci veti vedea ca acesta contine deja conturul unei metode onUpdate ():
@Override public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {// Pot exista mai multe widget-uri active, deci actualizati-le pe toate // pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager) ; }}
Indiferent daca widget-ul dvs. se actualizeaza automat sau ca raspuns la interactiunea utilizatorului, procesul de actualizare este exact acelasi: managerul de widget trimite o intentie de difuzare cu actiunea ACTION_APPWIDGET_UPDATE, iar clasa furnizor de widget-uri raspunde apeland la metoda onUpdate (), care la randul sau, apeleaza la metoda de ajutor updateAppWidget ().
Dupa ce am actualizat clasa noastra NewAppWidget.java pentru a prelua si afisa ora curenta, proiectul nostru va folosi aceasta aceeasi sectiune de cod, indiferent de modul de declansare a metodei onUpdate ().
import Android.appwidget.AppWidgetManager; import Android.appwidget.AppWidgetProvider; import android.content.Context; import Android.widget.RemoteViews; import Android.app.PendingIntent; import android.content.Intent; import Android.net.Uri; import java.text.DateFormat; import java.util.Date; public class NewAppWidget extinde AppWidgetProvider {static void updateAppWidget (context contextual, AppWidgetManager appWidgetManager, int appWidgetId) {// Recupera ora // String timeString = DateFormat.getTimeInstance (DateFormat.SHORT) .format (new Date) // Construieste obiectul RemoteViews // Vizualizari RemoteViews = noi RemoteViews (context.getPackageName (), R.layout.new_app_widget); views.setTextViewText (R.id.id_value, String.valueOf (appWidgetId)); // Recuperati si afisati ora // vizualizari.setTextViewText (R.id.update_value, context.getResources (). getString (R.string.time, timeString)); Intent intent = new Intent (Intent.ACTION_VIEW, Uri.parse (“https://code.tutsplus.com/”)); PendantIntent pendentIntent = PendantIntent.getActivity (context, 0, intentie, 0); viewss.setOnClickPendingIntent (R.id.launch_url, pendinteIntent); appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @Substituie public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {// Daca mai multe widget-uri sunt active, atunci actualizati-le toate // pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager), app; }}} PendantIntent pendentIntent = PendantIntent.getActivity (context, 0, intentie, 0); viewss.setOnClickPendingIntent (R.id.launch_url, pendinteIntent); appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @Substituie public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {// Daca mai multe widget-uri sunt active, atunci actualizati-le toate // pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager), app; }}} PendantIntent pendentIntent = PendantIntent.getActivity (context, 0, intentie, 0); viewss.setOnClickPendingIntent (R.id.launch_url, pendinteIntent); appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @Substituie public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {// Daca mai multe widget-uri sunt active, atunci actualizati-le toate // pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager), app; }}} appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); }}} appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); }}}
Exista o problema cu codul de mai sus: daca utilizatorul atinge TextView de mai multe ori pe durata unui minut, nu va exista nicio indicatie vizuala ca widget-ul s-a actualizat, pur si simplu pentru ca nu exista un timp nou pentru afisare. Acest lucru probabil nu va cauza probleme utilizatorilor dvs. finali, care este putin probabil sa stea acolo, atingand TextView de mai multe ori pe minut si se intreaba de ce nu s-a schimbat ora. Cu toate acestea, aceasta poate fi o problema la testarea aplicatiei dvs., deoarece inseamna ca va trebui sa asteptati cel putin 60 de secunde intre declansarea metodei onUpdate ().
Pentru a va asigura ca exista intotdeauna un fel de confirmare vizuala ca metoda onUpdate () a rulat cu succes, voi afisa un toast ori de cate ori onUpdate () este numit:
import Android.widget.Toast; … … … @Override public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {for (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, „Widget-ul a fost actualizat!”, Toast.LENGTH_SHORT) .show (); }}}
Actualizarea widget-ului dvs. ca raspuns la actiunea utilizatorului
Widget-ul nostru se va actualiza automat o data la fiecare jumatate de ora, dar ce se intampla cu actualizarea ca raspuns la interactiunea utilizatorului?
Am stabilit deja o multime de lucrari fundamentale adaugand un apasat la Actualizare TextView la aspectul nostru si extinderea clasei NewAppWidget.java pentru a prelua si afisa ora actuala ori de cate ori este apelat onUpdate ().
Singurul lucru ramas de facut este sa creezi o intentie cu AppWidgetManager.ACTION_APPWIDGET_UPDATE, care este o actiune care informeaza widgetul ca este momentul sa se actualizeze, apoi sa apeleze aceasta intentie ca raspuns la utilizatorul care interactioneaza cu Apasati pentru a actualiza TextView.
Iata clasa completata NewAppWidget.java:
import Android.appwidget.AppWidgetManager; import Android.appwidget.AppWidgetProvider; import android.content.Context; import Android.widget.RemoteViews; import Android.app.PendingIntent; import android.content.Intent; import Android.net.Uri; import java.text.DateFormat; import java.util.Date; import Android.widget.Toast; public class NewAppWidget extinde AppWidgetProvider {static void updateAppWidget (context contextual, AppWidgetManager appWidgetManager, int appWidgetId) {// Recupera ora actuala // String timeString = DateFormat.getTimeInstance (DateFormat.SHORT).); Vizualizari RemoteViews = noi RemoteViews (context.getPackageName (), R.layout.new_app_widget); views.setTextViewText (R.id.id_value, String.valueOf (appWidgetId)); views.setTextViewText (R.id.update_value, context.getResources (). getString (R.string). time, timeString)); // Creati o intentie cu AppWidgetManager.
filme porno romanesti xxx http://eslresourcecenter.us/__media__/js/netsoltrademark.php?d=adult66.net/
filme porno cu lezbience http://simpleskills.org/__media__/js/netsoltrademark.php?d=adult66.net/
web chat porno http://aircraftforce.com/__media__/js/netsoltrademark.php?d=adult66.net/
filme porno cu femei virgine http://aahonduras.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/amatori
filme gay porno http://benguerel.info/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/anal
gay boys porno http://mcnasonrisas.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/asiatice
fiulme porno http://1dollaronlinecourse.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/beeg
fre porno http://pesni.org/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/blonde
filme porno craiova http://money-supermarket.org/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/brazzers
school porno http://cadenceorcad.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/brunete
corina caragea porno http://makeworkhappy.biz/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/chaturbate
porno lung metraj http://gimmefreebies.com/__media__/js/netsoltrademark.php?d=adult66.net/asistenta-medicala-isi-violeaza-pacientul-apoi-ii-face-sex-oral
sport porno http://embargostudios.com/__media__/js/netsoltrademark.php?d=adult66.net/cuplu-de-tineri-infierbantati-face-sex-in-bucatarie-in-pozitii-ciudate
filme porno cu pizde paroase http://quickiecartoons.com/__media__/js/netsoltrademark.php?d=adult66.net/tanara-e-fututa-anal-chiar-de-tatal-ei-vitreg-cand-au-ramas-singuri-acasa
filme porno 2016 http://meraaspropertydevelopment.com/__media__/js/netsoltrademark.php?d=adult66.net/cuplu-de-amatori-au-orgasm-in-timp-ce-fac-sex-ca-animalele
casting filme porno http://t180network.info/__media__/js/netsoltrademark.php?d=adult66.net/creola-super-buna-e-fututa-pe-la-spate-de-un-salbatic-tatuat
filme porno istorice http://irishlifemail.com/__media__/js/netsoltrademark.php?d=adult66.net/orgasm-extrem-cu-o-bruneta-fututa-pe-scaun-de-fratele-ei
porno ascuns masaj http://nighttoremember.com/__media__/js/netsoltrademark.php?d=adult66.net/doua-scolarite-infierbantate-fac-sex-in-clasa
altyazılı porno http://editionsquebecormedia.com/__media__/js/netsoltrademark.php?d=adult66.net/o-minora-e-dezvirginata-de-doua-colegi-mai-mari-si-linsa-in-pizda
porno romanian http://defrisage.com/__media__/js/netsoltrademark.php?d=adult66.net/cuplu-de-japonezi-fac-sex-in-pat-pana-au-orgasm
ACTION_APPWIDGET_UPDATE actiune // Intent intentUpdate = new Intent (context, NewAppWidget.class); intentUpdate.setAction (AppWidgetManager.ACTION_APPWIDGET_UPDATE); // Actualizati doar instanta de widget curenta, creand un tablou care contine ID-ul unic al widget-ului // int [] idArray = new int [] {appWidgetId}; intentUpdate.putExtra (AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray); // Infasurati intentia ca PendantIntent, folosind IntelesIntent.getBroadcast () // PendenteIntent pendenteUpdate = PendantIntent.getBroadcast (context, appWidgetId, intentUpdate, PendantIntent.FLAG_UPDATE_CURRENT); // Trimiteti intentia in asteptare ca raspuns la utilizatorul atingand „Actualizare” TextView // views.setOnClickPendingIntent (R.id.update, pendinteUpdate); Intentie intentie = new Intent (Intent. ACTION_VIEW, Uri.parse (“https://code.tutsplus.com/”)); PendantIntent pendentIntent = PendantIntent.getActivity (context, 0, intentie, 0); viewss.setOnClickPendingIntent (R.id.launch_url, pendinteIntent); // Solicitati ca AppWidgetManager sa actualizeze widget-ul aplicatiei // appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @ Supraverseaza public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, „Widget-ul a fost actualizat!”, Toast.LENGTH_SHORT) .show (); }}} // Solicitati ca AppWidgetManager sa actualizeze widget-ul aplicatiei // appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @ Supraverseaza public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, „Widget-ul a fost actualizat!”, Toast.LENGTH_SHORT) .show (); }}} // Solicitati ca AppWidgetManager sa actualizeze widget-ul aplicatiei // appWidgetManager.updateAppWidget (appWidgetId, vizualizari); } @ Supraverseaza public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {pentru (int appWidgetId: appWidgetIds) {updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, „Widget-ul a fost actualizat!”, Toast.LENGTH_SHORT) .show (); }}}
Posibilitatea de a actualiza un widget la cerere poate fi de nepretuit atunci cand testati proiectul dvs., deoarece inseamna ca nu va trebui sa asteptati sa treaca intervalul de actualizare. Chiar daca nu includeti aceasta functionalitate in aplicatia finalizata, poate doriti sa adaugati un buton Atingeti temporar la Actualizare, doar pentru a va usura viata atunci cand testati proiectul.
Crearea unei imagini previzibile
Widget-ul nostru arata acum cu totul diferit de widget-ul pe care Android Studio l-a generat automat pentru noi, dar in acest moment inca foloseste imaginea de previzualizare generata automat.
In mod ideal, imaginea dvs. de previzualizare ar trebui sa incurajeze utilizatorii sa selecteze widget-ul din Selectorul de widget, dar cel putin ar trebui sa fie o reprezentare precisa a aspectului de fapt al widgetului dvs. In prezent, imaginea noastra de previzualizare nu bifeaza niciuna dintre casetele, asa ca trebuie sa cream una noua.
Cea mai simpla metoda este sa utilizati aplicatia Widget Preview care este inclusa in emulatorul Android.
Crearea unei previzualizari a widget-urilor
Mai intai, instaleaza-ti proiectul pe un dispozitiv virtual Android (AVD). Apoi, deschide sertarul aplicatiei AVD si lanseaza aplicatia Previzualizare widget. AVD va afisa o lista cu fiecare aplicatie instalata pe dispozitiv – selectati aplicatia din lista.
Widgetul dvs. va fi afisat pe un fundal gol. Petreceti ceva timp redimensionandu-va si regasindu-va widgetul astfel incat sa arate cat mai bine si, dupa ce sunteti multumit de rezultate, selectati Echipare. Imaginea de ecran va fi salvata ca PNG in folderul Descarcare AVD. Pentru a prelua acest fisier, treceti inapoi la Android Studio si deschideti Dispozitivul de fisiere Explorer, selectand Afisati> Instrumentul Windows> Device File Explorer din bara de instrumente. In vizualizarea Device File Explorer, navigati in folderul sdcard / Download, unde veti gasi imaginea de previzualizare salvata ca: [nume_aplicare] _ori_ [orientare] .png
Trageti aceasta imagine din Android Studio si aruncati-o undeva usor accesibil, cum ar fi desktopul dvs. Dati imaginii un nume mai descriptiv, apoi trageti si plasati imaginea in folderul desenabil al proiectului. Acum puteti deschide fisierul AppWidgetProviderInfo (in acest caz, acesta este new_app_widget_info.xml) si puteti schimba urmatoarea linie pentru a face referire la noua dvs. imagine de previzualizare:
android: previewImage = “@ drawable / example_appwidget_preview”
In cele din urma, puteti elimina exemplul inutil_appwidget_preview desenabil din proiectul dvs.
Testarea widget-ului
Este timpul sa pui widgetul final la test!
Mai intai, instalati proiectul actualizat pe dispozitivul dvs. fizic Android sau pe AVD. Eliminati toate instantele existente ale acestui widget de pe ecranul de domiciliu, astfel incat sa stiti ca lucrati cu cea mai recenta versiune.
Pentru a adauga widgetul, apasati orice spatiu gol pe ecranul de intampinare, atingeti Widget si apoi selectati widgetul. Veti avea ocazia sa redimensionati si sa repozitionati widgetul, dupa cum este necesar.
Valoarea Ultima actualizare va afisa perioada in care ati creat acest widget. Apasati Apasati pentru Actualizare si widget-ul ar trebui sa afiseze un toast si un timp nou. Daca asezati oa doua instanta a widget-ului pe ecranul de domiciliu, aceasta ar trebui sa afiseze o data diferita fata de prima.
Puteti actualiza oricare dintre aceste instante de widget, dand un apasare pe Actualizare textView. Daca declansati o actualizare manuala pentru primul widget, atunci cel de-al doilea widget nu va fi actualizat si invers.
Pe langa actualizarile manuale, App Widget Manager va actualiza toate instantele widget-ului o data la 30 de minute, in functie de momentul in care ati creat prima instanta. Desi actualizarile manuale pot duce la aparitia unor momente diferite, o data la o jumatate de ora, toate instantele vor fi actualizate simultan, moment in care vor afisa acelasi timp.
Poate doriti sa pastrati cateva instante ale acestui widget pe ecranul dvs. de pornire, astfel incat sa puteti monitoriza modul in care continutul lor se schimba in timp, ca raspuns la o combinatie de actualizari automate si manuale.
Concluzie
In aceasta serie, am creat un widget pentru aplicatii Android care arata cum sa implementam toate cele mai comune functii gasite in widget-urile pentru aplicatii. Daca ati urmarit de la inceput, atunci, pana la acest moment, veti fi construit un widget care se actualizeaza automat si ca raspuns la intrarea utilizatorului si care sa poata reactiona la evenimentele onClick (puteti descarca si proiectul complet de la GitHub ).
In urmatoarea postare, vom analiza cateva dintre cele mai bune practici pentru a va asigura ca widget-ul dvs. ofera o experienta buna pentru utilizatori si cum sa va imbunatatiti widgetul cu o activitate de configurare.








