RecyclerView Kullanımı
Bir önceki yazımızda RecyclerView tanımını, ListView ile karşılaştırılmasını incelemiştik. Şimdi de adım adım RecyclerView nasıl kullanılır inceleyelim.
Temel olarak yapmamız gerekenleri 4 adımda özetleyen aşağıdaki görseli hazırladım. Adım adım bu işlemleri uygulayacağız.
Projeye recyclerview ve cardview bağımlılıklarını ekleyelim.
ProjectStructure/app/Dependencies/+ butonu/Library Dependencies tıklayarak açılan pencerede recylerview yazıyoruz.
Listeden recylerview seçerek “OK” butonuna tıklıyoruz. Bu sayede recyclerview projemizin module app seviyesinde build.gradle içerisinde dependencies alanına eklenmiş oluyor.
Aynı işlemi cardview için de yapıyoruz. Artık projemizde RecylerView ve CardView kullanabiliriz.
1. adımda item_product_card.xml dosyamızı hazırlayacağız.
Bunun için res/layout/ dizinine sağ tıklayarak New Resource File tıklayalım ve item_product_card.xml adında dosyamızı oluşturalım.
Bu dosyayı oluştururken Root Element kısmını “CardView” seçelim. İlk olarak tasarımızın son hali üzerinde componentlerin yerleşimini gösteren bir görsel hazırladım.
Görselde gördüğümüz silme ikonu için res/drawable klasörüne “ic_delete_yellow” adında ikonumuzu ekledikten sonra tasarımımız için kodları inceleyelim.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="horizontal">
<ImageView
android:id="@+id/productImage"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ic_launcher_background" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/productName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="9dp"
android:text="productAdi"
android:textSize="15dp"
android:textStyle="bold" />
<TextView
android:id="@+id/productDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="3dp"
android:text="Aciklama"
android:textSize="12dp"
android:textStyle="italic" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<ImageView
android:id="@+id/deleteproduct"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:src="@drawable/ic_delete_yellow" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Burada root elementimizin CardView olduğuna dikkat edelim. CardView bir LayoutViewGrouptur. Her CardView öğesi aslında listemizin bir satırını oluşturuyor.İsimlendirmesinde item ifadesini kullanma sebebimiz de bu. Her satırımızın kenarlarına radius özelliği vermek için CardView bileşenimize “cardCornerRadius” özelliğini kullandık.
2. adımda activity_main.xml içerisine RecylerView ekleyelim
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hasibezafer.recyclerview.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recylerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
Burada 1. adımda oluşturmuş olduğumuz item_product_card yani her bir satır tasarımımız diyebiliriz bunu activity_main.xml’de gösteriyoruz.
RecylerView bileşenini kullanmamızı sağlayan kodu yazımızın en başında dependicies içerisine eklemiştik.
3. adımda kendimize bir “Veri Modeli” oluşturacağız.
MainActivity dosyamızın da bulunduğu java dizinimize Product.java adında bir dosya oluşturalım ve Veri Modelimizi hazırlayalım. Bu sınıfı oluşturmamızın sebebi her bir satırımızda farklı tiplerden oluşan verilere tek seferde ulaşıp satırı inflate etmek.
Veri modelimizde fotoğraflara sırasıyla erişmek için int tipinde değişken, albüm adını ve açıklaması için String tipinde değişkenler oluşturduk. Kodlarımızı incelemeden önce her bir satırımızda kullanacağımız görseller res/drawable klasörüne eklemeyi unutmayalım.
package com.example.hasibezafer.recyclerview;
import java.util.ArrayList;
/**
* Created by tchzafer on 21/03/2018.
*/
public class Product {
private String productName;
private String productDescription;
private int imageID;
public Product() {
}
public Product(int imageID, String productName, String productDescription) {
this.imageID = imageID;
this.productName = productName;
this.productDescription = productDescription;
}
public int getImageID() {
return imageID;
}
public void setImageID(int imageID) {
this.imageID = imageID;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductDescription() {
return productDescription;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public static ArrayList<Product> getData() {
ArrayList<Product> productList = new ArrayList<Product>();
int productImages[] = {R.drawable.gelecegiyazanlar, R.drawable.paycell, R.drawable.tvplus,R.drawable.dergilik,R.drawable.bip,R.drawable.gnc,R.drawable.hesabim,R.drawable.sim,R.drawable.lifebox,R.drawable.merhabaumut,R.drawable.yaani,R.drawable.hayalortagim,R.drawable.gollercepte,R.drawable.piri};
String[] productNames = {"Geleceği Yazanlar", "Paycell", "Tv+","Dergilik","Bip","GNC","Hesabım","Sim","LifeBox","Merhaba Umut","Yaani","Hayal Ortağım","Goller Cepte","Piri"};
for (int i = 0; i < productImages.length; i++) {
Product temp = new Product();
temp.setImageID(productImages[i]);
temp.setProductName(productNames[i]);
temp.setProductDescription("Turkcell");
productList.add(temp);
}
return productList;
}
}
Kodlarımızı inceleyecek olursak, değişkenlerimizi tanımladıktan sonra bu değişkenleri çağırmak ve veri set etmek için “getter ve setter” metodlarını kullandık.
Satırımızı doldurmak için ArrayList<Product> tipinde getData() adında bir method yazıyoruz. ArrayList’imizin bizim oluşturduğumuz Product sınıfı tipinde veri tuttuğuna dikkat edelim.
int tipinde productImages adında resimlerimizi tutan bir dizi oluşturduk. Resimlerimizi statik olarak drawable klasörüne ekledik. Ve bu dizide resimlerin path bilgisini tuttuk.Daha sonra resim sayısı kadar tüm bilgileri her bir satıra set etme işlemini yapan bir for döngüsü oluşturduk ve listemize ekledik. Methodumuz bize sonuç olarak productList döndü.
4. adımımızda ProductAdapter oluşturacağız.
Bu adıma kadar elimizde listemizin tasarımı, bu listeyi dolduracak verileri tutan bir sınıf var.
Şimdi de hazır olan verilerle satırımızı inflate işlemine geldi. Bunun için MainActivity dosyamızın da bulunduğu java dizinimize ProductAdapter.java adında bir dosya oluşturalım ve kodlarımızı inceleyelim.
package com.example.hasibezafer.recyclerview;
import android.content.Context;
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.ArrayList;
/**
* Created by tchzafer on 21/03/2018.
*/
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.MyViewHolder> {
ArrayList<Product> mProductList;
LayoutInflater inflater;
public ProductAdapter(Context context, ArrayList<Product> products) {
inflater = LayoutInflater.from(context);
this.mProductList = products;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_product_card, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Product selectedProduct = mProductList.get(position);
holder.setData(selectedProduct, position);
}
@Override
public int getItemCount() {
return mProductList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView productName, productDescription;
ImageView productImage, deleteproduct;
public MyViewHolder(View itemView) {
super(itemView);
productName = (TextView) itemView.findViewById(R.id.productName);
productDescription = (TextView) itemView.findViewById(R.id.productDescription);
productImage = (ImageView) itemView.findViewById(R.id.productImage);
deleteproduct = (ImageView) itemView.findViewById(R.id.deleteproduct);
deleteproduct.setOnClickListener(this);
}
public void setData(Product selectedProduct, int position) {
this.productName.setText(selectedProduct.getProductName());
this.productDescription.setText(selectedProduct.getProductDescription());
this.productImage.setImageResource(selectedProduct.getImageID());
}
@Override
public void onClick(View v) {
}
}
}
Kodlarımızı inceleyecek olursak bilmemiz gereken ilk şey Adapter’ımızı RecyclerView.Adapter’dan extend etmek. Bu işlemi yaptığımızda import etmemiz gereken methodları tek tek inceleyelim.
onCreateViewHolder() : Bu method adaptör oluşturulduğunda oluşturduğumuz ViewHolder'ın başlatılması için çağrılır.
onBindViewHolder() : onCreateViewHolder’dan dönen verileri bağlama işlemini gerçekleştirildiği metotdur.
getItemCount() : Listemizin eleman sayısını döndüren metottur.
MyViewHolder(): Her bir satırımızın içinde bulunan bileşenleri tanımlama işleminin yapıldığı metottur.
LayoutInflater sınıfından inflater adında bir nesne tanımlıyoruz. MainActivity sınıfımızda Adapter’ımızdan bir nesne türettiğimizde çalışacak ilk method Constructor olduğu için Adapter içerisinde Constructor’ı tanımlamamız gerekir.Context üzerinden getSystemService ile inflater erişmek için methodumuza parametre olarak Context, ArrayList<> doldurmak içinde Product tipinde listemizi ArrayList<Product> şeklinde parametre olarak yolladık.
MyViewHolder() methodunu inceleyecek olursak burada path bilgisini inflate() methodunun ilk parametresi olarak vererek View tipinde nesnemizi elde ettik. Oluşturulan bu nesneyi MyViewHolder tipine dönüştürerek holder return ettik.
MyViewHolder içerisinde item_product_layout.xml içerisindeki bileşenleri tanımladık.
onBindViewHolder() methodu içerisinde onCreateViewHolder’dan dönen holder ve position parametre olarak gönderip listenin hangi veri ile dolacağını ve elemana tıklanma olaylarını kontrol edebileceğiz. Bunun içinde setData() adında bir method oluşturarak tıklanılan verinin bilgilerini getter metodu ile alarak setter methodu ile ilgili yere set ediyoruz.
5. ProductAdapter’ı listemize bağlıyoruz.
Ve son adımımızda listemizi görüntülemek için oluşturmuş olduğumuz adapter’ı MainActivity.java içerisinde listemize bağlıyoruz. Kodlarımızı inceleyelim.
package com.example.hasibezafer.recyclerview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recylerview);
ProductAdapter productAdapter = new ProductAdapter(this, Product.getData());
recyclerView.setAdapter(productAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
}
}
Burada adapterımızı listemize bağlamak için setAdapter() kullanıyoruz.
Farklı olarak LinearLayoutManager sınıfından bir nesne üretip listemizin orientation bilgisini set ediyoruz. Bu sayede listemizi yatay, dikey, grid ve staggered şeklinde gösterebiliyoruz.Bu örneğimizde dikeyde listeledik.
Bir sonraki yazımızda OptionsMenu ile tüm Layout biçimlerini set edip, tıklanma ve silme işlemlerini açıklayacağız.
Bir sonraki yazımızda listemizin yatay(horizontal), ızgara (grid), zik-zak (staggered) görünümü ve listeden eleman silme işlemini anlatacağız.