13 Şubat 2018 Salı

Android Dersleri 7.1 - Fragment nedir, nasıl kullanılır? 3 farklı Fragment çeşidi, Single frame fragments, List fragments , Fragments transaction


7.1 - Fragment nedir, nasıl kullanılır?

https://www.tutorialspoint.com/android/android_fragments.htm
A Fragment is a piece of an activity which enable more modular activity design. ( Fragment, activity'nin bir parçasıdır, kendine ait UIi'ı ve behaviour'ı vardır. Fragment'lar sayesinde daha modular activity design'ları yapabiliriz, örneğin yazdığımız bir fragment'ı birden fazla activity'de kullanabiliriz. )
It will not be wrong if we say, a fragment is a kind of sub-activity. (Fragment'ı activity'nin bir parçası gibi düşünebiliriz farzı misal bir fragment'a subactivity diyebiliriz. )
Fragment'lar hakkındaki bazı önemli notlar şunlardır :
- A fragment has its own layout and its own behaviour with its own life cycle callbacks.( Bir fragment kendi layout'una yani kendi ui'ına sahiptir ve kendine ait bir davranışı vardır, kendine ait lifecycle'ı vardır. )
- You can add or remove fragments in an activity while the activity is running.( Bir activity çalışmaktayken bu activity'ye fragment eklemek/silmek mümkündür. Yani runtime'da bir activity'ye fragment eklenebilir/silinebilir. )
- You can combine multiple fragments in a single activity to build a multi-plane UI.( Bir activity, birden fazla fragment içerebilir, yani bir ekranda farklı fonksiyonları ve farklı ui'ları olan birden fazla birim(fragment) olabilir. )
- A fragment can be used in multiple activities.( Bir fragment, birden fazla activity'de kullanılabilir. )
- Fragment life cycle is closely related to the life cycle of its host activity which means when the activity is paused, all the fragments available in the activity will also be stopped. ( Bir fragment'ın lifecycle'ı, host activity'sinin(yani içerisinde olduğu activity'nin lifecycle'ı) ile yakından ilişkilidir. Örneğin bir activity pause edildiğinde, bu activity'nin içerdiği fragment'lar da pause edilir. )
- A fragment can implement a behaviour that has no user interface component.( Bir fragment'da UI implement edilmeyip sadece behaviour implement edilmesi mümkündür. )
- Fragments were added to the Android API in Honeycomb version of Android which API version 11.

        You can create custom fragments by extending Fragment class and You can insert a fragment into your activity layout by declaring the fragment in the activity's layout file, as a <fragment> element. ( Custom  bir fragment  nasıl yaratabiliriz?
- Fragment class'ını extend eden bir class tanımlarız.
- Fragment class'ının gerekli lifecycle method'larını override ederiz.
- Bir Activity'nin layout dosyasına <fragment> element'i kullanarak, bu fragment'ı activity'ye insert ederiz. )

        Prior to fragment introduction, we had a limitation because we can show only a single activity on the screen at one given point in time. So we were not able to divide device screen and  control different parts separately. But with the introduction of fragment we got more flexibility and removed the limitation of having a single activity on the screen at a time. ( Fragment'ları bilmiyoruz diyelim, bu durumda ekranda sadece single bir activity gösterebilirdik, ekranı ikiye ve üçe bölüp bu parçaları ayrı ayrı kontrol edebilme şansımız olmazdı. Allah'a şükür fragment'lar var ki onların sayesinde bir activity kendilerine ait fonksiyonları ve UI'ları olan subactivity(fragment)'lardan oluşur. Veya bir fragment tanımlayıp birden fazla activity'de tanımladığımız fragment'ı kullanabiliriz. )
        Now we can have a single activity but each activity can comprise of multiple fragments which will have their own layout, events and complete life cycle. (     Single bir activity, birden fazla fragment'dan oluşabilir. Herbir fragment'ın kendi layout'u, kendi event'i, kendi life cycle'ı vardır. )
Örnek :
        Following is a typical example of how two UI modules defined by fragments can be combined into one activity for a tablet design, but separated for a handset design.
        The application can embed two fragments in Activity A, when running on a tablet-sized device. However, on a handset-sized screen, there's not enough room for both fragments, so Activity A includes only the fragment for the list of articles, and when the user selects an article, it starts Activity B, which includes the second fragment to read the article.      (Aşağıdaki örneği inceleyelim. Soldaki resimde bir tablet sağdaki resimde ise bir telefon vardır.
        Bu uygulamayı tablette açtığımızda, tablet ekranı daha büyük olduğu için, single bir activity'de 2 fragment göstereceğiz.
        Bu uygulamayı telefonda açtığımızda ise, telefon ekranı daha küçük olduğu için, single bir activity'de sadece 1 fragment göstereceğiz.
        Soldaki resime bakalım. Burada sadece bir tane activity vardır o da Activity A'dır. Bu activity'ye Fragment A ve Fragment B insert edilmiştir. Soldaki liste Fragment A'dır, sağdaki ise Fragment B'dir. Fragment A'daki listeden bir haber başlığı seçilince Fragment B'de bu haberin içeriği gösterilir.
        Sağdaki resime bakalım.  Burada 2 tane activity vardır : Activity A ve Activity B . Activity A, sadece Fragment A'yı içerir. Activity B, sadece Fragment B'yi içerir. Dolayısıyla telefon ekranında Fragment A'daki yani Activity A'daki listeden bir haber başlığı seçilince, haberin detayını gösteren Activity B sayfası açılır. )

Fragment Life Cycle
        Android fragments have their own life cycle very similar to an android activity. This section briefs different stages of its life cycle. ( Fragment'ların da activity'lerin yaşam döngüsüne benzeyen bir yaşam döngüleri vardır. Bu konuda fragment'ların yaşam döngülerindeki aşamaları öğreneceğiz. )
        Here is the list of methods which you can to override in your fragment class.( Fragment class'ını extend bir class tanımlamıştık. Bu class'da Fragment class'ının şu method'larını override edebiliriz. )
onAttach() : The fragment instance is associated with an activity instance. The fragment and the activity is not fully initialized yet. Typically you get in this method a reference to the activity which uses the fragment for further initialization work. ( Bir fragment object, bir activity ile ilişkilendirilirken örneğin fragment activity'ye insert edilirken bu method çağırılır. Fragment ve activity henüz başlatılmamıştır. )
onCreate() : The system calls this method when creating the fragment. You should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.( Fragment yaratılırken sistem otomatik olarak onCreate() method'unu çağırır. Fragment pause,stop edilirken ve sonra resume edilirken, Fragment'ın tutmak,saklamak istediğimiz önemli bileşenlerini onCreate() method'unun implementation'ında initialize etmeliyiz.  )
onCreateView() : The system calls this callback when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View component from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI. ( Fragment, kendi UI'ını ilk defa çizeceği zaman onCreateView() callback fonksiyonu çağırılır otomatik olarak. Eğer fragment'ın UI'ının ekranda çizilmesini (ve sonraki method'lar çağırıldığında bu UI'ın görünebilir olmasını) istiyorsanız onCreateView() callback fonksiyonunu bir View component return etmelidir, yani bu method'u implement edip bir View component return etmeliyiz. Eğer fragment'ın UI'ı yoksa, sadece behaviour'ı varsa, onCreateView()  method'unda null return etmeliyiz.  )
onActivityCreated() : onActivityCreated() is called after the onCreateView() method when the host activity is created. Activity and fragment instance have been created as well as the view hierarchy of the activity. At this point, view can be accessed with the findViewById() method. example. In this method you can instantiate objects which require a Context object. ( onCreateView() method'u çağırılıp fragment'ın UI'ı çizildikten sonra,bu fragment'ı içeren activity(host activity) yaratılırken onActivityCreated() method'u çağırılır. onActivityCreated() callback fonksiyonu çağırıldıktan sonra, artık activity ve fragment yaratılmıştır, activity'nin view hiyerarşisi de yaratılmıştır. Bu noktada findViewById() method'u çağırılarak bu view'e erişilebilir. Ayrıca bu method'un implementation'ında, Context object gereken object'leri instantiate edebilirsiniz??? )
onStart() : The onStart() method is called once the fragment gets visible. ( Fragment'ın görünür olması için onStart() callback fonksiyonu çağırılır. Yani onStart() çağırıldıktan sonra fragment ekranda görünür olur artık. )
onResume() : Fragment becomes active.( onResume() çağırılınca Fragment ekranda aktif olur, yani focus bu fragment'dadır, bir input girsek bu fragment'ı etkiler. )
onPause() : The system calls this method as the first indication that the user is leaving the fragment. This is usually where you should commit any changes that should be persisted beyond the current user session. ( Fragment veya host activity ekranda yarı görünür olduğunda, onPause() method çağırılır. Kullanıcının uygulamadan ayrılmak üzere olduğunun ilk belirtisi bu method'un çağırılmasıdır, kaybetmek istemediğimiz verileri bu method çağırıldığında kaydetmeliyiz ki kullanıcı bu uygulamayı tekrar açtığında bu veriler kaybolmasın. )
onStop() : Fragment going to be stopped by calling onStop(). ( Fragment tamamen durdurulduğunda yani ekranda tamamen görünmez olduğunda onStop() method'u çağırılır. Fragment tamamen durdurulur. )
onDestroyView() : Fragment view will be destroyed after this method is called. ( Bu method çağırıldığında ekranda çizilmiş olan fragment view yok edilir. )
onDestroy() : called to do final clean up of the fragment's state but Not guaranteed to be called by the Android platform. ( onDestroy() method'u çağırılınca fragment'dan arta kalan tüm atıklar vs. hepsi yok edilip, genel bir temizlik yapılır. Android'in bu method'ı otomatik olarak çağıracağı kesin değildir. Dolayısıyla bu method'un kesinkes çağırılmasını istiyorsak manual olarak çağırmalıyız. )
How to use Fragments?
        İlk olarak kaç tane fragment kullanmak istediğimize karar vermeliyiz. 3 tane fragment kullanmak istiyoruz diyelim.
- Bu durumda Fragment class'ını extend eden 3 tane class tanımlamalıyız, Fragment class yukarıda bahsedilen callback fonksiyonlarına sahiptir, biz kendi tanımladığımız Fragment subclass'ında bu callback fonksiyonlardan ihtiyacımız olanları override ederiz.
- Sonra herbir fragment için yani 3 tane layout dosyası(.xml) oluşturmalıyız, bu dosyalar herbir fragment'ın UI'ını belirler.
- İstediğimiz activity'ye istediğimiz fragment'ı ekleyebiliriz artık, activity'nin layout(.xml) dosyasında <fragment> element'ini kullanarak.

Types of Fragments
        3 çeşit fragment vardır :
1 - Single frame fragments : Single frame fragments are using for hand hold devices like mobiles, here we can show only one fragment as a view.
2 - List fragments : fragments having special list view is called as list fragment
3 - Fragments transaction : Using with fragment transaction. we can move one fragment to another fragment.
Single Frame Fragment
Single frame fragment is designed for small screen devices such as hand hold devices(mobiles) and it should be above android 3.0 version. ( Küçük ekranlı cihazlar için, örneğin mobil telefonlar için Single frame fragment kullanılır. Android 3.0 ve üzerin versiyonlar için geçerlidir. )
      
This example will explain you how to create your own Fragments. Bu örnekte kendi fragment'larımızı tanımlayacağız. 2 tane fragment tanımlayacağız. Cihaz portrait modda iken yani dikey tutulurken bu fragment'lardan biri kullanılacak, landscape modda iken yani yatay tutulurken bu fragment'lardan diğeri kullanılacak. Yani telefon dikey ve yatay pozisyondayken farklı fragment'lar dolayısıyla farklı ui'lar göstereceğiz.
       - MyFragments isimli bir uygulama yaratalım. com.example.myfragments package'ı altında boş bir activity yaratalım bunun adı MainActivity.java olsun.
       - MainActivity class'ında cihazın orientation'ını check edelim, yani cihaz dik mi yatay mı tutuluyor diye bakalım ve buna göre uygun fragment'laı kullanalım.
       - com.example.myfragments package'ı altında Fragment class'ını extend eden PM_Fragment ve  LM_Fragment diye 2 tane class tanımlayalım. Bu class'larda Fragment class'ının gerekli lifecycle callback fonksiyonlarını override edelim.
      - res/layout/lm_fragment.xml ve res/layout/pm_fragment.xml isimli 2 tane layout dosyası oluşturalım. Bu dosyalar biraz önce tanımladığımız 2 farklı fragment'ın layout'ları olarak kullanılacaktır. Soru: fragment class'ları ve fragment layout dosyalarını tanımladıktan sonra bu ikisi arasındaki ilişkiyi nerede kuruyoruz?
      - Projeyi ilk oluşturduğumuzda otomatik olarak yaratılmış olan res/layout/activity_main.xml dosyasını açalım. Bu bizim main activity'mizdir yani uygulama açıldığında gösterilecek olan activity'dir. Bu activity'nin layout dosyasına <fragment> element'ini kullanarak fragment'ları koyalım.
      - res/values/strings.xml dosyasında gerekli string constant'ları tanımlayalım.
      - Uygulamayı çalıştıralım. Ekran dikey tutulduğunda ekranda gözüken activity'de res/layout/pm_fragment.xml layout'u ile tanımlanan fragment kullanılır. Ekran yatay tutulduğunda ekranda gözüken activity'de res/layout/lm_fragment.xml layout'u ile tanımlanan fragment kullanılır.
Aşağıda şu dosyaları tanımlayacağız :
-       MainActivity.java              -  res/layout/activity_main.xml 
-       LM_Fragment.java            - res/layout/lm_fragement.xml 
-       PM_Fragment.java             - res/layout/pm_fragment.xml 
MainActivity isimli class'ın onCreate() method'unda, Configuration class'ından bir object nasıl elde ederiz? getResource().getConfiguration() method'unu çağırarak. config object'in orientation isimli variable'ının değeri Configuration.ORIENTATION_LANDSCAPE mi diye bakarız, öyleyse telefon yatay pozisyonda tutuluyordur. 
       getFragmentManager() method'unu çağırarak FragmentManager object elde ederiz. fragmentManager object'in beginTransaction() method'unu çağırarak fragmentTransaction object'i elde ederiz.
       fragmentTransaction object'in replace() method'u çağırılarak activity ile ilişkilendirilen fragment değiştirilir :
       replace() method'unun 2. parametresi activity ile ilişkilendirilecek olan fragment'ın layout dosyasının ismidir.
        replace() method'unun 1. parametresi olan android.R.id.content nedir?  The android.R.id.content ID value indicates the  ViewGroup of the entire content area of an Activity . android.R.id.content gives you the root element of a view. If you need root view of your activity (so you can add your contents there) use findViewById(android.R.id.content). Bir Activity'nin tüm alanını kapsayan ViewGroup'un id'sidir android.R.id.content. MainActivity class'ı içerisinde android.R.id.content id'si, MainActivity layout'unun yani UI'ının root view'ine karşılık gelir. Yani biz aslında replace method'unu çağırarak şunu yaparız. replace() method'unun 1. parametresinde android.R.id.content olduğu için ve 2.parametresinde ls_fragment olduğu için MainActivity'nin UI'ının tamamının yerine ls_fragment object'in ilişkili olduğu layout olan lm_fragment.xml koyarız.
       fragmentTransaction object ile işimiz bittikten sonra bu object'in commit() method'unu çağırarak yapılan değişiklikleri kaydederiz.
       Tanımladığımız Fragment subclass'larına bakalım. Bu class'larda onCreateView() method'unu override ederiz, bu method'un ne return ettiğine dikkat edelim. Bu fragment'ın view'ini yani layout'unu return etmelidir onCreateView() method'u, bunu nasıl return etmişiz, inflater.inflate(R.layout.lm_fragment, container, false) method'unu çağırarak. onCreateView() method'u, bu fragment'ın layout'ını yani UI'ını belirlemek için override edilir. Bu fragment'ın layout'u lm_fragment.xml olarak belirlenmiştir.
  •         activity_main layout'una 2 tane fragment element eklenmiştir, tanımlanan her 2 fragment da eklenmiştir. Ancak MainActivity class'ında replace() method'u çağırılarak layout'un tümüne sadece 1 fragment layout koyulmaktadır. O halde neden 2 tane fragment koyuldu main layout'a activity_main.xml dosyasında? main layout'a fragment'lar static olarak koyulduğu için bu fragment'lar runtime'da activity'den çıkartılamaz diye okumuştum bir yerde burada neden böyle değil durum bu önemli soruyu cevapla!!! Cevap : MainActivity'de hiçbir layout set edilmediğine dikkat et. Yani bu örnekte activity_main. xml dosyası kullanılmıyor. ) You cannot replace a fragment defined statically in the layout file via a FragmentTransaction. You can only replace fragments that you added dynamically.

src/com.example.mycontentprovider/MainActivity.java :
package com.example.myfragments;
import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.res.Configuration;
import android.view.WindowManager;
public class MainActivity extends Activity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Configuration config = getResources().getConfiguration();
      FragmentManager fragmentManager = getFragmentManager();
      FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

      // Device orientation'ını check et.
      // Device dik mi yatay mı tutuluyor diye bak.
     if(config.orientation==Configuration.ORIENTATION_LANDSCAPE){
       // Cihaz yatay tutuluyorsa bu kod block'u çalışır.
       LM_Fragment ls_fragment = new LM_Fragment();
       fragmentTransaction.replace(android.R.id.content, ls_fragment);
     }
     else
     {
       // Cihaz dik tutuluyorsa bu kod block'u çalışır.        
       PM_Fragment pm_fragment = new PM_Fragment();
        fragmentTransaction.replace(android.R.id.content, pm_fragment);         
     }
   fragmentTransaction.commit();
  } // end of onCreate() implementation   
} // end of MainActivity class implementation
LM_Fragment.java :
package com.example.myfragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LM_Fragment extends Fragment{
   @Override
   public View onCreateView(LayoutInflater inflater,
      ViewGroup container, Bundle savedInstanceState) {
      /**
       * Inflate the layout for this fragment
       */
      return inflater.inflate(R.layout.lm_fragment, container, false);
   }
}
PM_Fragment.java :
package com.example.myfragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class PM_Fragment extends Fragment{
   @Override
   public View onCreateView(LayoutInflater inflater,
      ViewGroup container, Bundle savedInstanceState) {
      /**
       * Inflate the layout for this fragment
       */
      return inflater.inflate(R.layout.pm_fragment, container, false);
   }
}
res/layout/lm_fragment.xml :
<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:background="#7bae16">
  
   <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/landscape_message"
      android:textColor="#000000"
      android:textSize="20px" />

<!-- More GUI components go here  -->
</LinearLayout>
res/layout/pm_fragment.xml :
<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:background="#666666">
  
   <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/portrait_message"
      android:textColor="#000000"
      android:textSize="20px" />

<!-- More GUI components go here  -->
</LinearLayout>
res/layout/activity_main.xml : ( activity_main layout'unda root element olarak LinearLayout kullanılmıştır. Bu layout'un altında 2 tane fragment element vardır. Bu fragment element'lerin id'leri, fragment layout xml dosyalarının ismidir.  )
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="horizontal">

   <fragment
      android:name="com.example.fragments"
      android:id="@+id/lm_fragment"
      android:layout_weight="1"
      android:layout_width="0dp"
      android:layout_height="match_parent" />
   <fragment
      android:name="com.example.fragments"
      android:id="@+id/pm_fragment"
      android:layout_weight="2"
      android:layout_width="0dp"
      android:layout_height="match_parent" />
</LinearLayout>
res/values/strings.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">MyFragments</string>
   <string name="action_settings">Settings</string>
   <string name="hello_world">Hello world!</string>
   <string name="landscape_message">This is Landscape mode fragment</string>
   <string name="portrait_message">This is Portrait mode fragment></string>
</resources>
       Uygulamamızı çalıştıralım.
       Cihazı portrait modda tuttuğumuzda ekran aşağıdaki gibi görünür. Yani activity'de portrait fragment kullanılır.
       Cihazı landscape modda tuttuğumuzda ekran aşağıdaki gibi görünür. Yani activity'de landscape fragment kullanılır.

Virtual device'ımızın (Emulator'ın) orientation'ını değiştirmek için şu kısa yolları kullanırız:
·        ctrl+F11 on Windows.
·        ctrl+F11 on Linux.
       Bu örnekte kullanıcı cihazı dikey de tutsa yatay da tutsa aynı activity gösterilir. Ancak yatay ve dikey tutulunca, aynı activity içerisinde farklı ui ve farklı behaviour kullanılır ve gösterilir, çünkü aynı activity içerisinde duruma göre ya portrait fragment kullanılır ya da landscape fragment kullanılır. Örneğin dikey tutulurken yatay tutulmaya başlanırsa, activity içerisinde kullanılan fragment değiştirilir.

Basic Communication between two fragments ( 2 fragment birbiriyle nasıl iletişim kurar? )

http://stackoverflow.com/questions/13700798/basic-communication-between-two-fragments
        Have a look at the Android deverlopers page: http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface
        Basically, you define an interface in your Fragment A, and let your Activity implement that Interface. Now you can call the interface method in your Fragment, and your Activity will receive the event. Now in your activity, you can call your second Fragment to update the textview with the received value. ( Fragment class'ını extend eden FragA ve FragB isimli bir class tanımlarız.
        FragA class'ında bir inner interface(inner class) tanımlarız. Activity class'ımız, bu interface'i yani FragmentA class'ında tanımladığımız inner interface'i implement etmelidir. Bu örnekte FragA class'ında TextClicked isimli bir inner interface(inner class) tanımlarız. Activity class'ımız, bu interface'i yani FragA class'ında tanımladığımız inner interface'i, yani FragA. TextClicked isimli interface'i implement etmelidir. FragA class'ında tanımladığımız TextClicked isimli inner interface'de sendText() isimli bir method declare ederiz, activity class'ımızda sendText() method'unu implement ederiz. Özetle, FragA class'ında TextClicked isimli bir interface tanımlarız, bu interface'de sendText() isimli bir method declare ederiz. Activity class'ımızda ise TextClicked interface'ini dolayısıyla bu interface'deki sendText() method'unu implement ederiz.
        FragA class'ının sahip olduğu TextClicked() interface'inin FragA class'ının ait olduğu activity'de implement edilip edilmediğini nasıl kontrol edebiliriz, bunu nasıl check edebiliriz. FragA class'ının onAttach() method'unda try-catch block'u içerisinde mCallback = (TextClicked) activity; satırını çağırırız.
        Ayrıca FragA class'ında, TextClicked isimli interface type'ında olan mCallback isimli bir reference variable tanımladık. Bu variable'ın onAttach() method'unda bir object'e refer etmesini sağladık : mCallback = (TextClicked) activity; Sonra bu variable'ı kullanarak TextClicked interface'inin sahip olduğu sendText() method'u çağırılır FragmentA class'ında.
        Özetle, FragA FragB'nin sahip olduğu bir method'u çağırmak istiyor, böylece FragB 'deki bir text'i güncellemek istiyor. Bunun için FragmentA'da TextCLicked isimli bir interface declare edilir. FragmentA'yı içeren activity'de TextClicked isimli interface implement edilir. TexClicked isimli interface'in sahip olduğu method olan sendText() method'u FragA'da çağırılır. sendText() method'unda FragmentManager elde edilir, fragmentManager kullanılarak FragB elde edilir,sonra FragB class'ının updateText() method'u kullanılmaz. )
// You Activity implements your interface
public class YourActivity implements FragA.TextClicked{
    @Override
    public void sendText(String text){
        // Get Fragment B
        FraB frag = (FragB)getSupportFragmentManager(). findFragmentById(R.id.fragment_b);
        frag.updateText(text);
    }
}

// Fragment A defines an Interface, and calls the method when needed
public class FragA extends Fragment{
 
    TextClicked mCallback;
 
    public interface TextClicked{
        public void sendText(String text);
    }
 
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
 
// This makes sure that the container activity has implemented the callback interface. If not, it throws an exception.
        try {
            mCallback = (TextClicked) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement TextClicked");
        }
    }
 
    public void someMethod(){
        mCallback.sendText("YOUR TEXT");
    }
 
    @Override
    public void onDetach() {
        mCallback = null; // => avoid leaking, thanks @Deepscorn
        super.onDetach();
    }
}

// Fragment B has a public method to do something with the text
public class FragB extends Fragment{
 
    public void updateText(String text){
        // Here you have it
    }
}

 https://developer.android.com/guide/components/fragments.html

       A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities). ( Bir activity, birden fazla Fragment içerebilir. Bir fragment birden fazla activity'de kullanılabilir. Fragment'ı, bir activity'nin modular bir kısmı olarak düşünebiliriz, fragment'lar farklı activity'lerde tekrar tekrar kullanılabilirler, modular ve tekrar kullanılabilir kod yazmamızı sağlarlar. Fragment'ların kendilerine ait lifecycle'ları vardır. kendi input'larını alırlar. Activity çalışırken activity'den bir fragment'ı çıkarabiliriz veya activity'ye yeni bir fragment ekleyebiliriz. Fragment'ı bir subactivity gibi düşün. Bir fragment'ı tanımladıktan sonra bu fragment'ı farklı farklı activity'lerde kullanabiliriz.  )

       A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle. For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments.
       However, while an activity is running (it is in the resumed lifecycle state), you can manipulate each fragment independently, such as add or remove them.
       When you perform such a fragment transaction, you can also add it to a back stack that's managed by the activity—each back stack entry in the activity is a record of the fragment transaction that occurred. The back stack allows the user to reverse a fragment transaction (navigate backwards), by pressing the Back button.
       ( Her Fragment mutlaka bir activity içerisinde gömülü olmak zorundadır. Bir fragment'ın yaşam döngüsü host activity'nin(yani fragment'ı içeren, fragment'ın ev sahibi olan, fragment'ı misafir eden activity'nin) yaşam döngüsünden etkilenir. Örneğin, host activity pause state geçince, fragment da pause state'e geçer; host activity destroy edilince(yok edilince), fragment da destroy edilir.
       Buna karşın, bir activity çalışırken yani activity resumed state'de iken herbir fragment host activity'den bağımsız hareket edebilir, her state'de olabilir, yeni bir fragment eklenebilir veya varolan bir fragment çıkartılabilir.
       Bir activity'den başka bir activity'ye geçerken eski activity back stack'a konulur hatırlayalım, sonra geri tuşuna basarsak bir önceki activity back stack'dan getirilirdi hatırlayalım. Bu işlem otomatik olarak yapılır. Fragment'larda da backstack kavramı vardır, ancak bu işlem otomatik olarak değil manual olarak yapılır. Bir fragment'dan başka bir fragment'a geçerken eski fragment'ı back stack'a koyabiliriz. Sonra istediğimiz zaman back stack'dan fragment'ı getirebiliriz. Bu backstack'ı activity yönetir. Backstack sayesinde fragment transaction tersine işler yani geri tuşuna basan kullanıcı önceki fragment'lara geri gelir.      )

       When you add a fragment as a part of your activity layout, it lives in a ViewGroup inside the activity's view hierarchy and the fragment defines its own view layout. You can insert a fragment into your activity layout by declaring the fragment in the activity's layout file, as a <fragment> element, or from your application code by adding it to an existing ViewGroup. However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.
       ( Bir activity'ye bir fragment'ı static olarak nasıl ekleriz? activity'nin layout xml dosyasında fragment element'ini kullanarak.
       Bir activity'ye bir fragment'ı dynamic olarak nasıl ekleriz? .java dosyasında varolan bir ViewGroup'a fragment'ı ekleyerek.
       Fragment'ın bir activity'nin UI'ının parçası olması zorunluluğu yoktur. Bir fragment'ın UI layout'u olmayabilir, sadece behaviour'ı olabilir.)

       This document describes how to build your application to use fragments, including how fragments can maintain their state when added to the activity's back stack, share events with the activity and other fragments in the activity, contribute to the activity's action bar, and more. ( Bu dökümanda şunları öğreneceğiz :
- Uygulamada fragment'ları nasıl kullanacağımızı.
- Fragment'lar activity'nin back stack'ına eklendiğinde fragment'ların state'lerini nasıl sürdürebileceklerini.
- Fragment'ların activity ve fragment'larla nasıl iletişim kuracakları. )

Design Philosophy
       Android introduced fragments in Android 3.0 (API level 11), primarily to support more dynamic and flexible UI designs on large screens, such as tablets. Because a tablet's screen is much larger than that of a handset, there's more room to combine and interchange UI components. Fragments allow such designs without the need for you to manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, you become able to modify the activity's appearance at runtime and preserve those changes in a back stack that's managed by the activity. ( Android, Android 3.0 sürümüyle birlikte fragment'lar geldi. Fragment'ların ortaya çıkış nedeni, tablet gibi daha büyük ekranlı cihazlarda daha dinamik daha esnek UI dizaynları sağlamaktı. Telefon ekranına sığmayan UI'ları tablet ekranında göstermek  rahatlıkla mümkündür. Fragment'lar sayesinde activty'nin layout'unu fragment'lara böleriz, activity'nin görünümünü runtime'da değiştirebiliriz ve bu değişiklikleri backstack'da saklayabiliriz.   )
       For example, a news application can use one fragment to show a list of articles on the left and another fragment to display an article on the right—both fragments appear in one activity, side by side, and each fragment has its own set of lifecycle callback methods and handle their own user input events. Thus, instead of using one activity to select an article and another activity to read the article, the user can select an article and read it all within the same activity, as illustrated in the tablet layout in figure 1. ( Örneğin bir haber uygulaması düşünelim. Ekranda solda haber başlıklarının listesi gösteren bir fragment olsun. Ekranda sağda ise seçilen haber başlığıyla ilgili haberin detayları gösterilsin. Bu iki fragment aynı activity'de yan yana gösterilir ekranda. Herbir fragment, kendi yaşam döngüsü callback method'larına sahiptir, ve kendi input event'lerini handle ederler. Bu sayede, haber başlıklarını ve haber detaylarını ayrı activity'lerde göstermek yerine bir ekranı ikiye böleriz, yani aynı activity içerisinde kullanıcının ekranın solundan haber başlıklarını seçip ekranın solunda seçtiği haberin detaylarını görür. )

       You should design each fragment as a modular and reusable activity component. That is, because each fragment defines its own layout and its own behavior with its own lifecycle callbacks, you can include one fragment in multiple activities, so you should design for reuse and avoid directly manipulating one fragment from another fragment. This is especially important because a modular fragment allows you to change your fragment combinations for different screen sizes. When designing your application to support both tablets and handsets, you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space. For example, on a handset, it might be necessary to separate fragments to provide a single-pane UI when more than one cannot fit within the same activity. ( Herbir fragment tekrar kullanılabilir mobular bir activity bileşenidir. Dolayısıyla fragment'lar birden fazla activity'de kulanılabilirler. Bu çok önemlidir çünkü modular fragment bize farklı ekran size'ları için fragment'ları değiştirebilmemizi sağlar.  Uygulamanızın hem tablet'de hem de telefonda çalışmasını istiyoruz diyelim, aşağıdaki 2 resme bakalım. Soldaki resimde bir tablet sağdaki resimde bir telefon vardır. Tablet ekranında 1 tane activity'de 2 tane fragment vardır, soldaki fragment'dan haber başlığı seçilir, sağdaki fragment'da haberin detayı gösterilir. Telefonda ise haber başlıkları ve haber detayları ayrı activity'lerdeki fragment'larda gösterilir, bir haber başlığı seçilince başka bir activity açılır, bu activity'deki bir fragment'da haberin detayları gösterilir. )
       Figure 1. An example of how two UI modules defined by fragments can be combined into one activity for a tablet design, but separated for a handset design. ( Haber uygulaması tablet'de ve telefonda farklı görünür. Tablet'de aynı activity'de haber başlığı ve haber detayı fragment'ları yan yanadır. Telefonda ise haber başlığı ve haber detayı fragment'ları farklı activity'ler içerisindedir.  )

       For example—to continue with the news application example—the application can embed two fragments in Activity A, when running on a tablet-sized device. ( News uygulaması örneğiyle devam edelim. Tablet-size'ında bir cihazda, Activity A'da 2 tane fragment gömülüdür.  )
       However, on a handset-sized screen, there's not enough room for both fragments, so Activity A includes only the fragment for the list of articles, and when the user selects an article, it starts Activity B, which includes the second fragment to read the article. ( Telefonda ise Activity A haber başlıkları fragment'ını içerir.  Activity B haber detayları fragment'ını içerir.   )
Creating a Fragment
Figure 2. The lifecycle of a fragment (while its activity is running). ( Host activity çalışmaktayken, bir fragment'ın yaşam döngüsü yukarıdaki diagram'daki gibi çalışır. )

To create a fragment, you must create a subclass of Fragment (or an existing subclass of it). The Fragment class has code that looks a lot like an Activity.  It contains callback methods similar to an activity, such as onCreate(), onStart(), onPause(), and onStop().  ( Bir fragment yaratmak için Fragment class'ının veya bir Fragment subclass'ını extend eden bir class tanımlarız. Fragment class'ının implementation'ı Activity class'ının implementation'ına benzer. Fragment class'ı da Activity'nin içerdiği lifecycle method'larına benzer lifecycle method'ları içerir. )
In fact, if you're converting an existing Android application to use fragments, you might simply move code from your activity's callback methods into the respective callback methods of your fragment. (Varolan bir uygulamayı fragment kullanacak bir hale dönüştürmek istiyorsak, activity'nin callback method'larına karşılık gelen, fragment'daki callback method'larını aynı şekilde implement ederiz.  )

Usually, you should implement at least the following lifecycle methods: (Fragment class'ının en azından şu method'larını override etmeliyiz: )
onCreate()
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed. (Sistem fragment'ı yaratırken onCreate() method'unu çağırır. onCreate() method'unun implementation'ındafragment'ın önemli bileşenlerini initialize etmeliyiz, örneğin fragment pause veya stop edildikten sonra tekrar pause edildiğinde fragment'ın sürdürmek istediğimiz bileşenlerini burada initialize ederiz. )
onCreateView()
       The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI. ( Fragment'ın bir ui'ı varsa yani ekranda görünmesini istiyorsak bu method'u mutlaka implement etmeliyiz. Fragment, UI'ını ekranda çizeceği zaman onCreateView() method'u çağırılır. Bir fragment'ın ekranda bir UI'ının olmasını istiyorsak bu method bir View return etmek zorundadır. Fragment'ın onCreateView() method'unda return edilen view fragment'ın layout'unun root view'idir.  )
onPause()
       The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).( Fragment yarı görünür olduğunda diğer bir deyişle kullanıcı fragment'dan çıkmak için ilk adım attığında onPause() method çağırılır sistem tarafından. onPause() method'undan sonra kullanıcı fragment'a geri dönebilir veya uygulamayı terk edebilir. Current user session ile ilgili kaybetmek istemediğimiz verileri onPause() method'unda kaydetmeliyiz, çünkü kullanıcının uygulamayı terk etme ihtimali vardır.  )
       Most applications should implement at least these three methods for every fragment, but there are several other callback methods you should also use to handle various stages of the fragment lifecycle. ( Çoğu uygulamadaki tüm fragment'lar en az bu 3 method'u implement eder. Fragment'ların başka yaşam döngüsü method'ları da vardır, gerek duyulan lifecycle method'ları override edilebilir. )

       There are also a few subclasses that you might want to extend, instead of the base Fragment class: ( Base class olan Fragment'ı extend etmek yerine şu 3 Fragment subclass'larından birini extend etmek isteyebiliriz. )
DialogFragment
       Displays a floating dialog. Using this class to create a dialog is a good alternative to using the dialog helper methods in the Activity class, because you can incorporate a fragment dialog into the back stack of fragments managed by the activity, allowing the user to return to a dismissed fragment.( Dialog yaratmak için Activity class'ındaki dialog helper class'larını kullanmak yerine, DialogFragment class'ını kullanmak iyi bir alternatiftir. Çünkü fragment'ları backstack'a koyabiliriz bu sayede bir önceki dialog fragment'a dönebiliriz. )
Örnek :
ListFragment
       Displays a list of items that are managed by an adapter (such as a SimpleCursorAdapter), similar to ListActivity. ( Bir adapter tarafından yönetilen item listesini gösterir. )
       It provides several methods for managing a list view, such as the onListItemClick() callback to handle click events. ( Bir list view'i yönetmek için ListFragment class'ı birkaç method sağlamıştır bize. Örneğin, onListItemClick() callback method'unu çağırarak listedeki item'lara tıklanınca yapılacak işlemleri handle edebiliriz. )
PreferenceFragment
       Displays a hierarchy of Preference objects as a list, similar to PreferenceActivity. This is useful when creating a "settings" activity for your application. ( Preference object'lerin hiyerarşisini bir liste halinde gösterir. PreferenceActivity'ye benzer. Uygulamanız için bir ayarlar activity'si yaratmak için bu fragment kullanılabilir. )

Adding a user interface

       A fragment is usually used as part of an activity's user interface and contributes its own layout to the activity.( Genellikle bir fragment, bir activity'nin user interface'inin bir kısmı olarak kullanılır ve kendisine ait layout'u activity içerisine gömer. )
       To provide a layout for a fragment, you must implement the onCreateView() callback method, which the Android system calls when it's time for the fragment to draw its layout. ( Bir fragment için bir layout belirlemek istiyorsak, onCreateView() method'unu implement etmek zorundayız. Fragment, layout'unu ekranda çizeceği zaman onCreateView() method'u çağırılır. )
       Your implementation of this method(onCreateView()) must return a View that is the root of your fragment's layout. ( onCreateView() method'unun implementation'ı, fragment'ın layout'unun root'u olan bir view return eder. )
       Note: If your fragment is a subclass of ListFragment, the default implementation returns a ListView from onCreateView(), so you don't need to implement it. ( Eğer ListFragment'ı extend eden bir fragment tanımlıyorsak, onCreateView() method'unu implement etmeye gerek yoktur. Çünkü ListFragment class'ının sahip olduğu onCreateView() method'unun default implementation'ı zaten bir ListView implement eder.)
      
       To return a layout from onCreateView(), you can inflate it from a layout resource defined in XML. To help you do so, onCreateView() provides a LayoutInflater object. ( onCreateView() method'unun bir UI layout'u return etmesini nasıl sağlarız? inflater.inflate() method'unu çağırarak. Bu method'a verdiğimiz ilk argument fragment'ın layout xml dosyasıdır. onCreateView() method'unun 2. parametresini inflater.inflate() method'una 2.argument olarak veririz. )

Örnek :
In the sample below, R.layout.example_fragment is a reference to a layout resource named example_fragment.xml saved in the application resources. For example, here's a subclass of Fragment that loads a layout from the example_fragment.xml file: ( Fragment class'ını extend eden bir class tanımladık. Bu class'da onCreateView() method'unu implement ederiz. Fragment'ın UI'ı example_fragment.xml dosyasında tanımlıdır, bu dosya ismini inflater.inflate() method'una parametre olarak veririz. Artık bu fragment'ın UI'ı example_fragment.xml 'de tanımlanan UI olmuştur. )

public static class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}
      The container parameter passed to onCreateView() is the parent ViewGroup (from the activity's layout) in which your fragment layout will be inserted. ( onCreateView() ve inflater.inflate() method'larının aldığı 2.parameter olan container nedir? fragment'ın UI'ının insert edileceği parent ViewGroup'dur(activity'dir gibi düşünebilirsin). Yani fragment'ın view'i(UI'ının) container isimli ViewGroup'a konulur.  )
      The savedInstanceState parameter is a Bundle that provides data about the previous instance of the fragment, if the fragment is being resumed (restoring state is discussed more in the section about Handling the Fragment Lifecycle). ( onCreateView() method'unun aldığı 3.parameter olan savedInstanceState, bir Bundle'dır. fragment'ın önceki state'i ile ilgili bilgi tutar. )
      The inflate() method takes three arguments:
1 -  The resource ID of the layout you want to inflate.
2 - The ViewGroup to be the parent of the inflated layout. Passing the container is important in order for the system to apply layout parameters to the root view of the inflated layout, specified by the parent view in which it's going.
3 - A boolean indicating whether the inflated layout should be attached to the ViewGroup (the second parameter) during inflation. ( In this case, this is false because the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout. )

Now you've seen how to create a fragment that provides a layout. Next, you need to add the fragment to your activity. ( Bir Fragment'ın nasıl yaratıldığını öğrendik. Şimdi ise bir fragment'ı activity'ye eklemeyi öğreneceğiz. )

Adding a fragment to an activity

      Usually, a fragment contributes a portion of UI to the host activity, which is embedded as a part of the activity's overall view hierarchy. There are two ways you can add a fragment to the activity layout:
1 - Declare the fragment inside the activity's layout file(activity'nin layout xml dosyasında <fragment> element'ini kullanarak activity'ye bir fragment'ı static olarak ekleriz. )
In this case, you can specify layout properties for the fragment as if it were a view. The android:name attribute in the <fragment> specifies the Fragment class to instantiate in the layout. For example, here's the layout file for an activity with two fragments: (fragment'ın element'inin layout property'lerini de xml dosyasında belirtiriz, yani fragment'ımız sanki bir view'miş gibi fragment'ın property'lerini set edebiliriz. Aşağıdaki örnekte 2 tane fragment içeren bir activity'nin layout xml dosyası gösterilmiştir. fragment element'inin android:name attribute'ü ile fragment'ın hangi class'dan instantiate edileceğini belirtiriz. )
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>
      When the system creates this activity layout, it instantiates each fragment specified in the layout and calls the onCreateView() method for each one, to retrieve each fragment's layout. ( Sistem bu activity'nin UI'ını yaratırken, layout xml dosyasında belirtilen bu activity'nin içereceği 2 fragment'ı da instantiate eder, yaratılan 2 fragment object'in onCreateView() method'larını çağırarak fragment'ların UI'larını elde eder. )
      The system inserts the View returned by the fragment directly in place of the <fragment> element. ( fragment object'in onCreateView() method'u otomatik olarak çağırılınca return edilen View, activity'nin UI'ında fragment element'in olduğu yere yerleştirilir. )
      Note: Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). ( Herbir fragment unique bir identifier'a yani unique bir ID'ye sahiptir. Activity restart edilirse, sistem bu id'yi kullanarak fragment'ı bulup restore eder tekrar yükler. Ayrıca bu fragment'ı elde etmek için bu fragment'ın id'sine ihtiyacınız vardır. )
      There are three ways to provide an ID for a fragment: (Bir fragment için unique id nasıl belirleyebiliriz? Bunun 3 farklı yolu vardır. )
1 - Supply the android:id attribute with a unique ID. (fragment element'in android:id attribute'üne unique bir ID vererek. UI'lı bir fragment'ın id'sini android:id kullanarak belirleyebiliriz. UI'sız bir fragment'ın id'sini belirlemek için android:id kullanılamaz )  )
2 - Supply the android:tag attribute with a unique string. (fragment element'in android:tag attribute'üne unique bir string vererek fragment için unique bir id belirleyebiliriz. UI'sız ve UI'lı bir fragment'ın id'sini android:tag kullanarak belirleyebiliriz. Ancak UI'sız bir fragment'ın id'sini android:tag kullanarak belirlemek zorundayız. )
3 - If you provide neither of the previous two, the system uses the ID of the container view. ( Eğer yukarıdaki 2 yoldan birini kullanarak bir fragment'a manual olarak bir unique id sağlamazsa, sistem otomatik olarak devreye girer ve fragment'ın id'sine container view'in ID'sini verir. )
2 - Or, programmatically add the fragment to an existing ViewGroup. ( .java dosyasında bir fragment'ı bir activity'ye dinamik olarak eklemek. Uygulama çalışmaktayken bir fragmant'ı activity'ye dinamik olarak ekleyebiliriz veya çıkartabiliriz. )
      At any time while your activity is running, you can add fragments to your activity layout. You simply need to specify a ViewGroup in which to place the fragment. (Activity çalışırken bir fragment'ı activity'ye ekleyebiliriz veya çıkartabiliriz, yani dinamik olarak fragment ekleme çıkarma yapabiliriz. Fragment'ı hangi ViewGroup'a(activity'ye de diyebiliriz) ekleyeceğimizi belirtiriz.)
       To make fragment transactions in your activity (such as add, remove, or replace a fragment), you must use APIs from FragmentTransaction. (Activity'de fragment transaction yapmak için yani activity'ye fragment eklemek veya activity'den bir fragment'ı silmek veya bir fragment'ı replace etmek için FragmentTransaction class'ı kullanılır. )
      
       You can get an instance of FragmentTransaction from your Activity like this:( Activity class'ında getFragmentManager() method'unu çağırarak FragmentManager object elde ederiz. FragmentManager object'in beginTransaction() method'unu çağırarak FragmentTransaction object
elde ederiz. )

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager. beginTransaction();



      You can then add a fragment using the add() method, specifying the fragment to add and the view in which to insert it. ( Elde ettiğimiz FragmentTransaction object'in add() method'unu çağırarak bir fragment'ı activity'ye ekleyebiliriz.  )
 Örnek :
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
The first argument passed to add() is the ViewGroup in which the fragment should be placed, specified by resource ID, and the second parameter is the fragment to add. ( add() method'unun aldığı ilk parameter, fragment'ın hangi ViewGroup'a örneğin hangi activity'ye ekleneceğini belirtir, bu parameter resource id'dir. 2.parameter, eklemek istediğimiz fragment object'dir.)
      Once you've made your changes with FragmentTransaction, you must call commit() for the changes to take effect. (FragmentTransaction object'de gerekli işlemleri yaptıktan sonra bu değişiklikleri kaydetmek için FragmentTransaction object'in commit() method'unu çağırmalıyız. )

Adding a fragment without a UI

      The examples above show how to add a fragment to your activity in order to provide a UI. However, you can also use a fragment to provide a background behavior for the activity without presenting additional UI. ( Yukarıdaki örneklerdeki yarattığımız ve kullandığımız tüm fragment'ların bir UI'ı vardı. Bu fragment'lar, bir activity'nin UI'nın bir parçası olarak kullanılıyordu. Buna karşın, UI'ı olmayan bir fragment da tanımlayabiliriz, UI'ı olmayan bir fragment activity'nin arka plandaki bir davranış bir iş parçası olarak çalışır. )
      To add a fragment without a UI, add the fragment from the activity using add(Fragment, String tag) (supplying a unique string "tag" for the fragment, rather than a view ID). ( UI'sız bir fragment'ı activity'ye eklemek için add(Fragment, String tag) method'unu çağırırız. add() method'una 2.parameter olarak fragment'ın unique tag'ını veririz dikkat!! fragment'ın layout'u yani UI'ı olmadığı için activity'nin layout XML dosyasında fragment element de yoktur, fragment element olmadığı için fragment'ın id'si android:id attribute'ü ile belirlenmemiştir. UI'sız bir fragment'ın id'si android:tag attribute'ü kullanılarak belirlenir  )
      This adds the fragment, but, because it's not associated with a view in the activity layout, it does not receive a call to onCreateView(). So you don't need to implement that method. ( Bir fragment, activity'nin layout(UI)'undaki hiçbir view ile ilişkili değilse, yani fragment'ın bir UI'ı yoksa onCreateView() method'u çağırılmaz, onCreateView() method'unu implement etmemize de gerek yoktur. Çünkü onCreateView() method'unun fragment için bir layout belirlemek için kullanıldığını hatırlayalım.  )
      Supplying a string tag for the fragment isn't strictly for non-UI fragments—you can also supply string tags to fragments that do have a UI—but if the fragment does not have a UI, then the string tag is the only way to identify it. If you want to get the fragment from the activity later, you need to use findFragmentByTag().(UI'sız bir fragment'ın id'sini sadece android:tag kullanarak belirleyebiliriz. Ancak UI'lı bir fragment'ın id'sini android:tag veya android:id kullanarak belirleyebiliriz. Activity içerisinde findFragmentByTag() method'unu çağırarak fragment'ı elde edebiliriz, bu method'a elde etmek istediğimiz fragment'ın unique tag string'ini argument olarak veririz.  )
      For an example activity that uses a fragment as a background worker, without a UI, see the FragmentRetainInstance.java sample, which is included in the SDK samples (available through the Android SDK Manager) and located on your system as <sdk_root>/APIDemos/app/src /main/java/com/example/android/apis/app/FragmentRetainInstance.java. ( UI'sız bir fragment örneği görmek istiyorsanız, Android SDK Manager ile birlikte gelen SDK örneklerindeki FragmentRetainInstance.java örneğini inceleyebilirsiniz. )

Managing Fragments

      To manage the fragments in your activity, you need to use FragmentManager. To get it, call getFragmentManager() from your activity.  ( Activity'mizde fragmet'ları yönetmek için activity'mizde getFragmentManager() method'Unu çağırarak FragmentManager object elde ederiz. )

Some things that you can do with FragmentManager include: (FragmentManager object'i kullanarak şunları yapabiliriz : )
- Get fragments that exist in the activity, with findFragmentById() (for fragments that provide a UI in the activity layout) or findFragmentByTag() (for fragments that do or don't provide a UI). (findFragmentById() method'unu çağırarak activity'nin içerdiği UI'lı fragment'ları elde edebiliriz. findFragmentByTag() method'unu çağırarak activity'nin içerdiği UI'lı veya UI'sız fragment'ları elde edebiliriz. )
- Pop fragments off the back stack, with popBackStack() (simulating a Back command by the user). back stack nedir? ( popBackStack() method'unu çağırarak back stack'dan fragment'ları çıkartabiliriz. Bunu kullanıcının geri tuşuna bastığı case için yaparız. )
- Register a listener for changes to the back stack, with addOnBackStackChangedListener().(addOnBackStackChangedListener() method'unu çağırarak, back stack'a bir listener kaydedebiliriz. Back stack'da bir değişiklik olursa, back stack'a yeni bir fragment eklenirse veya varolan bir fragment backstack'dan çıkartılırsa veya back stack'daki bir fragment replace edilirse bize haber verilecektir backstack'a listener ile kaydolduğumuz için. )
Performing Fragment Transactions
A great feature about using fragments in your activity is the ability to add, remove, replace, and perform other actions with them, in response to user interaction.
Each set of changes that you commit to the activity is called a transaction and you can perform one using APIs in FragmentTransaction.
You can also save each transaction to a back stack managed by the activity, allowing the user to navigate backward through the fragment changes (similar to navigating backward through activities).
( User interaction'a response olarak activity'ye bir fragment eklenebilir, çıkartılabilir, replace edilebilir. Bu işlemleri yaptıktan sonra activity'ye yaptığımız herbir commit'e transaction denir,FragmentTransaction object kullanılarak bu yapılabilir. Herbir transaction, activity tarafından yönetilen bir back stack'a kaydedilebilir, kullanıcı geri tuşuna basarak activity'lerde geri geldiği gibi fragment'larda da geri gelebilir. )

You can acquire an instance of FragmentTransaction from the FragmentManager like this:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for a given transaction using methods such as add(), remove(), and replace(). Then, to apply the transaction to the activity, you must call commit(). ( Herbir transaction, aynı anda gerçekleştirmek istediğimiz bir veya daha fazla değişikliği içerir. Örneğin, sadece bir transaction, 2 tane fragment ekleyip, 3 fragment çıkartabilir, 1 tanesini replace edebilir. Bu değişiklikleri aynı FragmentTransaction object üzerinde yaptıktan sonra, transaction'ı activity'ye uygulamak için commit() methodU'nu çağırmalıyız. )

       Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.
(fragment transaction'ların back stack'ına bir transaction eklemek için, commit() method'unu çağırmadan önce addToBackStack() method'unu çağırmalıyız. )
For example, here's how you can replace one fragment with another, and preserve the previous state in the back stack:
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();
In this example, newFragment replaces whatever fragment (if any) is currently in the layout container identified by the R.id.fragment_container ID. ( Yukarıdaki örnekte bir fragment bir view ile replace edilir. ExampleFragment class'ından newFragment isimli bir Fragment object yaratılır.
transaction isimli bir FragmentTransaction object yaratılır. transaction isimli object'in replace method'u çağırılır.
fragment_container isimli view'in içerisinde her ne varsa bunun ile newFragment isimli fragment object replace edilir, yani fragment_container isimli view'in içindeki her şey override edilecek newFragment tarafından. )
       By calling addToBackStack(), the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button. (transaction.addToBackStack(null); denilerek, transaction isimli object'e kaydedilen replace transaction işlemi back stack'a koyulur. Bu sayede geri tuşuna basınca önceki fragment'a gelme özelliği sağlanmış olur.   )

       If you add multiple changes to the transaction (such as another add() or remove()) and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the Back button will reverse them all together. (transaction object üzerinde birden fazla değişiklik(ekleme,çıkarma veya replace) yaptıysak, addToBackStack() method'unu çağırınca tüm bu değişikilkler single bir transacation olarak backstack'a koyulur, FragmentTransaction'a hangi sırayla değişiklik yaptımızın bir önemi yoktur, önce ekleme sonra silme veya önce silme sonra ekleme aynı şeydir. addToBackStack() method'unu çağırdıktan sonra commit() method'u çağırılarak değişikilkler gerçekleştirilir. )

The order in which you add changes to a FragmentTransaction doesn't matter, except:
- You must call commit() last
- If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy
( FragmentTransaction'a hangi sırayla değişiklik yaptığımızın bir önemi yoktur, önce ekleme sonra silme veya önce silme sonra ekleme aynı şeydir. Şu sıra ise önemlidir dikkat edilmelidir :
- commit() method'u en son çağırılmalıdır.
- Bir container'a birden fazla fragment ekleyeceksek, hangi fragment'ı önce hangi fragment'ı sonra eklediğimiz önemlidir, sıra önemlidir, fragment'ları hangi sırayla eklediğimiz view hierarchy'de fragment'ların hangi sırayla görüneceğini belirler. )

If you do not call addToBackStack() when you perform a transaction that removes a fragment, then that fragment is destroyed when the transaction is committed and the user cannot navigate back to it.
Whereas, if you do call addToBackStack() when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back. ( Bir fragment'ı bir activity'den silen bir transaction'ı commit() ettik diyelim. Commit etmeden önce addToBackStack() method'unu çağırmadık diyelim. Bu case'de, transaction commit edilince fragment yok edilir, kullanıcı geri tuşunu kullanarak bu fragment'a geri gelemez artık.
Commit etmeden önce addToBackStack() method'unu çağırmışsak, fragment stack'a konulmuştur,  kullanıcı geri tuşunu kullanarak bu fragment'a geri gelebilir.  )

Tip: For each fragment transaction, you can apply a transition animation, by calling setTransition() before you commit.( Herbir fragment transition için, setTransition() method'U çağırılara bir transition animation uygulanabilir. )

executePendingTransactions()

Calling commit() does not perform the transaction immediately. Rather, it schedules it to run on the activity's UI thread (the "main" thread) as soon as the thread is able to do so.
If necessary, however, you may call executePendingTransactions() from your UI thread to immediately execute transactions submitted by commit().
Doing so is usually not necessary unless the transaction is a dependency for jobs in other threads.
( commit() method'unu çağırdığımızda, transaction anında gerçekleşmez. main UI'da yani activity'nin UI thread'inde çalışacak şekilde schedule edilir, yani thread müsait olunca transaction gerçekleşir. Eğer UI thread'in commit() edilen transaction'ları anında gerçekleştirmesini istiyorsak executePendingTransactions() method'unu çağırmalıyız. Eğer diğer thread'lerde işler için bu bir dependency ise kullanmalıyız bu method'u, gereksiz yere kullanmamalıyız. )
Performing Fragment Transactions
Caution: You can commit a transaction using commit() only prior to the activity saving its state (when the user leaves the activity). If you attempt to commit after that point, an exception will be thrown.
This is because the state after the commit can be lost if the activity needs to be restored. For situations in which its okay that you lose the commit, use commitAllowingStateLoss(). ( Bir transaction'ı, activity state'ini kaydetmeden önce commit etmeliyiz, yani kullanıcı activity'den ayrılmadan önce transaction'ı commit etmeliyiz. Aksi takdirde exception olur. )

Communicating with the Activity
       Although a Fragment is implemented as an object that's independent from an Activity and can be used inside multiple activities, a given instance of a fragment is directly tied to the activity that contains it. ( Fragment, Activity'den bağımsız bir object olarak implement edilir. Fragment, birden falz activity içerisinde kullanılabilir. Buna karşın, fragment bağlı olduğu activity'den bağımsız değildir, bağlıdır, onunla haberleşebilir. )

       Specifically, the fragment can access the Activity instance with getActivity() and easily perform tasks such as find a view in the activity layout: ( Fragment object'de, getActivity() method'Unu çağırarak fragment'I içeren activity'yi elde ederiz, activity'yi elde ettikten sonra activity'nin layout'undaki view'leri de kolaylıkla elde edebiliriz. )
Örnek :
View listView = getActivity().findViewById(R.id.list); // fragment object'den, içerisinde olduğu actiivty'deki list id'li view'i elde ederiz.

Likewise, your activity can call methods in the fragment by acquiring a reference to the Fragment from FragmentManager, using findFragmentById() or findFragmentByTag().
( Activity'den fragment'a erişmek için, FragmentManager object'in findFragmentById() veya findFragmentByTag() method'unu çağırırız. )
Örnek:
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

Creating event callbacks to the activity
In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it.
When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.
( fragment içerisinde bir interface declare ederiz. Host activity'de bu interface'i implement ederiz. Bu sayede fragment, activity ile event paylaşabilir(haberleşebilir). Bu fragment, bu interface'deki bir method'u çağırdığında activity bundan haberdar olur ve kendisine gelen bilgiyi diğer fragment'larla paylaşabilir. )
For example, if a news application has two fragments in an activity—one to show a list of articles (fragment A) and another to display an article (fragment B)—then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article.
In this case, the OnArticleSelectedListener interface is declared inside fragment A: ( Bir activity, 2 fragment içerir : FragmentA ve FragmentB. FragmentA haber başlıklarını, FragmentB haber detaylarını içerir.
FragmentA'daki bir haber başlığı seçilince, FragmentA bunu host activity'ye söyler, host activity de bunu Fragment B'ye söyler, böylece Fragment B ilgili haber detayını gösterir. Bu mekanizmayı şöyle kurarız :
FragmentA class'ında OnArticleSelectedListener isimli bir interface declare edilir. )
public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    ...
}

Then the activity that hosts the fragment implements the OnArticleSelectedListener interface and overrides onArticleSelected() to notify fragment B of the event from fragment A.
To ensure that the host activity implements this interface, fragment A's onAttach() callback method (which the system calls when adding the fragment to the activity) instantiates an instance of
OnArticleSelectedListener by casting the Activity that is passed into onAttach():
( Host activity OnArticleSelectedListener interface'ini implement eder ve onArticleSelected() method'Unu override eder.
Host activity'nin bu interface'i implement ettiğinden emin olmak için fragment A'nın onAttach() isimli callback method'unda aşağıdaki kod yazılır. onAttach() method'Unun aldığı parametre olan Activity object OnArticleSelectedListener interface type'ına cast edilmeye çalışır.
Bu, try catch block'da yapılır. )

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    ...
}
If the activity has not implemented the interface, then the fragment throws a ClassCastException.
On success, the mListener member holds a reference to activity's implementation of OnArticleSelectedListener,
so that fragment A can share events with the activity by calling methods defined by the OnArticleSelectedListener interface.
For example, if fragment A is an extension of ListFragment, each time the user clicks a list item, the system calls onListItemClick() in the fragment,
which then calls onArticleSelected() to share the event with the activity:
( Host activity, bu interface'i implement etmemişse, fragment A ClassCastException fırlatır.
Host activity, bu interface'i implement etmişse, mListener isimli variable host activity'deki OnArticleSelectedListener interface'inin implementation'ına refer eder.
Artık fragmentA OnArticleSelectedListener interface'inde tanımlı method'ları çağırabilir, yani host activity ile event share edebilir.
Örneğin, fragment A ListFragment'ı extend eden bir class olsun. Bu durumda kullanıcı listedeki item'lardan birine tıklayınca, fragmentA class'ında tanımlı olan onListItemClick() method'U çağırılır otomatik olarak.
Bu method içerisinde de onArticleSelected() method'u çağırılarak host activity ile event share edilir. )
public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
        mListener.onArticleSelected(noteUri);
    }
    ...
}
The id parameter passed to onListItemClick() is the row ID of the clicked item, which the activity (or other fragment) uses to fetch the article from the application's ContentProvider.( onListItemClick() method'unu aldığı id parameter, listedeki tıklanılan item'ın row id'sidir. )
Handling the Fragment Lifecycle

Figure 3. The effect of the activity lifecycle on the fragment lifecycle.
Handling the Fragment Lifecycle
Managing the lifecycle of a fragment is a lot like managing the lifecycle of an activity. Like an activity, a fragment can exist in three states:
Resumed
The fragment is visible in the running activity.
Paused
Another activity is in the foreground and has focus, but the activity in which this fragment lives is still visible (the foreground activity is partially transparent or doesn't cover the entire screen).
Stopped
The fragment is not visible. Either the host activity has been stopped or the fragment has been removed from the activity but added to the back stack. A stopped fragment is still alive (all state and member information is retained by the system). However, it is no longer visible to the user and will be killed if the activity is killed.
Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated.
You can save the state during the fragment's onSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), or onActivityCreated().

The most significant difference in lifecycle between an activity and a fragment is how one is stored in its respective back stack.
An activity is placed into a back stack of activities that's managed by the system when it's stopped, by default
(so that the user can navigate back to it with the Back button, as discussed in Tasks and Back Stack).
However, a fragment is placed into a back stack managed by the host activity only when you explicitly request that the instance be saved by calling addToBackStack() during a transaction that removes the fragment.

Otherwise, managing the fragment lifecycle is very similar to managing the activity lifecycle. So, the same practices for managing the activity lifecycle also apply to fragments.
What you also need to understand, though, is how the life of the activity affects the life of the fragment.

Caution: If you need a Context object within your Fragment, you can call getActivity(). ( Fragment class'ının içerisinde Context object'i elde etmek için getActivity() method'unu çağırmalıyız. )
However, be careful to call getActivity() only when the fragment is attached to an activity. When the fragment is not yet attached, or was detached during the end of its lifecycle, getActivity() will return null.
( Fragment bir activity'nin içine gömüldükten sonra çağırmaya dikkat et getActivity() method'unu. Aksi takdirde, getActivity() method'u null return eder. )

Coordinating with the activity lifecycle
The lifecycle of the activity in which the fragment lives directly affects the lifecycle of the fragment, such that each lifecycle callback for the activity results in a similar callback for each fragment.
For example, when the activity receives onPause(), each fragment in the activity receives onPause().

Fragments have a few extra lifecycle callbacks, however, that handle unique interaction with the activity in order to perform actions such as build and destroy the fragment's UI.
These additional callback methods are:

onAttach()
Called when the fragment has been associated with the activity (the Activity is passed in here).
onCreateView()
Called to create the view hierarchy associated with the fragment.
onActivityCreated()
Called when the activity's onCreate() method has returned.
onDestroyView()
Called when the view hierarchy associated with the fragment is being removed.
onDetach()
Called when the fragment is being disassociated from the activity.
The flow of a fragment's lifecycle, as it is affected by its host activity, is illustrated by figure 3.
In this figure, you can see how each successive state of the activity determines which callback methods a fragment may receive.
For example, when the activity has received its onCreate() callback, a fragment in the activity receives no more than the onActivityCreated() callback.

Once the activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, only while the activity is in the resumed state can the lifecycle of a fragment change independently.

However, when the activity leaves the resumed state, the fragment again is pushed through its lifecycle by the activity.
Bu dersin tamamının pdf'ini linkten indirebilirsiniz: https://drive.google.com/file/d/197jW8LhSU6HJz35rIIiqN1mDM8m6rT_3/view?usp=sharing

Hiç yorum yok:

Yorum Gönder