2 android gui

Upload: milan-surbatovic

Post on 02-Mar-2016

37 views

Category:

Documents


1 download

DESCRIPTION

android

TRANSCRIPT

  • Android letnja kola - GUI -

    */63

    Elementi GUIKomponente (view, widgets, home-screen widgets)Raspored (layouts)Dogaaji (events)Resursi (resources)MenijiPozivanje drugih aktivnostiDijaloziAdapteriAsyncTask

    */63

    ViewsViewGroup je osnovna klasa za layout kontejnere koji sadre View elemente kao svoju decu i odgovorni su sa njihov raspored na ekranuView je osnovni element za pravljenje korisnike sprege. To je pravougaoni objekat na ekranu odgovoran za iscrtavanje sadraja i obradu dogaajaView komponente su organizovane u strukturu poput stablaView komponente mogu biti definisane u XML deskriptoru ili run-time

    */63

    WidgetsKomponente korisnikog interfejsa:za forme (TextView, Button, ToggleButton, itd.)tekstualna polja (EditText,DatePicker, itd.)kompozitna polja (ListView, GridView, itd.)napredne (SurfaceView, ZoomControls)Problem sa terminologijom: home-screen widgets su specijalne komponente koje se nalaze na radnoj povrini (home-screen ili desktop)

    */63

    Komponente za formeZa interakciju sa korisnikomTextView ispisuje tekstButton je dugmeToggleButton je dugme sa unutranjim stanjem (ukljuen/iskljuen)CheckBox, RadioButtonSpinner ekvivalent ComboBox komponente (drop down)RatingBar za prikaz rejtinga u vidu zvezdicaProgressBar za prikazivanje napretka

    */63

    Button, ToggleButtonDugme je objekat klase ButtonReakcija na pritisak dugmenta se definie oslukivaem:btnBig.setOnClickListener(new OnClickListener() { public void onClick(View v) { // OVDE SE PIE KOD KOJI REAGUJE NA PRITISAK }});Alternativan nain reakcije je da se u layout datoteci doda atribut android:onClick=mojaMetoda" u tagu Button (koji opisuje dugme), a da se u aktivnosti napravi metoda:public void mojaMetoda(View view) {Stanje ToggleButton komponente se moe saznati:tglBtn.isChecked()

    ComponentExamples

    */63

    SpinnerSpinner spinner je padajuci meni (Combo Box). Sastoji se od zaglavlja koje prikazuje trenutno odabranu opciju i prozora koji prikazuje sve opcije (sadrzaj).ArrayAdapter Adapter povezuje podatke sa grafickim elementom. U sluaju Spinner-a, povezuje podatke iz programa sa prikazom u Spinner-u.onItemSelectedListener callback funkcija u kojoj se reaguje na odabir elementa Spinner-a.

    */63

    Tekstualna poljaEditText ima 30-tak varijanti. Atribut inputType definie te vrste:textPasswordtextEmailAddresstextMultiLinedateAutoCompleteTextView nudi mogunost automatskog dopunjavanja teksta, na osnovu spiska reiMultiAutoCompleteTextView nudi mogunost automatskog dopunjavanja vie rei, na osnovu spiska i na kraju rei dodaje delimiter

    */63

    AutoCompleteAutoCompleteTextViewtextView koji ima spisak pojmova za auto completeMultiAutoCompleteTextViewnasleuje AutoCompleteTextView, ali omoguuje da se vie sugestija prikazuje u tekst polju, jedna za drugom (odvojene zadatim delimiterom)ako odaberemo sugestiju, sistem e sam dopisati i delimiter, i opet e biti spreman na nove sugestijepraktino, to je AutoCompleteTextView, kojim je mogue uneti vie sugestija razdvojenih delimiterom

    */63

    AutoCompleteTextViewprivate static final String[] COUNTRIES = new String[] { "Belgium", "Bulgaria", "France", "Italy", "Germany", "Spain", "Sweden"};private void setAutoComplete() { ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES); AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); textView.setAdapter(adapter);}*

    */63

    MultiAutoCompleteTextViewprivate static final String[] COUNTRIES = new String[] { "Belgium", "Bulgaria", "France", "Italy", "Germany", "Spain", "Sweden};private void setMultiAutoComplete() { ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES); MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.multiAutoCompleteTextView1); textView.setAdapter(adapter); textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());}*

    */63

    Kompozitna poljaScrollView ukljuuje skrolovanje ako broj komponenti preraste veliinu ekranaList View prikazuje podatke kao listuGrid View tabelarni prikaz podatakaWeb View prikazuje web straniceGallery prikazuje slikeGoogle Map View prikazuje Google mapu

    */63

    ScrollViewAko nam je broj komponenti toliki da ne mogu sve da stanu na ekran, kao roditelj se postavlja ova komponentaMoe da ima samo jedan podelement, a to je neki od rasporedaScrollViewLinearLayoutTextViewTextView,...ListViewExamples

    */63

    ListViewMoze da prikazuje staticke podatke ili iz baze podataka ili neeg treegMetoda setListAdapter povezuje ListView sa podacimaonListItemClick callback funkcija koja se poziva kad se klikne na element listeListActivity Activity namenjen prikazivanju podataka u listiListViewExamples

    */63

    Prikaz podatakaPrikaz podataka iz liste moe da se uradi koristei predefinisane sistemske komponente:this.setListAdapter( new ArrayAdapter(this,android.R.layout.simple_list_item_1,names));Alternativno, moe se napraviti layout sa dva elementa: ListView za prikaz elemenata(@android:id/list) iTextView za poruku kada je lista prazna ("@android:id/empty)

    */63

    GridViewPrikazuje stavke u vidu tabelePuni se preko adaptera:gv.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1, PLANETS));OnItemClickListener.onItemClick() se poziva kada se tapne na stavkuGridViewExamples

    */63

    WebViewKomponenta koja prikazuje web sadraj (HTML stranice)po definiciji nije ukljuen JavaScript, nema kontrole koje postoje u browser-ima i ignorie grekeako je potrebna potpuna funkcionalnost browser-a, preporueno je da se startuje pravi browser:Uri uri = Uri.parse("http://www.example.com");Intent intent = new Intent(Intent.ACTION_VIEW, uri);startActivity(intent);WebViewExamples

    */63

    WebViewStranica se uitava pozivom metode loadUrl():web.loadUrl(http://www.google.com);Obavezno ukljuiti dozvolu za pristup internetu u AndroidManifest.xml:

    */63

    WebViewDinamiki generisan tekst se moe uitati u ovu komponentu upotrebom loadData() metode:String summary = "Hello World.";webview.loadData(summary, "text/html", "utf-8");

    */63

    VideoViewSlui za prikaz animacijaLokacija animacije se podeava pozivom metode setVideoURI():video.setVideoURI(Uri.parse("android.resource://com.rtrk.videoview/raw/famous"));Animacija se startuje pozivom metode start()

    VideoViewExamples

    */63

    VideoViewKontrole se dodaju instanciranjem MediaController klase:video.setMediaController(new MediaController(this));Metoda setOnCompletionListener() postavlja oslukiva dogaaja zavretka animacije

    */63

    GalleryKontrola koja reprezentuje galeriju slikaPuni se preko adaptera

    GalleryExamples

    */63

    Gallerypublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Gallery galery = (Gallery)findViewById(R.id.gallery1); ia = new ImageAdapter(this); galery.setAdapter(ia); image = (ImageView)findViewById(R.id.imageView1); galery.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View arg1, int index, long arg3) { Toast.makeText(getBaseContext(), "You have selected picture " + (index+1) + " of Antartica", Toast.LENGTH_SHORT).show(); image.setImageResource(ia.pics[index]); } }); }*

    */63

    ImageAdapterpublic class ImageAdapter extends BaseAdapter { private Context ctx; int imageBackground; Integer[] pics = { R.drawable.antartica1, R.drawable.antartica2, R.drawable.antartica10 };... @Override public View getView(int arg0, View arg1, ViewGroup arg2) { ImageView iv = new ImageView(ctx); iv.setImageResource(pics[arg0]); iv.setScaleType(ImageView.ScaleType.FIT_XY); iv.setLayoutParams(new Gallery.LayoutParams(150,120)); iv.setBackgroundResource(imageBackground); return iv; }...}*

    */63

    Home-screen widgetsKomponente koje se nalaze na desktopu ureajaInstaliraju se i smetene su na desktopNe izvravaju se unutar desktop aplikacije, ve nezavisnoda ne bi oborili desktop proces svojom grekomSistem moe da proziva ovu komponentu periodino

    */63

    LayoutsKlase za prostorni razmetaj komponenti na ekranuJedna aktivnost moe da ima jedan ili vie layout-amogu se kombinovati (jedan layout unutar drugog)LayoutExamples

    */63

    Layouts

    Linear Layout Relative Layout Table Layout Tab Layout

    */63

    FrameLayoutZa prikaz jedne komponente, preko celog ekrana

    */63

    LinearLayoutSlae komponente jednu do druge, horizontalno ili vertikalnoOpcionim atributom android:orientation = "vertical podeavamo orijentacijuPrilikom dodavanja komponente u LinearLayout, atributi android:layout_width i android:layout_heigth definiu irinu i visinu komponentematch_parent (nekadanji fill_parent) iskoristi sav raspoloiv prostorwrap_content nemoj da iskoristi sav prostorlayout_weight suma svih teina je 1; pojedinana teina definie procentualni udeo u dimenzijamaPomeranje komponente od neke od ivica (u pikselima) se definie atributom:android:padding=2dip

    */63

    LinearLayoutGravitacija (android:gravity), koji se moe shvatiti kao alignmenttop ili bottom postavi objekat u vrh/dno konejnera, bez promene dimenzijaleft ili right postavi objekat u levo/desno u konejneru, bez promene dimenzijacenter_vertical stavi u vertikalnu sredinu, bez promene dimenzijafill_vertical neka komponenta naraste vertikalno dok ne popuni kontejnercenter postavi u centar (i vert. i horiz.) bez promene dimenzija

    */63

    RelativeLayoutStavke se pozicioniraju relativno jedna u odnosu na druguIgnorie gravity atributSledei atributi kao vrednost imaju id komponente u odnosu na koju se pozicioniraju: layout_below, layout_above, i sl. definiu poziciju u odnosu na navedenu komponentu (layout_below=@id/textView)layout_toRightOf, layout_toLeftOflayout_alignTop, layout_alignRight

    */63

    TableLayoutOmoguuje tabelaran prikaz komponentiKomponente se u tabelu dodaju vrstu po vrstu (unutar TableRow taga)poravnanje komponente u eliji se definie android:gravity atributomkoliko komponenti stavimo u ovaj tag, toliko elija imamoMerge prostora dve komponente se odrauje atributom: android:layout_span="2" Komponente se slau u elije po redosledu (s leva na desno)ako je potrebno komponentu staviti u neku drugu eliju od one na koju je red, to se podeava atributom:android:layout_column=2

    */63

    TabLayoutKlasa TabActivity nasleuje Activity i slui kao osnovna klasa u kojoj e biti TabSa stanovita dizajna, TabHost je osnovna komponenta koja prima TabWidget (za tabove) i FrameLayout (za sadraj tekueg taba)Klasa TabSpec definie karakteristike tabova (naziv, ikona)

    */63

    DogaajiAndroid aplikacije reaguju na dogaaje korisnikog interfejsaDodir (tap) po kontroli se pretvara u dogaaj koji registruje odgovarajui oslukiva (Listener)Na primer, tap po dugmetu e biti uhvaen na sledei nain:btnFrame.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // OVDE SE PIE REAKCIJA NA DOGAAJ }});

    */63

    ResursiFolder res u projektu sadri resurseResursi mogu biti:animacije folder animliste boja kojee se koristiti folder colormultimedija (slike, animacije, itd.) folder drawableostali fajlovi folder rawandroid.resource://com.rtrk/raw/famousxml fajlovi koji opisuju prostorni raspored komponenti na ekranu Aktivnosti folder layoutImena fajlova u res folderu se piu malim slovima (uz eventualno znak _)

    */63

    MeniOptions Menu meni koji se poziva sistemskim dugmetom za menijecallback metoda onCreateOptionsMenu(menu) slui za dodavanje stavki menijacallback metoda onMenuItemSelected(featureId, menuItem) se poziva kada korisnik odabere opciju iz menijaContext Menu ekvivalent popup menijametoda registerForContextMenu(getListView()) prijavljuje kontekstni meni za zadatu komponentucallback metoda onCreateContextMenu(menu, view, contextMenuInfo) slui za dodavanje stavki menijacallback metoda onContextItemSelected(menuItem) se poziva kada korisnik odabere opciju iz kontekstnog menijaMenuExamples

    */63

    Options menuKako se dodaju stavke:@Overridepublic boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, OPTIONS_MENU_ADD_ID, 0, R.string.options_menu_add); return true;}

    */63

    Options menuKako reagujem na odabir stavke:@Overridepublic boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case OPTIONS_MENU_ADD_ID: // TODO return true; } return super.onMenuItemSelected(featureId, item);}

    */63

    Kontekstni meniIniciranje kreiranja kontekstnog menija:registerForContextMenu(komponenta); ako je aktivnost nasledila ListActivity, onda se iniciranje radi ovako:registerForContextMenu(getListView());Kako se dodaju stavke? public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.v3_menu_delete);}

    */63

    Kontekstni meniKako da saznam na koju stavku se odnosi kontekstni meni?U metodi onContextItemSelected(menuItem):AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();Log.d("V3", "Id stavke: " + info.id + ", pozicija: + info.position);

    */63

    PreferencesAplikacija moe da sadri inicijalne podatke koji se mogu sistemski itati i editovatixml fajl sa inicijalizacionim podacima: res/xml/prefs.xmlitanje:SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);String username = preferences.getString("username", "n/a");Runa izmena :Editor edit = preferences.edit(); String username = preferences.getString("username", "n/a");edit.putString("username", new_value); edit.commit();

    PreferencesExamples

    */63

    Pozivanje aktivnostiAktivnost se poziva kreiranjem Intent-a i pozivanjem jedne od dve sledee metode:startActivity(Intent intent) ilistartActivityForResult(Intent intent, int requestCode)Ako se pozove prva metoda, ne oekuje se rezultat radaPozvana aktivnost moe da eksplicitno da zavri rad pozivom finish() metode, mada je za to dovoljno pritisnuti Back dugme na ureaju

    */63

    Pozivanje aktivnostiKako da aktivnost prenese neto pozvanoj aktivnosti?Object o = this.getListAdapter().getItem(position);selectedCity = o.toString();Intent i = new Intent(this, AnotherActivity.class);i.putExtra("com.rtrk.v3.CITY", selectedCity);startActivityForResult(i, EDIT_ID);Kako da pozvana aktivnost dobije podatke?Bundle extras = getIntent().getExtras();city = extras != null ? extras.getString("com.rtrk.v3.CITY"): null;

    */63

    Poziv sa rezultatomAko se pozove druga aktivnost sa rezultatom, oekuje se da ona vrati status operacije i tada se u glavnoj aktivnosti pie callback rutina:protected void onActivityResult(int requestCode, int resultCode,Intent intent)Iz pozvane aktivnosti, pre povratka se postavlja resultCode i, opciono, kreira se povratni Intent koji moe da sadri rezultat rada:Intent i = new Intent();Bundle b = new Bundle();city = editCity.getText().toString();b.putString("com.rtrk.v3.CITY", city);i.putExtras(b);setResult(RESULT_OK, i);finish();

    povratni Intent

    */63

    Glavna aktivnost kupi rezultat rada preko onActivityResult callback metode:@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { ... }}Poziv sa rezultatom

    */63

    DijaloziZa kratku komunikaciju sa korisnikompozadinska aktivnost gubi fokus. Dialog preuzima kontroluVrste dijaloga:custom dijalozi sami pravimo GUIpredefinisani dijalozi Android nudi nekoliko standardnih tipova dijalogaPredefinisani dijalozi:AlertDialogpoziva se metodom Activity.showDialog(ID)callback metoda onCreateDialog(ID) kreira dijalog i vraa referencu metodi showDialog(ID), ime se prikazuje dijalogProgressDialogmetoda setProgress(int) podeava trenutnu vrednostDialogExamples

    */63

    Custom DialogsIzgled se podesi u odgovarajuem xml fajlu unutar res/layout folderaNasledi se klasa Dialog i u konstruktoru se podesi izgled (setContentView() metoda)Iz glavne aktivnosti se kreira i pozove dijalog:bd = new BigDialog(this);bd.show();Ako je potrebno da se reaguje na dogaaj korisnikog interfejsa, iz glavne aktivnosti se piu odgovarajui oslukivai:Button btnClose = (Button)bd.findViewById(R.id.btnDialogBigClose);*

    */63

    Predefinisani dijaloziKreiranje dijaloga uz pomo builder-a:AlertDialog.Builder builder = new AlertDialog.Builder(main_activity);builder.setMessage("Are you sure you want to DELETE city + getListAdapter().getItem(info.position) + "?");builder.setCancelable(false);builder.setPositiveButton("Yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Toast.makeText(ComplexAppActivity3.this, "DELETING city + l.getItem(info.position), Toast.LENGTH_LONG).show(); }});builder.setNegativeButton("No, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); }});dialog = builder.create();

    */63

    ObavetenjaStatus Bar Notificationporuka u statusnoj linijitap po poruci je uklanja, a moe i da pozove neku aktivnostToast tekst koji se prikazuje na ekranu kratko vremestatika metoda makeText(roditelj, tekst, duina) vraa referencu na Toast sa porukomstatika metoda show() prikazuje poruku*

    */63

    AdapteriAdapteri povezuju komponente sa kolekcijama podatakaobino povezuju komponente koje listaju ili prikazuju vie od jednog podatka (liste, spineri, itd.)

    */63

    Punjenje adapteraVie naina:statika lista iz resursaniz stringova (objekata) iz programadinamiki, iz programa

    */63

    Punjenje adaptera iz resursaU res/values folderu se napravi xml datoteka:

    Mercury Venus

    Kreira se adapter na osnovu statikog teksta:ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_list_item_1);listView.setAdapter(adapter);ListViewExamples

    */63

    Punjenje adaptera nizomNapravi se ArrayAdapter koji se puni nizom:private static final String[] COUNTRIES = new String[] { "Belgium", "France", "Italy", "Germany", "Spain" };...ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, COUNTRIES);listView.setAdapter(adapter);

    */63

    Punjenje adaptera kolekcijomNapravi se ArrayAdapter koji se puni nizom:ArrayList cities = new ArrayList(); cities.add(Novi Sad);cities.add(Beograd); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, cities);listView.setAdapter(adapter);

    */63

    Predefinisane definicije izgleda jednog redaAndroid poseduje velik broj predefinisanih definicija izgleda jednog reda u listama ili spineru (android.R.layout):activity_list_itembrowser_link_context_headerexpandable_list_contentlist_contentpreference_categoryselect_dialog_itemselect_dialog_multichoiceselect_dialog_singlechoicesimple_dropdown_item_1linesimple_expandable_list_item_1simple_expandable_list_item_2

    */63

    Predefinisane definicije izgleda jednog redaAndroid poseduje velik broj predefinisanih definicija izgleda jednog reda u listama ili spineru (android.R.layout):simple_gallery_itemsimple_list_item_1simple_list_item_2simple_list_item_activated_1simple_list_item_activated_2simple_list_item_checkedsimple_list_item_multiple_choicesimple_list_item_single_choicesimple_selectable_list_itemsimple_spinner_dropdown_itemsimple_spinner_itemtest_list_itemtwo_line_list_item

    */63

    Kolekcije objekatata ako imamo kolekciju objekata, a ne stringova?lista bi trebalo da ima vie kolonaza to je poeljno da se napravi custom izgled (res/layout/jedan_red.xml)za to je potreban custom ArrayAdapternasledi se ArrayAdapter i redefinie se metoda getView()ova metoda vraa jedan red listeadapter = new CityAdapter(this,R.layout.v22_row, cities);this.setListAdapter(adapter);

    */63

    Kolekcije objekatapublic class CityAdapter extends ArrayAdapter {public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; CityHolder holder = null; if(row == null) { LayoutInflater inflater = ((Activity)context).getLayoutInflater(); row = inflater.inflate(textViewResourceId, parent, false); holder = new CityHolder(); holder.txtViewZip = (TextView)row.findViewById(R.id.textZip); holder.txtViewName = (TextView)row.findViewById(R.id.textName); row.setTag(holder); } else holder = (CityHolder)row.getTag(); City city = cities.get(position); holder.txtViewZip.setText(city.getZipCode()); holder.txtViewName.setText(city.getName()); return row; }}

    */63

    Auriranje GUI i dugotrajna obradaSvaka reakcija na dogaaj korisnikog interfejsa se odvija u programskoj niti koja obrauje dogaaje (UI thread)ako u reakciji na dogaaj napiemo kod koji se dugo izvrava, blokiraemo aplikaciju (nee reagovati na dogaaje korisnikog interfejsa)Reenje:korienje standardnih Java niti (klasa Thread)mana ne moe da aurira korisniki interfejs (na primer progress bar)ako je potrebno da se aurira GUI, koristi se klasa Handlerkoristi se klasa AsyncTask, koja omoguuje da se kod izvrava paralelno sa UI thread nitiAsyncTaskExamples

    */63

    Standardne nitiAuriranje GUI se mora raditi preko Handler klase:handler.post(new Runnable() { @Override public void run() { pBar.setProgress(count); }});GUI se ne sme aurirati bez Handler klase!

    */63

    Klasa AsyncTaskNasledi se klasa AsyncTask i redefinie se barem doInBackground() metoda:@Overrideprotected Integer doInBackground(Integer... params) { int start = params[0]; for (int i = start; i