RecyclerView ile dinamik listeler oluşturma Android Jetpack'in bir parçasıdır.
RecyclerView, büyük veri kümelerini verimli bir şekilde görüntülemeyi kolaylaştırır. Verileri siz sağlar ve her öğenin nasıl görüneceğini tanımlarsınız. RecyclerView kitaplığı, öğeleri gerektiğinde dinamik olarak oluşturur.
Adından da anlaşılacağı üzere RecyclerView, bu öğeleri geri dönüştürür. Bir öğe kaydırılarak ekrandan çıktığında RecyclerView, öğenin görünümünü yok etmez. Bunun yerine, RecyclerView, ekranda kaydırılan yeni öğeler için görünümü yeniden kullanır. RecyclerView, performansı ve uygulamanızın yanıt verme hızını artırır, güç tüketimini azaltır.
Önemli sınıflar
Dinamik listenizi oluşturmak için birkaç sınıf birlikte çalışır.
RecyclerView, verilerinize karşılık gelen görünümleri içerenViewGroup'dir. Kendisi bir görünüm olduğundanRecyclerViewöğesini, diğer kullanıcı arayüzü öğelerini eklediğiniz gibi düzeninize eklersiniz.Listedeki her bir öğe, görünüm tutucu nesnesiyle tanımlanır. Görünüm tutucu oluşturulduğunda, kendisiyle ilişkilendirilmiş herhangi bir veri yoktur. Görünüm tutucu oluşturulduktan sonra
RecyclerView, görünüm tutucuyu verilerine bağlar. Görünüm tutucuyuRecyclerView.ViewHoldersınıfını genişleterek tanımlarsınız.RecyclerView, adaptördeki yöntemleri çağırarak görünümleri ister ve görünümleri verilerine bağlar. BağdaştırıcıyıRecyclerView.Adaptersınıfını genişleterek tanımlarsınız.Düzen yöneticisi, listenizdeki bağımsız öğeleri düzenler. RecyclerView kitaplığının sağladığı düzen yöneticilerinden birini kullanabilir veya kendi düzen yöneticinizi tanımlayabilirsiniz. Düzen yöneticilerinin tümü, kitaplığın
LayoutManagersoyut sınıfını temel alır.
Tüm parçaların nasıl bir araya geldiğini RecyclerView örnek uygulamasında (Kotlin) veya RecyclerView örnek uygulamasında (Java) görebilirsiniz.
RecyclerView'ınızı uygulama adımları
RecyclerView kullanacaksanız yapmanız gereken birkaç şey vardır. Bunlar aşağıdaki bölümlerde ayrıntılı olarak açıklanmıştır.
Listenin veya tablonun nasıl görüneceğini belirleyin. Normalde RecyclerView kitaplığının standart düzen yöneticilerinden birini kullanabilirsiniz.
Listedeki her öğenin görünümünü ve davranışını tasarlayın. Bu tasarıma göre
ViewHoldersınıfını genişletin.ViewHoldersürümünüz, liste öğeleriniz için tüm işlevleri sağlar. Görünüm tutucunuz,Viewiçin bir sarmalayıcıdır ve bu görünümRecyclerViewtarafından yönetilir.Verilerinizi
ViewHoldergörünümleriyle ilişkilendirenAdaptertanımlayın.
Ayrıca RecyclerView'ınızı tam olarak ihtiyaçlarınıza göre uyarlamanıza olanak tanıyan gelişmiş özelleştirme seçenekleri de vardır.
Düzeninizi planlama
RecyclerView'ınızdaki öğeler bir LayoutManager sınıfı tarafından düzenlenir. RecyclerView kitaplığı, en yaygın düzen durumlarını işleyen üç düzen yöneticisi sağlar:
LinearLayoutManageröğeleri tek boyutlu bir listede düzenler.GridLayoutManageröğeleri iki boyutlu bir ızgarada düzenler:- Izgara dikey olarak düzenlenmişse
GridLayoutManager, her satırdaki tüm öğelerin aynı genişlik ve yüksekliğe sahip olmasını sağlamaya çalışır ancak farklı satırlar farklı yüksekliklere sahip olabilir. - Izgara yatay olarak düzenlenmişse
GridLayoutManager, her sütundaki tüm öğelerin aynı genişlik ve yüksekliğe sahip olmasını sağlamaya çalışır ancak farklı sütunlar farklı genişliklere sahip olabilir.
- Izgara dikey olarak düzenlenmişse
StaggeredGridLayoutManager,GridLayoutManagerile benzerdir ancak bir satırdaki öğelerin aynı yüksekliğe (dikey ızgaralar için) veya aynı sütundaki öğelerin aynı genişliğe (yatay ızgaralar için) sahip olmasını gerektirmez. Sonuç olarak, bir satır veya sütundaki öğeler birbirinden kaydırılabilir.
Ayrıca, her bir öğenin düzenini de tasarlamanız gerekir. Bir sonraki bölümde açıklandığı gibi, görünüm tutucuyu tasarlarken bu düzene ihtiyacınız vardır.
Bağdaştırıcınızı ve görünüm tutucunuzu uygulama
Yerleşiminizi belirledikten sonra Adapter ve ViewHolder uygulamanız gerekir. Bu iki sınıf, verilerinizin nasıl gösterileceğini tanımlamak için birlikte çalışır. ViewHolder, listedeki bağımsız bir öğenin düzenini içeren View için bir sarmalayıcıdır. Adapter, gerektiğinde ViewHolder nesneleri oluşturur ve bu görünümlerin verilerini de ayarlar. Görünümleri verileriyle ilişkilendirme işlemine bağlama adı verilir.
Adaptörünüzü tanımlarken üç temel yöntemi geçersiz kılarsınız:
onCreateViewHolder():RecyclerView, yeni birViewHolderoluşturması gerektiğinde bu yöntemi çağırır. Yöntem,ViewHolderve ilişkiliViewöğesini oluşturup başlatır ancak görünümün içeriğini doldurmaz.ViewHolderhenüz belirli verilere bağlanmamıştır.onBindViewHolder():RecyclerView, birViewHolderöğesini verilerle ilişkilendirmek için bu yöntemi çağırır. Yöntem, uygun verileri getirir ve görünüm tutucunun düzenini doldurmak için bu verileri kullanır. Örneğin,RecyclerViewbir ad listesi gösteriyorsa yöntem, listede uygun adı bulup görünüm tutucununTextViewwidget'ını doldurabilir.getItemCount():RecyclerView, veri kümesinin boyutunu öğrenmek için bu yöntemi çağırır. Örneğin, bir adres defteri uygulamasında bu, toplam adres sayısı olabilir. RecyclerView, görüntülenebilecek başka öğe kalmadığını belirlemek için bunu kullanır.
Aşağıda, veri listesi gösteren iç içe yerleştirilmiş ViewHolder içeren basit bir bağdaştırıcı örneği verilmiştir. Bu durumda RecyclerView, metin öğelerinden oluşan basit bir liste gösterir. Bağdaştırıcıya, ViewHolder öğelerinin metnini içeren bir dize dizisi iletilir.
Kotlin
class CustomAdapter(private val dataSet: Array<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { // Define click listener for the ViewHolder's View textView = view.findViewById(R.id.textView) } } // Create new views (invoked by the layout manager) override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { // Create a new view, which defines the UI of the list item val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } // Replace the contents of a view (invoked by the layout manager) override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.textView.text = dataSet[position] } // Return the size of your dataset (invoked by the layout manager) override fun getItemCount() = dataSet.size }
Java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } /** * Initialize the dataset of the Adapter * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView */ public CustomAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.text_row_item, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } }
Her görünüm öğesinin düzeni, her zamanki gibi bir XML düzen dosyasında tanımlanır.
Bu durumda, uygulamanın aşağıdaki gibi bir text_row_item.xml dosyası vardır:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
</FrameLayout>
Sonraki adımlar
Aşağıdaki kod snippet'i, RecyclerView öğesini nasıl kullanabileceğinizi gösterir.
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dataset = arrayOf("January", "February", "March") val customAdapter = CustomAdapter(dataset) val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = customAdapter } }
Java
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.layoutManager = new LinearLayoutManager(this) recyclerView.setAdapter(customAdapter);
Kitaplık, uygulamanızı özelleştirmenin birçok yolunu da sunar. Daha fazla bilgi için Gelişmiş RecyclerView özelleştirmesi başlıklı makaleyi inceleyin.
Uçtan uca ekranı etkinleştirin
RecyclerView için uçtan uca ekranı etkinleştirmek üzere aşağıdaki adımları uygulayın:
enableEdgeToEdge()yöntemini çağırarak geriye dönük uyumlu bir uçtan uca ekran oluşturun.- Liste öğeleri başlangıçta sistem çubuklarıyla çakışıyorsa
RecyclerViewöğesine iç dolgular uygulayın. Bunu yapmak içinandroid:fitsSystemWindowsdeğerinitrueolarak ayarlayabilir veyaViewCompat.setOnApplyWindowInsetsListenerkullanabilirsiniz. RecyclerViewüzerindeandroid:clipToPaddingdeğerinifalseolarak ayarlayarak kaydırma sırasında liste öğelerinin sistem çubuklarının altında çizilmesine izin verin.
Aşağıdaki videoda, uçtan uca ekranın devre dışı bırakıldığı (solda) ve etkinleştirildiği (sağda) bir RecyclerView gösterilmektedir:
Örnek ekleme kodu:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener( findViewById(R.id.my_recycler_view) ) { v, insets -> val innerPadding = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() // If using EditText, also add // "or WindowInsetsCompat.Type.ime()" to // maintain focus when opening the IME ) v.setPadding( innerPadding.left, innerPadding.top, innerPadding.right, innerPadding.bottom) insets }
Java
ViewCompat.setOnApplyWindowInsetsListener( activity.findViewById(R.id.my_recycler_view), (v, insets) -> { Insets innerPadding = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() // If using EditText, also add // "| WindowInsetsCompat.Type.ime()" to // maintain focus when opening the IME ); v.setPadding( innerPadding.left, innerPadding.top, innerPadding.right, innerPadding.bottom ); return insets; } );
RecyclerView XML:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Ek kaynaklar
Android'de test etme hakkında daha fazla bilgi için aşağıdaki kaynakları inceleyin.