Android RecyclerView ve CardView Kullanımı

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.

Ş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

 

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.

1

Alper Beyler

Yüksek Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği
Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği (4/3.30) (2010-2014)
Lisans : Viyana Teknik Üniversitesi / Bilgisayar Bilimleri (2013)

27 Yorum

    • 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.

    • 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

    • 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

  • 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..

    • 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?

  • 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.

Haftalık Bülten

Mobilhanem'de yayınlanan dersleri haftalık mail almak ister misiniz?