[Kotlin] Hướng dẫn mọi người sử dụng StaggeredGridLayoutManager với recycler view trên Kotlin
Bạn đã quá chán với việc thiết kế các row của recycler view có giống nhau Hôm nay mình sẽ hướng dẫn mọi người phá cách 1 chút , làm cho recycler trở nên khác biệt hơn Bên trái là khi recycler view sử dụng GridLayoutManager Bên phải là recycler view sử dụng StaggeredGridLayoutManager, đây ...
Bạn đã quá chán với việc thiết kế các row của recycler view có giống nhau Hôm nay mình sẽ hướng dẫn mọi người phá cách 1 chút , làm cho recycler trở nên khác biệt hơn
Bên trái là khi recycler view sử dụng GridLayoutManager Bên phải là recycler view sử dụng StaggeredGridLayoutManager, đây chính là thứ mình muốn giới thiệu với mọi người hôm nay
Ảnh demo
Dưới đây mình sẽ hướng dẫn mọi người cách thực hiện (chú ý là mình xài Kotlin nhé )
Tạo project mới với tên StaggeredGrid
Mở Gradle Scripts -> build.gradle và cấu hình như sau
implementation "com.android.support:recyclerview-v7:26.1.0" là thư viện RecyclerView
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 26 defaultConfig { applicationId "com.tuananh.staggeredgrid" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' implementation "com.android.support:recyclerview-v7:26.1.0" testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' }
Mở res -> layout -> activity_main và viết code như dưới đây. Layout gồm có 1 button refresh và 1 recyclerview
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_awidth="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" tools:context="com.tuananh.staggeredgrid.MainActivity"> <android.support.v7.widget.AppCompatButton android:id="@+id/btnRefresh" android:layout_awidth="wrap_content" android:layout_height="wrap_content" android:text="Refresh"/> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_awidth="match_parent" android:layout_height="match_parent"/> </LinearLayout>
Mở thư mục drawable và tạo 1 file xml custom_item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:awidth="1dp" android:color="#000"/> </shape>
Chúng ta sẽ thiết kế 1 layout gồm 2 thành phần là TextView và ImageView
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_awidth="wrap_content" android:id="@+id/rlRoot" android:layout_height="wrap_content" android:background="@drawable/custom_item_layout" android:padding="5dp"> <ImageView android:id="@+id/image" android:layout_awidth="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/name" android:layout_awidth="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="ABCD" android:textColor="#fff" android:textSize="20sp"/> </RelativeLayout>
Tạo 2 list name và image là personNameList và personImageList
Khởi tạo recycler view chú ý chúng ta sẽ dùng StaggeredGridLayoutManager làm layout manager chính cho nó .
val staggeredGridLayoutManager = StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL) recyclerView.layoutManager = staggeredGridLayoutManager Collections.shuffle(personImageList) val customAdapter = CustomAdapter(this, personNameList, personImageList) recyclerView.adapter = customAdapter
Bắt sự kiện cho button refresh để trộn list ảnh của recycler view
btnRefresh.setOnClickListener { Collections.shuffle(personImageList) customAdapter.notifyDataSetChanged() }
package com.tuananh.staggeredgrid import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.StaggeredGridLayoutManager import kotlinx.android.synthetic.main.activity_main.* import java.util.* class MainActivity : AppCompatActivity() { private var personNameList: MutableList<String> = mutableListOf( "Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6", "Person 7", "Person 8", "Person 9", "Person 10", "Person 11", "Person 12", "Person 13", "Person 14") private var personImageList: MutableList<Int> = mutableListOf( R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7, R.drawable.person8, R.drawable.person9, R.drawable.person10, R.drawable.person11, R.drawable.person12, R.drawable.person13, R.drawable.person14) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val staggeredGridLayoutManager = StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL) recyclerView.layoutManager = staggeredGridLayoutManager Collections.shuffle(personImageList) val customAdapter = CustomAdapter(this, personNameList, personImageList) recyclerView.adapter = customAdapter btnRefresh.setOnClickListener { Collections.shuffle(personImageList) customAdapter.notifyDataSetChanged() } } }
Trong bước này chúng ta sẽ set layout item cho recycler view là item_recycler_view.xml và gắn dữ liệu cho các item của recycler view trong onBindViewHolder
package com.tuananh.staggeredgrid import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import kotlinx.android.synthetic.main.item_recycler_view.view.* /** * Created by FRAMGIAvu.tuan.anh on 26/03/2018. */ class CustomAdapter(context: Context, private var personNameList: MutableList<String>?, private var personImageList: MutableList<Int>?) : RecyclerView.Adapter<CustomAdapter.MyViewHolder>() { private var layoutInflater: LayoutInflater = LayoutInflater.from(context) override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.name.text = personNameList!![position] holder.image.setImageResource(personImageList!![position]) holder.rlRoot.setOnClickListener { // todo } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder { return MyViewHolder(layoutInflater.inflate(R.layout.item_recycler_view, parent, false)) } override fun getItemCount(): Int { return personNameList!!.size } class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { val name = view.name!! val image = view.image!! val rlRoot = view.rlRoot!! } }
Dưới đây là 1 số hình ảnh trong demo
Code
http://abhiandroid.com/materialdesign/recyclerview-as-staggered-grid-example.html