Witaj Sieciowy Szperaczu :)
Wiedz, że nie znajdziesz tutaj kodów źródłowych ani poradników jak kodzić dobre i przemyślane aplikacje na Androida.

Za to zobaczysz moje wolne przemyślenia, porady i pomysły. Dowiesz się też z czym miałem problemy, które napotkałem podczas swojej przygody z 'Andkiem' oraz, co ważniejsze, ich rozwiązania.

poniedziałek, 25 lipca 2011

Przerwa...

Nie wiem czy mam wielu czytelników, ale jak niektórzy zauważyli póki co jest mały przestoj w blogowaniu. Spowodowane jest to problemami zdrowotnymi. Jak tylko wrócę do zdrowia blog znów będzie na bieżąco ;)

Take care Androids :)

piątek, 24 czerwca 2011

Androidowa Adaptacja, czyli Adapter i getView

'Ciekawe' pomyślałem, bo z jednej strony to dobrze, a z drugiej źle. Tak to już jest, wszystko ma plusy i minusy. No ale 'osochozi'?

Dzisiaj robiłem sobie prostą listę, którą podpiąłem do widoku jako ListView. Oczywiście nie chciałem aby wyglądała standardowo, dlatego musiałem stworzyć własny Adapter, a dokładniej ArrayAdapter. Miała to być lista z ikonkami po boku:

1
public class MyIconAdapter extends ArrayAdapter<Object>

Potem należało nadpisać metodę getView i wpisać dowolny kod.

1
2
@Override
public View getView(int position, View convertView, ViewGroup parent)

I w tym momencie, nareszcie, dochodzimy do meritum tego posta :)
Jeśli lista jest zbyt długa, żeby wyświetlić ją na ekranie to podczas przesuwania ekranu za każdym razem, dla kolejnych elementów wywoływana jest metoda getView! Czyli każdy element jest 'generowany' na bieżąco, a po starcie aplikacji wczytywane są tylko elementy widoczne.

Może parę słów dlaczego? Otóż programiści Androida w ten sposób wyłuskują ograniczenie zjadania pamięci, niepotrzebnych obliczeń, a co za tym idzie, również mniejsze zużycie baterii. Dobry pomysł! Chociaż przy listach większych gabarytów potrafi przymulić ;)

czwartek, 23 czerwca 2011

Zmiany

Dziś wpis bez kodzenia, co dla niektórych może być bajeczne, cudowne, fajne, kapitalne, nadzwyczajne, rewelacyjne, zajebiste, wyśmienite, zjawiskowe, a dla innych kiepskie, liche, marne, niedobre, ułomne lub złe (każdy może wybrać odpowiedni epitet).

Małe zmiany na blogu, poprawa wyglądu, a co ważniejsze - od dziś, do każdego wpisu będę się starał robić jakieś mniej lub bardziej zabawne grafiki, które, mam nadzieję, urozmaicą bloga. Dodałem już kilka i na dziś to powinno wystarczyć :)

Trzymajcie się, o ile jesteście.

poniedziałek, 20 czerwca 2011

Size - czy liczy się rozmiar?



Tak! :)

Rozmiar się liczy, przynajmniej w Androidzie. Ekran zazwyczaj jest stosunkowo niewielki (wykluczając tablety), a co za tym idzie, o miejsce trzeba dbać i dobrze zarządzać wielkościami.
Pewnie nie każdy zdaje sobie sprawę ile jest rodzajów jednostek, które możemy wykorzystać (no bo przecież można wszystko ustawiać w pikselach).
A ja zgłębiłem trochę ten temat i przybliżę ten temat Wam. Oto rodzaje wielkości w Androidzie:


  • px - Piksele (Pixels) - jednostka odnosząca się do wielkości jednego piksela na ekranie urządzenia
  • in - Cale (Inches) - liczone od fizycznego rozmiaru ekranu
  • mm - Milimetry (Millimeters) - j.w. - liczone od fizycznego rozmiaru ekranu
  • pt - Punkty (Points) - jest to 1/72 cala liczona na podstawie fizycznego rozmiaru ekranu
  • dp - gęstość niezależnych pikseli? (Density-independent Pixels) - jednostka abstrakcyjna liczona na podstawie zagęszczenia ekranu (fizycznie rzecz biorąc). Jednostka ta odnosi się do 160dpi, czyli 1dp to jedna plamka na ekranie 160dpi. Wartość ta jest zmienna w zależności od ekranu, jednak trzeba uważać, bo nie zawsze jest przeliczana proporcjonalnie.
  • sp - pixele ustalane w zależności od skali (Scale-independent Pixels) - coś na podobieństwo dp, ale jest skalowane w zależności od ustawień czcionki użytkownika. Zalecane podczas podawania wielkości czcionek! Wtedy wielkość czcionki jest ustanawiana na podstawie zagęszczenia (dpi) i ustawień czcionki użytkownika.


Dlatego warto pamiętać, aby rozmiar tekstu definiować w sposób następujący:
1
2
3
4
5
6
<TextView  
    android:id="@+id/label"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:textSize="44sp"
    />

Przykłady możecie znaleźć tutaj.


sobota, 18 czerwca 2011

OnItemClick czy OnItemSelected ?



No właśnie, jak to jest z tymi dwiema metodami?
  • OnItemClick 
  • OnItemSelected
Obie nadpisujemy implementując ich interfejsy (OnItemClickListener i OnItemSelectedListener)
OnItemClick możemy napisać w ten sposób:

1
2
3
4
5
6
7
8
OnItemClickListener onItemClickListener = new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
    long itemId) {
   ((TextView)findViewById(R.id.selection)).setText("Wybrales - "+items[position]);
   
  }
 };

OnItemSelected z kolei tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
OnItemSelectedListener onItemSelectedListener = new OnItemSelectedListener() {

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position,
        long itemId) {      
      ((TextView)findViewById(R.id.selection)).setText("Wybrales - "+items[position]);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
      ((TextView)findViewById(R.id.selection)).setText("Nic nie wybrales");
    }
  };

I teraz pytanie: która z tych metod zostanie kiedy 'uruchomiona'?


czytając 'Android: Beginning 2' w przykładach znajdujemy użycie 'onItemSelected' np. na Grid'zie, aby coś zrobić po dotknięciu elementu w siatce. To nie zadziała. Po części.

Kiedy dotykamy elementu zostaje wywołana metoda 'onItemClick', bo jest to kliknięcie, a nie zaznaczenie.

Aby dostać się do 'onItemSelected' musimy element zaznaczyć, użyć np. trackball'a, którego dodaje HTC do niektórych modeli telefonów, nie wiem jak jest z 'selectowaniem' na innych urządzeniach. w inny sposób nie udało mi się wywołać tej metody dotykając ekranu.

wtorek, 14 czerwca 2011

setContentView(R.layout.main); a ListActivity

Kolejny dzień, kolejny problem.
Co się stało? Chcąc pobawić się adapterami w Androidzie, po napisaniu kodu aplikacja cały czas się wysypywała, nie wiedzieć dlaczego, skoro kod był prosty, czysty i przejrzysty.
Moja główna klasa dziedziczyła po ListActivity zamiast Activity, co za tym idzie, przy osadzaniu listy w widoku, w ten sposób:




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MainActivity extends ListActivity {
 TextView selection;
 String[] items = {"lody", "burak", "cos", "Cluedo", "lampka", "wazon",
       "inne", "samochod"};
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                        
        setListAdapter(new ArrayAdapter<String>(
             this, 
             android.R.layout.simple_list_item_1, 
             items));        
                               
    }
}


Dlaczego kod nie działa? Dziwnym trafem, którego póki co nie jestem w stanie wytłumaczyć, wadzi tutaj setContentView(R.layout.main);. Kiedy się pozbędziemy tego, wszystko jest OK.
Rozwiązanie
Wszystko się wyjaśniło. W pliku odpowiedzialnym za widok (layout/main.xml):
1
2
3
4
5
6
7
<ListView 
 android:id="@android:id/list"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:drawSelectorOnTop="true"
 > 
</ListView>

Należy tutaj pamiętać, aby naszemu ListView nadać id o wartości: android:id="@android:id/list". Trzeba to zrobić, aby klasa dziedzicząca po ListActivity wiedziała, który ListView jest tym głównym. Bez tego ani rusz. Sprawa rozwiązana :)

poniedziałek, 13 czerwca 2011

View - główna klasa kontrolek widoku

Jak zapewne część z Was wie (a część nie :)) większość części składowych widoku (Button, TextView, EditText, CheckBox, itp.) dziedziczy po klasie View.

Taka postać rzeczy daje nam do dyspozycji przydatny, a nie wszystkim znany wachlarz metod:

  • setEnabled - ustawia czy obiekt 'jest włączony'
  • isEnabled - sprawdzamy czy 'jest aktywny' 
  • requestFocus - próbujemy ustawić focus na danym obiekcie
  • isFocused - i sprawdzamy czy obiekt dostał focus
  • getParent - pobieramy rodzica obiektu lub kontener
  • findViewById - znajdujemy obiekt po ID (zazwyczaj R.id.jakisId)
  • getRootView - znajdujemy korzeń drzewa (np.: to co przekazaliśmy do aktywności poprzez 'setContentView()')