今天打算實作按按鈕可以更換 Layout 的樣式。讓我們來看看怎麼實作吧。
MainActivity.kt
lateinit var layoutManager: GridLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
layoutManager = GridLayoutManager(this,1)
val adapter = ImageAdapter(this, DataSevice.loadingforlargelayout(), layoutManager)
mainRecyclerView.layoutManager = layoutManager
mainRecyclerView.adapter = adapter
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.menu_switch_layout){
changeSpanCount(item)
return true
}
return super.onOptionsItemSelected(item)
}
private fun changeSpanCount(item: MenuItem) {
if (layoutManager.spanCount == 1 ) {
layoutManager.spanCount = 2
item.icon = ContextCompat.getDrawable(this, R.drawable.onerow)
}else {
layoutManager.spanCount = 1
item.icon = ContextCompat.getDrawable(this, R.drawable.twoinrow)
}
}
我們用了一個 Menu 做了一個 Item 讓使用者按下。
當使用者按下 Item 時,我們執行 changeSpanCount 這個 function 。
我們會判斷當前 layoutManager.spanCount 的狀態去做變換,同時也會把 icon 換掉。
但這個功能最重要的關鍵的地方在 Adapter 裡。
class ImageAdapter(val context: Context, val imageList:List<ImageData>, val layoutManager: GridLayoutManager): RecyclerView.Adapter<ImageAdapter.ViewHolder>() {
val ONE_VIEW_ROW = 1
val TWO_VIEW_ROW = 2
override fun getItemViewType(position: Int): Int {
when(layoutManager.spanCount) {
1 -> return ONE_VIEW_ROW
else -> return TWO_VIEW_ROW
}
}
inner class ViewHolder(itemView: View, val viewType: Int): RecyclerView.ViewHolder(itemView) {
fun bindView(imageData: ImageData) {
when (viewType) {
1 -> {
val resourceId = context.resources.getIdentifier(imageData.imageSource, "drawable", context.packageName)
Glide.with(context)
.load(resourceId)
.into(itemView.niceViewImage)
itemView.niceViewTextView.text = imageData.imageName
itemView.likeTextView.text = imageData.likeCount
itemView.commitTextView.text = imageData.commitCount
}
2 -> {
val resourceId = context.resources.getIdentifier(imageData.imageSource, "drawable", context.packageName)
Glide.with(context)
.load(resourceId)
.into(itemView.smallImageView)
itemView.smallTextView.text = imageData.imageName
}
}
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
when (viewType) {
1 -> {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.image_large, viewGroup, false)
return ViewHolder(view, viewType)
}
else -> {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.image_small, viewGroup, false)
return ViewHolder(view, viewType)
}
}
}
override fun getItemCount(): Int {
return imageList.size
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
viewHolder.bindView(imageList[position])
}
}
首先我們看到我們的 Adapter 需要三個參數,分別是 context, imageList, layoutManager 下面我們就可以看到他們在哪裡發揮作用了。
我們 override getItemViewType 來判斷當前使用的 layout 適用哪個樣式。
這時 RecyclerView 在 CreateViewHolder 的時候就能利用 ViewType 來判斷我要創造哪一種 ViewHolder 同時也要傳值給 ViewHolder 讓 ViewHolder 判斷要載入那些資料。
這次我們載入 Image 是採用 Glide 這個 3rd library 。效果意外不錯且方便。
下次我們在專文討論這個套件囉。
在 ViewHolder 判斷完要載入什麼資料後,這個功能就算完成了。
今天就先這樣囉。我們明天見~~