iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 27
0

LayoutSwitch

LayoutSwitch

今天打算實作按按鈕可以更換 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 判斷完要載入什麼資料後,這個功能就算完成了。

今天就先這樣囉。我們明天見~~


上一篇
Day26_Thread, Handler, Runnable 簡介
下一篇
Day28_TransitionActivity
系列文
發現新大陸-Android Kotlin 開發之路30

尚未有邦友留言

立即登入留言