Kod Dünyası

1 Nisan 2015 Çarşamba

Bu dersimizde Tab Layoutu  resimler, kodlar ve örneklerle destekleyerek anlatacağım.

Tab Layout

Tab layout adından da anlaşılacağı üzere tabların kullanıldığı şablondur. Örneğimizle daha iyi anlayacaksınız. Örneğimiz 3 tane tab içerecek, tabların kendilerine ait isimleri ve simgeleri olacak. Ve de tabların kendi içerikleri de olacak. Örneğimizin emulatör çıktısı şöyle olacak: 

tablayout

Gerekli Adımlar:

1. Yeni bir proje oluşturup (1. derste anlatmıştım.) adına TabLayout diyoruz.

2. activity_main.xml dosyasına aşağıdaki kodu girin. 

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>
    </LinearLayout>
</TabHost>

3. Aşağıda verdiğim fotoğrafları /res/drawable-hdpi dosyasına kaydedin, isimleri sırasıyla:home, music, photos olmalı.

  home   music    photos

4. res altındaki layout klasörüne sağ tıklayıp 3 tane yeni android xml dosyası açın, isimleri şöyle olmalı: home.xml, music.xml, photo.xml (sıra önemli değil) Sırasıyla bu xml dosyalarına aşağıdaki kodları girin.

home.xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/anaSayfaView"
        android:layout_width="185dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.19"
        android:text="ANASAYFA İÇERİK"
             android:textSize="20dp" />

</LinearLayout>

music.xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/muzikView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MÜZİK İÇERİK" 
             android:textSize="20dp"/>

</LinearLayout>

photo.xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/fotoView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FOTOĞRAF İÇERİK"
        android:textSize="20dp" />

</LinearLayout>

5. drawable-hdpi klasörü altına üç tane android xml dosyası açın. Sırasıyla şu isimleri verin: hometab, musictab, phototab. Ve aşağıdaki kodları girin:

hometab.xml 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/home"
          android:state_selected="true" />

    <item android:drawable="@drawable/home" />
</selector>

musictab.xml 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/music"
          android:state_selected="true" />
    <item android:drawable="@drawable/music" />
</selector>

  phototab.xml 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/photos"
          android:state_selected="true" />
    <item android:drawable="@drawable/photos" />
</selector>

  6. Madem 3 farklı tabımız olacak o zaman 3 tane farklı .java dosyamız olmalı, çünkü biz bu üç tabın içinde farklı şeyler olsun istiyoruz. src klasörü altındaki paket dosyanıza sağ tıklayarak üç tane yeni sınıf oluşturun isimleri şöyle olsun: HomeActivity.java, MusicActivity.java, PhotoActivity.java Sırasıyla aşağıdaki kodları girin:

HomeActivity.java 

package com.androidhocam.tablayout;import android.app.Activity;
import android.os.Bundle;public class HomeActivity extends Activity {@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.home);}}

MusicActivity.java 

package com.androidhocam.tablayout;import android.app.Activity;
import android.os.Bundle;public class HomeActivity extends Activity {@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.home);}}

PhotoActivity.java 

package com.androidhocam.tablayout;import android.app.Activity;
import android.os.Bundle;public class PhotoActivity extends Activity {@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.photo);}}}

7. Şimdi de MainActivity.java dosyasında tabları ve tabların isimlerini oluşturup tabhost a ekleyeceğiz. Aşağıdaki kodu MainActivity.java dosyasına girin. 

package com.androidhocam.tablayout;import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;public class MainActivity extends TabActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);TabHost tabHost = getTabHost();TabSpec homespec = tabHost.newTabSpec("Anasayfa");
homespec.setIndicator("Anasayfa", getResources().getDrawable(R.drawable.hometab));
Intent videosIntent = new Intent(this, HomeActivity.class);
homespec.setContent(videosIntent);TabSpec photospec = tabHost.newTabSpec("Fotoğraflar");photospec.setIndicator("Fotoğraflar", getResources().getDrawable(R.drawable.phototab));
Intent photosIntent = new Intent(this, PhotoActivity.class);
photospec.setContent(photosIntent);TabSpec songspec = tabHost.newTabSpec("Müzik");
songspec.setIndicator("Müzik", getResources().getDrawable(R.drawable.musictab));
Intent songsIntent = new Intent(this, MusicActivity.class);
songspec.setContent(songsIntent);

tabHost.addTab(homespec);
tabHost.addTab(photospec);
tabHost.addTab(songspec);

}
}

8. Şimdi de 6. adımda ek olarak oluşturduğumuz aktiviteleri AndroidManifest.xml dosyasına activite olarak giriyoruz. Şu kodları manifeste ekleyin: 

 <activity android:name=".PhotoActivity" />
        <activity android:name=".HomeActivity" />
        <activity android:name=".MusicActivity" />

9. Herşey hazır, şimdi projemize sağ tıklayıp Run as -> Android Application diyoruz. Sonuç aşağıda görülüyor.

Tab Layout Emülatör Çıktısı 


tablayout

Not: Bu yazı Android Evreni kurucusu ve yazarı Mustafa DEMİR tarafından yazılmıştır.

Kodları indirmek ve dersin kaynağına ulaşmak için tıklayınız.

31 Mart 2015 Salı

Animasyon(Animation) sınıfı android.view.animation paketi altında bulunur. Bunu şu şekilde kontrol edebilirsiniz: Eclipse te oluşturduğunuz herhangi bir projenin dosyalarında Android'in bir sürümü vardır. Bu sürümün altında android.jar adlı dosyayı göreceksiniz. Buna tıklayıp altındaki paketlerden söylediğim paketi bulup Animation.class dosyasını görebilirsiniz. 

animation_class_android  


Animasyon Kaynakları (Animation Resources)

Android teki animasyon kaynakları iki türdür. Bunlar: 
1. Özellik Animasyonu (Propery Animation) 
2. Görüntü Animasyonu (View Animation)

Özellik Animasyonu (Propery Animation) 
Adından da anlaşılacağı üzere ; burada bir nesnenin özelliklerini değiştirerek animasyon oluşturuyoruz. Burda Animator lar kullanılır. Sonraki derslerim anlatacağım bu animasyon türünü.

Görüntü Animasyonu (View Animation)
Bu türde ise bir nesnenin (genellikle resim) görüntüsüne ait özellikleri değiştirerek animasyon oluşturuyoruz. Örnekle daha iyi anlayacaksınız, sabırlı olun. :) 

Uygulama Örneğimiz: Örneğimizde bir buton ve bir imageview nesnesi olacak. Kullanıcı butona dokunduğu zaman gösterilen resim aynı anda  hem büyüyecek hem de dönücek. 

Yazının devamını okumak ve kodları indirmek için: Devamını Oku

30 Mart 2015 Pazartesi

Bu yazımda sizlere servis kullanımını anlatmaya çalışacağım. Servis kullanarak uygulamanıza arka planda çalışacak özellikler ekleyebilirsiniz. Bu yazıda yazacağımız uygulama arka planda çalışacak ve düzenli aralıklarla ekrana sistem tarihini ve saatini yazdıracak.

ServisOgreniyorum isimli bir proje oluşturarak işe başlayalım.

Projeyle beraber oluşturduğumuz ana etkinliğin tasarımını yaparak işe başlayalım. Servisi durdurup başlatmak için bir düğme ekleyelim. Layout dosyamız aşağıdaki gibi görünmeli.
Kullanacağımız metinleri belirlediğimiz strings.xml dosyamız da şöyle görünmeli.
Şimdi servis sınıfımızı oluşturalım. Ana etkinlik dosyamızdan bir kopya oluşturup içeriğini aşağıdaki gibi değiştirelim.
Projemizin temelleri hazır. Şimdi ana etkinliğimizi açıp servisi başlatıp durdurmakla ilgili kodları yazarak başlayalım.

İlk iş olarak eklediğimiz düğmenin tıklama olayını oluşturalım.
Bu düğmeye tıklandığında servis durdurulmuş haldeyse servis başlatılacakbaşlatılmış haldeyse durdurulacak. Bunun için servisin çalışıp çalışmadığını kontrol etmemiz gerekiyor. Haydi bunun için bir metod yazalım.
Bu metod çağrıldığında eğer servisimiz çalışıyorsa geriye true döndürülecek. Eğer çalışmıyorsa false döndürülecek.

Bunun için bir ActivityManager nesnesi oluşturup sistemin etkinlik servisini alıyoruz. Java'nın gelişmiş for döngüsü yapısını kullanarak getRunningServices() metodu ile sistemde çalışan tüm servisleri alıyoruz. Bu metodun döndürdüğü RunningServiceInfo nesnelerinden oluşan dizi içinde servis isimli değişken ile dönüyoruz. Döngü sırasındaki servis nesnesinin paket adı, bizim uygulamamızın paket adına eşitse bizim servisimiz çalışıyor demektir. Bu mantığı kullanarak tüm çalışan servisleri geziyoruz ve bizim servisimiz çalışıyor mu kontrol ediyoruz.

Şimdi tıklama metodumuzun içini dolduralım ve yazdığımız metodu da kullanalım.
Temel mantık bu şekilde olacak. Servis başlatılacağı zaman ilgili metod çağrılacak ve düğmenin üzerindeki yazı durdur yazısına çevrilecek. Servis durdurulacağı zaman da tam tersi yapılacak.

Oluşturduğumuz tıklama olayının parametresi (daha önceki yazılarda bahsettiğim gibi) üzerine tıklanan nesneyi temsil ettiği için v nesnesini Button türüne dönüştürerek dugme ismiyle saklıyoruz. Daha sonra bu nesne üzerinden yazı değişikliğini yapıyoruz.

Tıklama olayımızın kodları bittiğinde aşağıdaki gibi görünmeli.
Şimdi etkinliğin onCreate() metoduna da bir ekleme yapalım. Servis arka planda çalışacağı için servisin çalışıp çalışmama durumuna göre uygulama başlangıcında düğmenin üzerindeki yazıyı belirlememiz gerekiyor. Bunun için aşağıdaki gibi bir ekleme yapıyoruz.
Şimdi servisimizin kodlarını yazalım.

İlk önce düzenli aralıklarla iş yapmak için bir Timer nesnesi ve servis içinden ekrana Toast ile yazı yazabilmek için birHandler nesnesi tanımlayalım.
Eksik import bilgilerini Ctrl + Shift + O ile ekleyelim. Burada Eclipse birden fazla Handler sınıfı bulduğu için bize hangisini eklemek istediğimizi soracak. Bizim ihtiyacımız olan android.os.Handler olacak.
Şimdi de zamanlayıcının çalışacağı aralığı bir sabit olarak belirleyelim. Buraya milisaniye cinsinden bir zaman belirtmemiz gerekiyor. (1 sn = 1000 ms) Örneğin ben 10 saniyede bir çalışmasını istedim.
Şimdi servisimiz oluşturulduğunda çalıştırılacak onCreate() metodu içinde bu nesnelerimize ilk değerlerini verelim.

yardimci nesnesine uygulamanın ana Looper nesnesini atıyoruz. Böylece bu Handler nesnesine göndereceğimiz bilgiler, içinde bulunduğumuz sınıf yerine (bu durumda bizim servisimiz) uygulamanın kendisi üzerinde işletilecek. Eğer bunu yapmazsak servis sınıfı içinden Toast nesnesi ile bilgi vermemiz mümkün olmayacak.

Şimdi zamanlayıcımıza bir görev verelim. Bunun için TimerTask türünden bir nesneye ihtiyacımız olacak. Ama biz bunu metod çağrısı içinde bir iç sınıf (inner class) oluşturarak yapacağız. Haydi başlayalım.

zamanlayici nesnemiz üzerinden scheduleAtFixedRate() metodunu çağırıyoruz ve parametre olarak yeni bir TimerTask iç sınıfı oluşturuyoruz. Burada Eclipse'in bize sağladığı imkanlardan faydalanacağız.

zamanlayici yazıp yanına bir nokta koyduktan sonra Eclipse bize kullanabileceğimiz metodları listeliyor. Buradan scheduleAtFixedRate() metodunu seçiyoruz.


Daha sonra ilk parametreye new yazıp bir boşluk bırakıyoruz ve Ctrl + Boşluk tuşlarına basıyoruz. Eclipse bize yazıyor olduğumuz parametreyle ilgili önerilerde bulunuyor. Buradan yeni bir iç sınıf oluşturacağız. Anonymous Inner Type seçeneğini seçiyoruz.

 Gördüğünüz gibi iç sınıfımız oluşturuldu.

Şimdi diğer parametreleri değiştiriyoruz ve metod çağrısını sonlandıran parantezin sonrasına ; işaretimizi koyuyoruz.


Burada yazdığımız ikinci parametre zamanlayıcının ne kadarlık bir gecikmeyle işe başlayacağını, üçüncü parametre ise ne kadar zamanda bir zamanlayıcının tekrar çalışacağını belirtiyor. Ben 0 ms gecikme ile ve daha önce belirlediğim 10 sn zaman aralığıyla çalışması gerektiğini belirttim.

Şimdi bu belirttiğimiz özelliklerle yapılacak işi tanımlayalım. Yazının başında belirttiğim gibi bu uygulama düzenli aralıklarla sistem tarihini ve saatini ekrana yazdıracak.

Şimdi bu iş için bir metod oluşturalım.


Gördüğünüz gibi belirttiğimiz aralıklarla bu metod çağrılacak ve ekranda bilgi gösterilecek.

Şimdi bilgiyi belirli bir biçimde göstereceğiz.

Burada Java'nın sunduğu imkanlardan faydalanacağız. İlk önce sistem zamanını alalım. (Bunu bildirim kullanımını anlattığım yazıda kullanmıştık.)


Şimdi bu zamanı kullanarak istediğimiz biçimde bilgi oluşturacağız. Bunun için SimpleDateFormat sınıfından faydalanacağız. Boş bir SimpleDateFormat nesnesi oluşturduktan sonra istediğimiz biçimi belirliyoruz. (SimpleDateFormat için kullanılabilecek biçimlerle ilgili daha fazla bilgiyi internette bulabilirsiniz, ben detaylara girmeyeceğim.)


Şimdi belirlenen biçimi kullanarak bir bilgi oluşturalım. Bunun için SimpleDateFormat nesnemiz üzerinden format() metodunu çağırıyoruz ve gerekli parametre için sistem zamanını kullanarak oluşturduğumuz bir Date nesnesi veriyoruz.


Artık sonuc isimli String bizim istediğimiz şekilde biçimlenmiş tarih ve saat bilgisini içeriyor. Şimdi bunu ekranda göstereceğiz. Bunun için önceden oluşturduğumuz Handler nesnemiz üzerinden post() metodunu çağıracağız ve parametre olarak Runnable türünde bir iç sınıf oluşturacağız.


Artık Toast kullanarak bilgiyi ekranda gösterebiliriz.


Burada bir hata aldık, Eclipse bize sonuc isimli Stringin final olarak belirlenmesi gerektiğini söyledi. Bunun nedenini tam bilmiyorum, o yüzden detaylı anlatamayacağım. Hatayı bu şekilde çözebiliriz.


İşimiz bitti gibi görünüyor ama aslında bitmedi. :) Şu an uygulamayı çalıştırmaya kalkarsak servis durdurulduğunda hata alacağız çünkü zamanlayıcıyı durdurmadık. Haydi şimdi servis durdurulduğunda olacakları belirleyelim.

Servis sınıfımız içinde onDestroy() isimli metodu Override ederek yeniden yazacağız. Bunun için on yazıp Ctrl + Boşluk yapmanız yeterli. Eclipse size yardımcı olacaktır.


Metodu oluşturduktan sonra içine zamanlayıcıyı durduracak kodu ekliyoruz.


Artık işimiz bitti gibi. Son bir adım olarak yazdığımz bu servisi uygulamanın manifest dosyasına ekliyoruz.

Manifest dosyasını açtıktan sonra Application sekmesine geliyoruz. Application Nodes kısmındaki Add düğmesine tıklayıp Service seçeneğini seçiyoruz.

 Daha sonra yan taraftan Name alanının yanındaki Browse'a tıklıyoruz ve servisimizi seçiyoruz.

Manifest dosyasısnı kaydediyoruz.

Haydi şimdi uygulamamızı deneyelim! :)

Gördüğünüz gibi uygulamamız açıldı ve servis çalışmıyor durumda olduğu için düğmenin üzerinde Servisi Başlat yazıyor.


Düğmeye basıp servisi başlattığımızda istediğimiz biçimde oluşturulmuş tarihi ve saati göreceğiz.

Servis arka planda çalıştığı için uygulamadan çıksak bile belirlediğimiz 10 sn ardından tekrar ekranda tarihi ve saati göreceğiz.
Uygulama listesinden uygulamamızı tekrar çalıştırdığımızda ise servis çalışır durumda olduğu için düğmenin üzerinde Servisi Durdur yazıyor.
Bir yazının daha sonuna geldik.

Bu yazıda sizlere servis kullanımını elimden geldiğince anlatmaya çalıştım. Aslında birkaç özellik daha olacaktı yazdığımız uygulamada ama tuhaf sorunlarla karşılaştım. O yüzden yazıyı daha fazla uzatıp sizleri de sıkmamak adına bu kadar yazıp bitirdim.

Uygulamanın kodlarını buradan indirebilirsiniz.