Kotlin:如何使用 Spinner 将项目设置为 RecyclerViewAdapter?

Kotlin: How to set items to RecyclerViewAdapter with Spinner?

我正在尝试使用两个微调器函数对 Recyclerview 进行编码。 主要目标是显示两个微调器过滤的结果。 例如,有7个列表,每个列表都有一定的纪律,如"Architectural"、"Mechanical"、"Electrical"等,楼层数据如1、2、3、4..

所以,我编写了这样的代码

这是 recyclerview 的适配器。

class ProjectFilesModel(val fileName: String, val ctype: String, val floor: Int)

class FileDataViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer

class FileDataAdapter(val fileList: List<ProjectFilesModel>) :
    RecyclerView.Adapter<FileDataViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileDataViewHolder {

        val view =
            LayoutInflater.from(parent.context).inflate(R.layout.filtered_file, parent, false)

        return FileDataViewHolder(view)
    }

    override fun getItemCount(): Int {
        return fileList.count()
    }

    override fun onBindViewHolder(holder: FileDataViewHolder, position: Int) {
        holder.containerView.fileNameLayout.text = fileList[position].fileName
        holder.containerView.ctypeLayout.text = fileList[position].ctype
        holder.containerView.floorLayout.text = "${fileList[position].floor}floor"
    }
}

而且,这是主要的 Activity;

class MainActivity : AppCompatActivity() {

    //ctype option array
    var ctypeArray =
        arrayOf("All", "Architectural", "Mechanical", "Electrical", "Structural", "Civil")
    var ctypeOptionAdapter: ArrayAdapter<String>? = null

    //floor option arry
    var floorArray = arrayOf(1, 2, 3)
    var floorOptionAdapter: ArrayAdapter<Int>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ctypeOptionAdapter =
            ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, ctypeArray)
        ctypeOption.adapter = ctypeOptionAdapter

        floorOptionAdapter =
            ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, floorArray)
        floorOption.adapter = floorOptionAdapter

        ctypeOption.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {}

            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                if (position >= 0 && position < floorArray.size) {
                    getSelectedListData(position)
                } else {
                    Toast.makeText(
                        this@MainActivity,
                        "Selected Category Does not Exist!",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }

        val fileArrayList = arrayListOf(
            ProjectFilesModel("A_file", "Architectural", 1),
            ProjectFilesModel("B_file", "Mechanical", 1),
            ProjectFilesModel("C_file", "Electrical", 2),
            ProjectFilesModel("D_file", "Structural", 2),
            ProjectFilesModel("E_file", "Architectural", 2),
            ProjectFilesModel("F_file", "Mechanical", 3),
            ProjectFilesModel("G_file", "Electrical", 3)
        )

        val fileArrayAdapter = FileDataAdapter(fileArrayList)
        filteredListView.adapter = fileArrayAdapter
        filteredListView.layoutManager = LinearLayoutManager(this)

    }

    fun getSelectedListData(position: Int) {
        /* I'm stuck from here..*/
    }
}

我不确定我的方向是否正确..

请多多指教!

尝试如下。请参考评论。

适配器

class FileDataAdapter : RecyclerView.Adapter<FileDataViewHolder>() {
    var items : List<ProjectFilesModel> = listOf()
    set(value) {
        // implements setter for notifying item changed
        field = value
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileDataViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.filtered_file, parent, false)
        return FileDataViewHolder(view)
    }

    override fun getItemCount(): Int = items.count()

    override fun onBindViewHolder(holder: FileDataViewHolder, position: Int) {
        holder.containerView.fileNameLayout.text = fileList[position].fileName
        holder.containerView.ctypeLayout.text = fileList[position].ctype
        holder.containerView.floorLayout.text = "${fileList[position].floor}floor"
    }
}

Activity

class MainActivity : AppCompatActivity() {

    //ctype option array
    var ctypeArray =
        arrayOf("All", "Architectural", "Mechanical", "Electrical", "Structural", "Civil")
    var ctypeOptionAdapter: ArrayAdapter<String>? = null

    //floor option arry
    var floorArray = arrayOf(1, 2, 3)
    var floorOptionAdapter: ArrayAdapter<Int>? = null

    private val files = arrayListOf(
        ProjectFilesModel("A_file", "Architectural", 1),
        ProjectFilesModel("B_file", "Mechanical", 1),
        ProjectFilesModel("C_file", "Electrical", 2),
        ProjectFilesModel("D_file", "Structural", 2),
        ProjectFilesModel("E_file", "Architectural", 2),
        ProjectFilesModel("F_file", "Mechanical", 3),
        ProjectFilesModel("G_file", "Electrical", 3)
    )
    private val adapter by lazy {
        FileDataAdapter().apply {
            items = files
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ctypeOptionAdapter =
            ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, ctypeArray)
        ctypeOption.adapter = ctypeOptionAdapter

        floorOptionAdapter =
            ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, floorArray)
        floorOption.adapter = floorOptionAdapter

        ctypeOption.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {}

            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                //replace items in adapter to filtered list by selected CType
                //TODO : stored selected ctype & floor and update filtered list logic
                adapter.items = if(position == 0) files else files.filter {
                    it.ctype == ctypeArray[position]
                }
            }
        }

        //TODO : you should implement selected listener as below to filter files by floor 
        floorOption.onItemSelectedListener = ...


        filteredListView.adapter = adapter
        filteredListView.layoutManager = LinearLayoutManager(this)
    }
}

附加 - 组合两个过滤器

设置监听器

ctypeOption.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) {}

            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                invalidateItems()
            }
        }

floorOption.onItemSelectedListener = ... // same as ctypeOption

使用过滤器使函数无效

private fun invalidateItems() {
    //position == 0 isn't filter items by selected option
    val cTypeFilter: (ProjectFilesModel) -> (Boolean) = { item ->
        if (ctypeOption.selectedItemPosition != 0) item.ctype == ctypeArray[spinner.selectedItemPosition]
        else true
    }
    val floorFilter: (ProjectFilesModel) -> (Boolean) = { item ->
        if (floorOption.selectedItemPosition != 0) item.floor == floorArray[spinner.selectedItemPosition]
        else true
    }

    adapter.items = files.filter { cTypeFilter(it) && floorFilter(it) }
}