Bu dersimizde greenrobot eventbus kütüphanesini fragmentten activity’e ve de activity’den fragmente veri gönderdiğimiz bir uygulama üzerinde gerçekleştirmeye çalışıcaz. Ve bu örneği yaparken sticky event kullanmamız gerekecek.
Bu örnek fragmentlerin tekrar kullanımı ve fragmentler ile flexible yani esnek arayüzler tasarlanaması ile ilgilidir. Portrait ve landscape modlarda kullanıcıya farklı arayüzler sunarak kullanıcı dostu uygulamalar yapmalıyız. Böyle durumlarda fragmentler işlerimizi kolaylaştırır.
Portrait modda main activity içerisinde bi fragment açılır ve bu fragmentin içinde bazı konu başlıklarını içeren listview var. Bu listview verileri strings.xmlde belirttiğimiz string arraydan alıyor. Kullanıcı listedeki elemanları tıkladığında activity’e position değeri gönderilir ve yeni bir activity açılarak bu değer kullanılır. Açılan yeni activity bu position değerini detaylar fragmentine gönderir ve tıklanılan elemanın listedeki yerine göre açıklama gösterilir.
Landscape modda ise main activity için farklı bir layout hazırlanır. Bu layoutun içinde ekranı daha verimli kullanmak için iki fragmenti de gösteririz. Konu başlıkları fragmentinde tıklanılan başlık bilgisine göre açıklamaları tutan fragmentin ilgili verileri göstermesini sağlarız.
Anlaşılacağı üzere tıklanılan öğenin position değeri activity ve farklı bir fragmente gönderiliyor. Bu değeri eventbus ile gönderirsek interface ve bundle kullanmamıza gerek kalmaz ve bileşenleri birbirlerine bağlamadan, birbirlerine zorunlu kılmadan istediğimiz işlemleri yapabiliriz.
Bunu yaparken sticky event kullanabiliriz. Normal event ve sticky event göndermenin arasındaki fark, EventBus tarafından kullanılan önbellek mekanizmasıyla alakalı bir durum. Kanala sticky bir event gönderdiğinizde, bu event önbellekte saklanır. Yeni bir Activity veya Fragment o event kanalına abone olduğunda, yeni bir event’in yayınlanmasını beklemeden en son yayınlanan ve önbellekte saklanan yapışkan event’i direkt olarak alır. Bu event herhangi bir abone onu kanaldan alsa bile önbellekte saklanmaya devam eder.
Örneğimizde DigerActivity yayınlanan position değerini alamıyor. Çünkü bu mesaj yayınlandığında henüz oluşturulmamıştı. Bu durumu aşmak için sticky event kullandık. Bu sayede yayınlanan bu mesaj önbellekte tutulur ve bir bileşen abone olduğunda daha önce yayınlanan ve önbellekte tutulan mesajları alabilir.
Bu derste yazılan kodlar aşağıdaki gibidir, eventbus kullanmadan yazılan kodlar yorum satırları içerisine alınmıştır. Projenin düzenlenmiş, eski kodlardan silinmiş ve son halini buradan indirebilirsiniz. Göreceksinizki eventbus ile çok temiz ve az kod ile istenilen işlemler çok kolay bir şekilde yapılabiliyor 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public class MainActivity extends AppCompatActivity /*implements MyListener */{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /*@Override public void sendData(int position) { }*/ @Subscribe public void onPositionEvent(PositionEvent event){ int position=event.getPosition(); FragmentAciklama fragmentAciklama = (FragmentAciklama) getFragmentManager().findFragmentById(R.id.fragmentAciklamaLand); //landscape modda burası çalışır if (fragmentAciklama != null && fragmentAciklama.isVisible()) { fragmentAciklama.konuAciklamasi(position); } //portrait modda burası çalışır else { Intent i = new Intent(this, DigerActivity.class); startActivity(i); } } @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override protected void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public class DigerActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_diger); /* Intent intent=getIntent(); int pos=intent.getIntExtra("position", 0);*/ } @Subscribe (sticky = true) public void onPositionEvent(PositionEvent event){ FragmentAciklama fragmentAciklama= (FragmentAciklama) getFragmentManager().findFragmentById(R.id.fragmentAciklama); fragmentAciklama.konuAciklamasi(event.getPosition()); } @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override protected void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class FragmentKonu extends Fragment implements AdapterView.OnItemClickListener { ListView konuListesi; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment_konu, container,false); konuListesi= (ListView) view.findViewById(R.id.konularListesi); ArrayAdapter adapter=ArrayAdapter.createFromResource(getActivity(), R.array.konular, android.R.layout.simple_list_item_1); konuListesi.setAdapter(adapter); konuListesi.setOnItemClickListener(this); return view; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { /* MyListener listener= (MyListener) getActivity(); listener.sendData(position);*/ EventBus.getDefault().postSticky(new PositionEvent(position)); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class FragmentAciklama extends Fragment { TextView aciklama; String[] aciklamalar; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment_aciklama, container, false); aciklama= (TextView) view.findViewById(R.id.tvAciklama); aciklamalar=getResources().getStringArray(R.array.aciklamalar); aciklama.setText(aciklamalar[0]); return view; } public void konuAciklamasi(int pos) { aciklama.setText(aciklamalar[pos]); } } |