Farklı farklı ekran boyutlarını destekleyen bir uygulama tasarlarken, birçok esnekliği beraberinde getiren Fragment'ları kullanabilirsiniz. Farklı layout yapılandırmaları sayesinde kullanılabilecek ekran alanını en verimli şekilde kullanabilir ve kullanıcı deneyimini artırabilirsiniz.
Örneğin avuca sığan bir telefonda tek bölmeli bir tasarımla sadece bir Fragment göstermek isteyebilirsiniz. Aynı şekilde daha geniş ekranlı bir tablette kullanıcıya daha fazla bilgi göstermek için Fragment'ları yan yana kullanabilirsiniz.
Resim 1: Farklı boyuttaki ekranlardaki iki Fragment, aynı Activity'nin içinde farklı ayarlamalarla gösteriliyor. Geniş ekranda Fragment'lar yan yana gelebiliyorken bir avuç büyüklüğündeki telefon gibi cihazlarda tek seferde tek Fragment gösteriliyor. Böyle ufak ekranlarda olası bir kullanıcı etkileşiminde gösterilen Fragment'ı diğer Fragment ile yer değiştirmek kullanıcı deneyimi açısından iyi olacaktır.
Gelelim Fragment kullanırken olmazsa olmaz FragmentManager sınıfına. FragmentManager sınıfı, dinamik bir kullanıcı deneyimini sağlayabilesiniz diye çalışma zamanı (runtime) sırasında bir Activity'ye Fragment ekleme, çıkarma, yer değiştirme gibi işlemleri yapmanıza olanak sağlar. Şimdi ayrıntılarına bakalım.
Çalışma zamanında bir Fragment'ı Activity'ye Eklemek
Fragment'ları doğrudan <fragment> elementi şeklinde XML layout dosyaları içerisinden Activity'ye eklemenin dışında, çalışma zamanı sırasında da Activity'ye ekleyebilirsiniz. Böyle bir işleme, Fragment'ları istediğiniz zaman ekleyip çıkaracağınız zaman ihtiyaç duyarsınız.
Fragment eklemek ya da çıkarmak gibi bir işlemi (transaction) gerçekleştirmek için mutlaka FragmentManager'ı kullanarak bir FragmentTransaction oluşturmalısınız. FragmentTransaction size fragment ekleme, çıkarma, yer değiştirme ve diğer fragment işlemlerini gerçekleştirmenizi sağlayan API'ler sunar. Adı üstünde, Fragment işlemi yapmanızı sağlar.
Activity'nizin Fragment'ları çıkarabilmesini ya da yer değiştirebilmesini sağlamak istiyorsanız, Activity'nin onCreate() metodu sırasında ilk olarak istediğiniz Fragment(ları) ekleyebilirsiniz.
Fragment'lar ile çalışırken dikkat etmeniz gereken bir kural da (özellikle çalışma zamanında ekleyerek kullandığınız Fragment'lar için) Fragment'ın yer alacağı layout'un mutlaka bir taşıyıcı (container) View üzerinde olması gerektiğidir. Bir başka deyişle şöyle açıklayabiliriz: Ekleme-çıkarma yapacağınız Fragment'ları doğrudan Activity'ye bir yere eklemek istiyorsanız bunun için bir yer açmalısınız ve o yer bir View nesnesi olmalı. Aşağıdaki örneklerde bu yer bir FrameLayout olarak karşınıza çıkacak.
Aşağıdaki layout, bir önceki içerikte sözünü ettiğimiz "tek seferde tek fragment gösteren" layout'a alternatif bir layout'tur. Bir Fragment'ı diğeriyle yer değiştirmek için Activity'nin layout'unda Fragment taşıyıcısı gibi davranan boş bir FrameLayout olması gerekir.
Örneği incelemeye başlamadan önce gözünüzden kaçmasını istemediğimiz bir şey var: Bu örnekteki layout dosyalarının ismi bir önceki derstekiyle aynı ancak layout dizini "large" son ekini içermiyor. Bu layout, tek seferde iki fragment sığmayan, geniş ekrandan daha ufak ekranı olan cihazlar için tasarlanmıştır.
res/layout/news_articles.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity'nizin içindeyken getSupportFragmentManager() metodunu kullanarak bir FragmentManager nesnesi elde etmelisiniz. Tüm bunlar Anroid Destekleme Kütüphanesi API'leri ile gerçekleştireceğimiz işlemler. Ardından beginTransaction() metodunu kullanarak bir FragmentTransaction nesnesi oluşturuyoruz ve add() metoduyla da fragment'ı FrameLayout'un olduğu yere ekliyoruz.
NOT: Eğer uygulamanız API 11 ve sonrasını hedef alıyorsa getSupportFragmentManager() metodu yerine getFragmentManager() metodunu kullanmanız yeterli.
Bu arada Activity'de birden fazla Fragment üzerinde işlem gerçekleştirmek için aynı FragmentTransaction nesnesini kullanabilirsiniz. Buradaki işleriniz bittiğinde tüm değişiklikleri kullanıcıya göstermek için commit() metodunu çağırmanız gerekir.
Şimdi yukarıda anlattıklarımızı kod bloğunda görelim. Yukarıdaki FrameLayout içine (adı fragment_container idi) bir fragment ekleyelim:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
// Activity'nin fragment_container isimli FrameLayout'u olan
// bir layout'u kullandığını doğrulayalım; o an başka bir
// kaynak (resource) dizinindeki içinde fragment_container
// olmayan başka bir layout kullanıyor olabilir
if (findViewById(R.id.fragment_container) != null) {
// Eğer Activity'yi önceki durumundan (state) geri
// dönüştürüyorsak bir şey yapmamıza gerek yok ve
// doğrudan return yapabiliriz. Veyahut üst üste gelen
//Fragment'ların icabına bakabiliriz
if (savedInstanceState != null) {
return;
}
// Activity layout'unun içinde yer alacak yeni bir Fragment oluşturalım
HeadlinesFragment firstFragment = new HeadlinesFragment();
// Activity'miz Intent'ten gelen özel verilerle başlatılmış
// olabilir. Bu nedenle (örnek olması açısından) Intent'in
// ekstra verilerini Fragment'a argüman olarak geçiriyoruz
firstFragment.setArguments(getIntent().getExtras());
//Fragment'ı ‘fragment_container' isimli FrameLayout'a ekliyoruz
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}
Fragment, çalışma zamanı sırasında FrameLayout taşıyıcısına eklenebildiğinden dolayı, Activity, o Fragment'ı aynı zamanda kaldırabilir veya başka biriyle yer değiştirebilir. Şimdi bunu nasıl yapabileceğimize bakalım.
Bir Fragment'ı diğeriyle yer değiştirmek
Bir Fragment yer değiştirme işlemi aynı Fragment eklemeye benziyor. Sadece add() metoduyla değil, replace() metoduyla yapılıyor.
Şu detaya dikkatimizi yoğunlaştıralım: Fragment'lar üzerinde gerçekleştirilen ekleme-çıkarma gibi işlemleri, kullanıcının geriye dönme veya yaptığı işlemi geri alma gibi işlemlerde sıkça kullanabilirsiniz. Kullanıcının Fragment işlemleri arasında geriye dönebilmesini sağlamak için FragmentTransaction'ı commit() metoduyla çalıştırmadan önce mutlaka addToBackStack() metodunu çağırmalısınız.
NOT: Bir Fragment'ı yer değiştirdiğinizde veya kaldırdığınızda ve bu işlemi "back stack" denilen yere eklediğinizde fragment kaldırılır ve durur (yok edilmez). Kullanıcı Fragment'ı geri dönüştürerek geriye dönerse o Fragment yeniden başlatılır. Eğer işlemi "back stack"e eklemezseniz, Fragment kaldırıldığında veya yer değiştirildiğinde yok edilir.
Aşağıda bir Fragment'ı diğeriyle yer değiştirme işlemini örnekle görebilirsiniz:
// Fragment'ı oluşturalım ve göstereceği makaleyi
// (article) ona argüman olarak verelim
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// fragment_container layout'u içinde o anki
// Fragment ile istediğiniz bir fragment'ı yer
// değiştirin ve bu işlemi back stack'e de ekleyin
// ki kullanıcı geri döndüğünde önceki Fragment'ı görebilsin
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// yapacak bir şey kalmadı. işlemi FragmentManager'a teslim ediyoruz
transaction.commit();
addToBackStack() metodu yapılan işlemi ifade eden eşsiz bir string parametresini isim olarak alır. Eğer FragmentManager.BackStackEntry API'leriyle ileri seviye Fragment işleri yapmayacaksanız işleme bir isim vermenize gerek olmayacaktır. Yukarıdaki kodda bu yüzden null parametresi geçilmiştir.
Bu sayfadaki parçalar Android Open Source Project kapsamında oluşturulmuş ve paylaşılmış içeriğin küçük değişiklikler yapılmış hâlidir ve Creative Commons 2.5 Attribution License'ta belirlenen koşullara göre kullanılmıştır.
Bu eğitim içeriğinin orijinal hâline buradan ulaşabilirsiniz: Building a Flexible UI