Merhaba arkadaşlar,
mobilhanem.com üzerinden anlattığımız/yayınladığımız derslere bugün sizlere RecyclerView ve CardView kavramlarının nasıl kullanıldığını anlatacağım. Android 5.0 Lollipop güncellemesi ile birlikte ortaya çıkan bu iki widget , gerçekten çok kullanışlı ve uygulamalarınıza estetik olarak daha güzel bir görünüm sağlamaktadır. İlk olarak RecyclerView nedir ona bakalım ; bu widget ,ListView in farklı bir versiyonu olarak düşünülebilir. Daha esnek bir yapıya sahiptir ayrıca, hem horizontal (yatay) hem de vertical (dikey) olarak konumlanan bir layout yapısına sahiptir. ListView yapısından farklı olarak, RecyclerView, verilerin konumlanmasını yönetebilmek için, LayoutManager yapısına ihtiyaç duymaktadır. Kendi LayoutManager ını tanımlayacabileceğin gibi, çoğu zaman LayoutManager ın kendi alt sınıflarını da kullanabilirsin. Bu alt sınıflar nelerdir şimdi ona bakalım :
* LinearLayoutManager: Verilerin horizontal veya vertical eksende görüntülenmesini sağlar.
* GridLayoutManager: Verilerin grid yapısı içinde görüntülenmesini sağlar.
* StaggeredGridLayoutManager: Verilerin staggered grid yapısı içinde görüntülenmesini sağlar.
Ben bu dersimizde, LinearLayoutManager kullandım. Kaynak kodlarını da indirip incelerseniz eğer sizin için daha faydalı olacaktır.
Android RecyclerView ve CardView Kullanımı
Şimdi de biraz CardView yapısından bahsedelim, CardView genelde tek başına kullanılabilen bir yapı değildir, RecyclerView veya ListView içerisinde bir liste elemanı olarak kullanılması yaygındır. Bende bu dersimizde, RecyclerView içerisinde nasıl kullanacağımızı sizlere anlatmaya çalışacağım. CardView , farklı yapıda içeriklerin bir arada kullanmamıza ve görsellik olarak yeni bir deneyim kazanmamıza yardımcı olmaktadır. İki farklı widget ı da gördüğümüze göre, şimdi yapmış olduğum uygulamayı anlamaya çalışalım.
v7 support library sayesinde, bu iki yapıyı kullanmamıza olanak sağlamaktadır. Şimdi uygulamamızda kullanabilmemiz için build.gradle açıp dependencies kısmına aşağıdaki iki kod bloğunu yapıştırıyoruz.
compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:cardview-v7:25.3.1'
Daha sonra CardView yapısının layout kısmını ayarlayalım. CardView de gözükmesini istediğimiz verileri belirledik aşağıdaki layout kısmına bakarsanız eğer, bir ImageView , iki tane de TextView kullandığımı göreceksiniz.
id sini person_photo olarak belirlediğim ImageView kullanıcın resmini tutacak
id sini person_name olarak belirlediğim TextView , kullanıcının ismini tutacak
id sini person_age olarak belirlediğim TextView ise, kullanıcının yaşını tutacak
CardView için xml layout dosyamız aşağıdaki gibidir.
card_view_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:padding="16dp" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" card_view:cardCornerRadius="4dp" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" > <ImageView android:layout_width="50dp" android:layout_height="50dp" android:id="@+id/person_photo" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginRight="16dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/person_name" android:layout_toRightOf="@+id/person_photo" android:layout_alignParentTop="true" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/person_age" android:layout_toRightOf="@+id/person_photo" android:layout_below="@+id/person_name" /> </RelativeLayout> </android.support.v7.widget.CardView> </LinearLayout>
Şimdir RecyclerView yapımızın layout kısmına bakalım. Aşağıda gördüğünüz gibi, RecyclerView widget ımızı tanımladık. Uygulamamızı çalıştırdığımızda, ilk çalışacak kısma bağlı olarak açılan kısım activity_main.xml olduğu için burada bu yapıyı gösterdim.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:background="@drawable/android_background" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
İki widget ımızın da görselliğini tamamladığımıza göre kod kısmına bakabiliriz.
Bu yapının içinde gözükmesini istediğim bileşenleri yukarıda belirtmiştim. kullanıcı ismi, yaşı ve resmi gibi verileri tutabilmemiz için Person adını verdiğim bir sınıf oluşturdum. Şimdi bu sınıfa bakalım;
Aşağıda gördünüğümüz gibi Person sınıfımızın değişkenleri ; name, age ve photo_id dir. Constructor ve getter methodlarımız da yazılmıştır.
Person.java
package com.mobilhanem.recyclerviewexample; import android.widget.ImageView; import java.util.ArrayList; import java.util.List; /** * Created by Alper on 15.5.2015. */ public class Person { private String name; private String age; private int photo_id; public String getName() { return this.name; } public String getAge() { return this.age; } public int getPhoto_id() { return this.photo_id; } public Person(String name,String age,int photo_id) { this.name = name; this.age = age; this.photo_id = photo_id; } public Person() { } }
Sınıfımızı da gördüğümüze göre; şimdi verilerimizi şekillendirmemiz için bir adapter yapısını yaratmamız gerekmektedir. Aşağıdaki şekilde ne demek istediğimi tam olarak anlayacaksınız.
RecyclerView yapısında Layout Manager ımız ile verilerimiz arasında köprü kuran Adapter sınıfını nasıl oluşturduğumuza bakalım. Aşağıdaki kodu incelediğimiz de, nasıl bir ListView için custom adapter yaratıp istediğimiz verileri ListView mizde gösteriyorsak, RecyclerView yapısı içinde aynı mantıkla bir Adapter oluşturduk ismini de SimpleRecyclerAdapter koyduk. Bu yapıda, ViewHolder pattern yapısını kullanmaya zorunlu kıldığını görmekteyiz. ViewHolder kısmında yer alacak değişkenleri yazdık ve referanslarını aldık. SimpleRecyclerAdapter constructor une baktığımızda, içinde Person sınıfını barındıran bir Liste aldığını göreceksiniz. Listenin içindeki verileri de , ilgili oldukları değişkenlerimize atadık.
ListView deki setOnItemClickListener methodunun Recylerview de olmadığını göreceksiniz. Bu yüzden ben bir interface oluşturdum. Tıklanan elemanı ve pozisyonunu alıyor fonksiyon gördüğünüz gibi.
public interface CustomItemClickListener { void onItemClick(View v, int position); }
Daha sonra adapter sınıfımızda view e tıklandığında kendi interface de yazdığımız onItemClick methodunu tetikledik.
SimpleRecyclerAdapter.java
package com.mobilhanem.recyclerviewexample; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.List; /** * Created by Alper on 14.5.2015. */ public class SimpleRecyclerAdapter extends RecyclerView.Adapter<SimpleRecyclerAdapter.ViewHolder> { public static class ViewHolder extends RecyclerView.ViewHolder { public TextView person_name; public TextView person_age; public ImageView person_img; public CardView card_view; public ViewHolder(View view) { super(view); card_view = (CardView)view.findViewById(R.id.card_view); person_name = (TextView)view.findViewById(R.id.person_name); person_age = (TextView)view.findViewById(R.id.person_age); person_img = (ImageView)view.findViewById(R.id.person_photo); } } List<Person> list_person; CustomItemClickListener listener; public SimpleRecyclerAdapter(List<Person> list_person, CustomItemClickListener listener) { this.list_person = list_person; this.listener = listener; } @Override public SimpleRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_layout, parent, false); final ViewHolder view_holder = new ViewHolder(v); v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(v, view_holder.getPosition()); } }); return view_holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.person_name.setText(list_person.get(position).getName()); holder.person_age.setText(list_person.get(position).getAge()); holder.person_img.setImageResource(list_person.get(position).getPhoto_id()); } @Override public int getItemCount() { return list_person.size(); } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); } }
Adapter kısmını da bitirdiğimize göre, şimdi MainActivity sınıfımızı inceleyelim. Aşağıda gördüğünüz gibi, Person sınıfını barındıran, List bileşenini oluşturup , gerekli bilgileri SimpleRecyclerAdapter ın constructor une yolladık. Yukarı da bahsettiğim gibi LinearLayoutManager yapısını kullanarak konumunu vertical olarak belirledik. En son olarak da RecyclerView yapısına oluşturduğumuz adapter ımızı ekledik.
MainActivity.java
package com.mobilhanem.recyclerviewexample; import android.app.Activity; import android.os.Bundle; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private RecyclerView recycler_view; private List<Person> person_list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recycler_view = (RecyclerView)findViewById(R.id.recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.scrollToPosition(0); recycler_view.setLayoutManager(layoutManager); person_list = new ArrayList<Person>(); person_list.add(new Person("Alper Beyler", "23 yaş", R.drawable.boy_img)); person_list.add(new Person("Taha Kırca", "25 yaş", R.drawable.user_man_img)); person_list.add(new Person("Ayşe Fatma", "35 yaş", R.drawable.women_img)); person_list.add(new Person("Ahmet Ali", "60 yaş", R.drawable.male_img)); person_list.add(new Person("Pelin Pelin", "20 yaş", R.drawable.female_img)); person_list.add(new Person("Osman Osman", "33 yaş", R.drawable.gender_male)); person_list.add(new Person("Sevgi Bütün", "40 yaş", R.drawable.gender_female)); person_list.add(new Person("Abulkadir Yavaş", "33 yaş", R.drawable.men_image)); person_list.add(new Person("Ayşe Mutlu", "36 yaş", R.drawable.girl_worker)); person_list.add(new Person("Ahmetcan Can", "28 yaş", R.drawable.user_operator)); person_list.add(new Person("Fatma Can", "28 yaş", R.drawable.girl_girl)); person_list.add(new Person("Mustafa Altın", "28 yaş", R.drawable.computer_men)); person_list.add(new Person("Caner Yalçın", "28 yaş", R.drawable.worker_man)); person_list.add(new Person("Gönül Yalçın", "28 yaş", R.drawable.computer_girl)); SimpleRecyclerAdapter adapter_items = new SimpleRecyclerAdapter(person_list, new CustomItemClickListener() { @Override public void onItemClick(View v, int position) { Log.d("position", "Tıklanan Pozisyon:" + position); Person person = person_list.get(position); Toast.makeText(getApplicationContext(),"pozisyon:"+" "+position+" "+"Ad:"+person.getName(),Toast.LENGTH_SHORT).show(); } }); recycler_view.setHasFixedSize(true); recycler_view.setAdapter(adapter_items); recycler_view.setItemAnimator(new DefaultItemAnimator()); } }
Böylelikle, RecyclerView ve CardView kullanımı bitirmiş olduk. Daha yeni android dünyasına giren bu widget ları sizlere tanıtmak ve nasıl kullanılacağını göstermek istedim. Umarım faydalı bir ders olmuştur. Uygulamanın kaynak kodunu indirip, çalıştırın ve bu yeni widget lar ile ilgili görüşlerinizi paylaşın. Ben gerçekten çok beğendim, uygulamalarımıza farklı bir hava katacağı kesin bu yapıların.
Ders hakkında soru ve önerilerinizi çekinmeden yorum bırakabilirsiniz. Bol Android’li günler sizin olsun
Sizlerden ricamız facebook.com/mobilhanem sayfamızı beğenmenizdir. Diğer dersimde görüşmek üzere kendinize iyi bakın..
Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.
Merhaba herşeyi uyguladım ama cardviewler bu şekilde görünüyor neden acaba ?
http://i.hizliresim.com/NEy6yN.jpg
Merhaba, burdaki kaynak kodu indirip incelediniz mi ? video var bide run ettiğinizde uygulamayı sorunsuz bir şekilde çalışacaktır cardview lerin arasındaki boşluk oluşturduğunuz layout ile ilgili olabilir oradaki kodları görmek lazım.
ayrıca cardview e bu kodu ekleyip (yada çıkarıp) farka bakar mısın : app:cardUseCompatPadding=”true”
Kodu ekledim ama birşey değişmedi. Kaynak kodları indirip çalıştırdığımda sorun yok ama kendi uygulamama entegre edince kodları resimdekigibi açıklık oluyor aralarında.
main_activity.xml
card_view_layout.xml
card_view_layout dosyasından kaynaklanıyor bu durum. Ana layoutu linearLayout olduğu için bu şekilde görünüyor. Ana layoutu CardView yaparsanız arka arkaya Person objelerini görebilirsiniz. Bunun için de card_view_layout dosyası:
şeklinde olacak.
Benzer bir sorun bende de vardı. Çözümünüz işe yaradı. Teşekkürler.
Merhaba bu dersteki kaynak kodu yeniledik tekrardan indirip denersen düzgün bir şekilde çalıştığını göreceksin
Merhaba, Empty Activity’de verdiğiniz kodları ekleyince kartların arasında açıklık olmuyor ama Navigation Drawer Activity açtıktan sonra uygulamaya resimdeki hatayı veriyor tıklayıp implemet methots diyince;
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
bu kodları ekliyor ve ondan sonra kartlar arasında açıklık oluşuyor. Bunu nasıl çözebilirim neyden kaynaklanıyor acaba ?
Merhaba bu konuda çoklu şeçme işlemini
Silme okuma ekleme vb işlemleri anlatabilirmisiniz veya örnek verebilirmisiniz
Web’de RecyclerView Action Mode diye aratın, örneklerine rastlıyacaksınız hocam.
Paylaşımınız için teşekkürler
Biz teşekkür ederiz. İsinize yaradıysa ne mutlu.
Merhaba. recyclerview’da tıklanılan cardın idsini nasıl alabiliriz?
Merhaba interface yardımı ile click listener oluşturursun ve mainactivity sınıfında erişip card positionu ve tıkladığın yerin adını alabilirsin kaynak kod güncel indirip denersen faydalı olacaktır
şu şekilde bir hata alıyorum
https://uploads.disquscdn.com/images/11464fafd8466ea6f86eb7b63e57a319b39cbb3cee162f61684789caf1ea1db5.png
Merhaba, kaynak kodu indirip çalıştırdınız mı ? new LinearLayoutManager(getContext()) şeklinde deneyebilirmisiniz
Oldu teşekkürler 😀
Program açıldığında , activity_main.xml ‘de RelativeLayout ; card_view_layout.xml dosyasında da,LinearLayout altı kırmızı çizgiyle çiziliyor. Maus bu kırmızı çizgiye dokundurulduğunda hataların “Cannot find the declaration of element LinearLayout” ve “Cannot find the declaration of element RelativeLayout” olduğu görülüyor.Bu hata nasıl giderilir.Teşekkürler..
Emeğinize sağlık. İyi ki varsınız
olumlu görüşünüz için teşekkürler elimizden geldiğince yardımcı olmaya çalışıyoruz.
İmage yerine buton koyup id tanımlaması yapıp eklediğim buton kadar belirlediğim ses dosyalarının çalmasını istiyorum bunu nasıl yapabilirim?
[…] uygulama yapacağım.Bu derse başlamadan önce RecyclerView ve CardView kullanımı ile ilgili bu dersimizi incelemeniz faydalı […]
Merhaba, burda yazanları uyguladım ancak item e tıkladığımda hata oluyor ve ;
‘listener.onItemClick(v, view_holder.getPosition());’ ve ‘Person person = person_list.get(position);’ satırlarında problem olduğunu söylüyor, api hatası vardı ‘getPosition’ yerine ‘getAdapterPosition’ kullandım ancak hala hata veriyor, neden kaynaklı olabilir?
Merhaba cartview üzerine solite database verilerini Cursor üzerinden kart listesine eklediğim uygulama çöküyor ama stringBuffer üzerine atıp textview üzerinde ise çalışıyor. Hata ne olabilir.
Arka plan resmi listeyi kasıyor resim boyutunu nasıl ayarliyacam çözünürlük düşüyor bu sefer görüntü kalitesi gider. Arka plan resmini kaldırıp color renk atadigim zaman liste hızlanıyor.
2. Sorum bir veri tabanı oluşturdum Cursor database üzerinden veri tabanında verileri stringbuffer üzerinde goruntuleyebiliyorum bunu listede kartlar üzerinde görüntülemek istediğimde uygulama çöküyor Cursor Adapter farklı mı acaba
Merhaba Hocam. Dizi boyutu 10 olan bir RecyclerView örneği yaptım. cardView tasarımım içinde bir adet buton var. şimdi benim RecyclerView örneğim 10 adet cardView barındırmış oluyor. 10 adet activity oluşturdum. cardView içindeki butonlara tıkladığımda her biri farklı activitye geciş yapmasını istiyorum.Nasıl yapabilirim Hocam. Adapter sınıfında tek id ye sahip tek butonum var. bunun bir kodu olmalı. birçok alışveriş sitesinde bunun örneğini gördüm.
teşekkürler emeğinize sağlık