piątek, sierpnia 06, 2010

AppInventor - pierwsze wrażenia i pierwsze programy :-)

Dostałem 2 dni temu czy jakoś tak zaproszenie do Google AppInventor for Android.
Zacząłem się bawić i zacząłem pracować nad projektem, który "obiecałem" w swojej aplikacji o konto [nie wiem czy akurat "za to" mi przyznali konto, bo kilka razy na ten adres próbowałem uzyskać zaproszenie [na inne też ;-)]], czyli postanowiłem spróbować napisać tą samą aplikację przy pomocy AppInventor'a i Java'y i porównać wrażenia.

Programem będzie Plan Lekcji.

Layout wersji dla AppInventora wygląda tak:



Idea jest taka, by po kliknięciu w guziczek u góry pokazywała się lista wyboru z nazwami dni tygodnia, a po wybraniu którejś z wartości pokazywać się będzie zapisana w bazie pod kluczem z nazwą tygodnia "notatka" będąca planem lekcji na dany dzień. Plan lekcji będzie pokazywał się w polu tekstowym pod guziczkiem do wyboru.
Danych dostarczy użytkownik klikając na odpowiedni dzień, wpisując dane w polu tekstowym i klikając na Save.

Kod AppInventorowy aplikacji wygląda tak:



Program "mówi":
po wybraniu opcji z listy wyboru (ListPicker1) ustaw tekst wyświetlany przez listę wyboru na wybraną opcję,
następnie ustaw zawartość pola tekstowego (TextBox1) przy pomocy wartości pobranej z bazy (TinyDB1) spod klucza równego wybranemu z listy (ListPicker1) tekstowi (tak naprawdę temu co wyświetla lista jako wybraną opcję, ale to to samo dzięki wcześniejszemu krokowi),
w końcu ustaw nazwę okna (Screen1) na wybrany tekst.

oraz:

W momencie przyciśnięcia guzika (Button1) zapisz do bazy (TinyDB1) pod kluczem równym wybranej z listy wyborów opcji (ListPicker1) treść z pola tekstowego (TextBox1).

Banał, prawda? :-)

Jest "małe" ale, w obecnej wersji AppInventor'a jest błąd, powodujący, że pobieranie z bazy wartości spod kluczy pod które nigdy nic nie zapisano wyrzuca błąd:



Mają to naprawić w tym lub przyszłym tygodniu :-)

Dlatego dla testu dodałem jeszcze jeden guziczek, który będzie inicjalizował naszą bazę.



Tu już jest trudniej niż w poprzednich blokach programu.
Najpierw mamy użycie pętli forEach, czyli "dla każdego", w tym przypadku dla każdego var z elementów naszej listy z dniami tygodnia (ListPicker1) zapisujemy do bazy (TinyDB1) pod kluczem będącym nazwą dnia tygodnia (w zmiennej var) nazwę tego dnia (z tej samej zmiennej).

Czas wykonania: Trudno powiedzieć dokładnie, ale nie więcej niż 30 minut :-) i to tylko przez to, że to "pierwszy raz".
Rozmiar: trochę ponad 1MB.
Poziom trudności: bardzo łatwy
Wymagana wiedza: niewielka

Działająca aplikacja nie jest zbyt piękna ;-)



Ale działa :-)
Dla mnie jako dla programisty wykonanie tej aplikacji było banalne, dla zwykłego człowieka powinno nie być zabójczo trudne :-)

Teraz wersja w Java'ie :-)

Zaczynamy od Layout'u:


Nasza aplikacja składa się z dokładnie 1 aktywności, w której jedyny istotny kod jest w metodzie onCreate():
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
List<String> list = Arrays.asList("Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday".split(","));
final Spinner spinner = (Spinner)findViewById(R.id.Spinner01);
final EditText editText = (EditText)findViewById(R.id.EditText01);
final SharedPreferences prefs = getSharedPreferences("plan", Context.MODE_PRIVATE);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
String str = (String)spinner.getSelectedItem();
String content = prefs.getString(str, str);
editText.setText(content);
PlanLekcji.this.setTitle(str);
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String str = (String)spinner.getSelectedItem();
String content = editText.getText().toString();
prefs.edit().putString(str, content).commit();
}
});
}


I to by było na tyle ;-)

Wygląda tak:


Wg. mnie lepiej :-)

Rozmiar: niecałe 15KB.
Czas wykonania: około 15-30 minut, z "kradzieżą" kodu z moich innych projektów.
Poziom trudności: dużo wyższy niż w przypadku AppInventora.
Wymagana wiedza: Po pierwsze trzeba znać Java'ę, ale także API, trzeba też wiedzieć jak zainicjalizować listę wyboru dni, co takie oczywiste nie jest.

Program w Java'ie wykorzystuje łącznie 3 klasy, jedną główną PlanLekcji, oraz 2 anonimowe.

Na samym końcu wersja w HTML5, która powinna działać też np. na iPhone'ie czy iPad'zie ;-) (ale nie działa na moim G1 :-( bo w nim nie ma HTML5)

Która wygląda tak [tutaj, zrzut z ekranu emulatora udającego Nexus One]:



Ładna nie jest, choć faktem jest, że jej uładnienie byłoby najprostsze, bo w HTML'u mamy niemal pełną kontrolę nad layoutem strony.

Kod źródłowy wygląda tak:
<html>
<body>
<script>
function change(elem) {
var str = localStorage[elem.value];
if (str==null) {
str = elem.value;
}
document.getElementById("content").value=str;
}
function save() {
var str = document.getElementById("select").value
var content = document.getElementById("content").value;
localStorage[str]=content;
}
</script>
<select id="select" onchange="change(this)">
<option>Monday</option>
<option>Tuesday</option>
<option>Wednesday</option>
<option>Thursday</option>
<option>Friday</option>
<option>Saturday</option>
<option>Sunday</option>
</select><br />
<textarea id="content" rows="10" cols="10"></textarea><br />
<button onclick="save()">Save</button>
</body>
</html>


Rozmiar: 713 bajtów
Czas wykonania: 10 minut [mnie to tyle zajęło!]
Trudność: łatwe
Potrzebna wiedza: znajomość HTML/JavaScript.

A teraz sekcja downloadów :-)
Plan Lekcji w wersji z AppInventora [1MB]
Plan Lekcji w Java'ie [15KB]
Plan Lekcji w wersji HTML
"Źródła" wersji z AppInventor
Źródła wersji w Java'ie

Podsumowując, jak na razie AppInventor nie wprowadza rewolucji dla programistów, ale daje w ręce trochę bardziej zwykłych ludzi narzędzie do tworzenia prostych programików prostą metodą drag&drop. Robi to niestety kosztem ograniczenia funkcjonalności i wpływu na wygląd aplikacji wynikowej. Ma też jak na razie trochę błędów. Np. wspomniany już tu błąd działania TinyDB, oraz błąd polegający na złym odczytywaniu danych z akcelerometru :-)
Jeszcze kilka miesięcy i będzie to potężne narzędzie do zabawy, a może i do pracy :-)

[prawie 3 w nocy i mi się spać chce ;-)]


Podobne postybeta
Czy ustalanie pozycji w Androidzie może kosztować?
"Kodowanie" na Chrome OS ;-)
Jak "okradłem" Google Readera ;-)
AppInventor - tego się da używać :-)
Python for Android vs. AppInventor - 2:0 ;-)