如何在不在 ListView 可见部分的适配器 class 中获取视图? - 科特林

How get view inside adapter class that is not in visible part of ListView? - Kotlin

我有 listView 铃声

每次音乐开始或停止时,我都需要将 play_arrow 图像更改为 stop 图像。 当我在一张图片上单击播放时,它变成了 stop 图片,然后我在其他音乐项目图片上单击播放,所以上一张应该变成 play_arrow 而刚刚点击的一张应该变成 stop。 问题在于按位置获取视图。在前 12 个音乐视图中,一切都很好。如果我尝试使用 previousListened > 12 获得这样的视图 parent.getChildAt(previousListened) 它 returns null.

编辑: 添加适配器 class

class SoundListAdapter constructor(
    private var context: Context,
    private val layout: Int,
    private var arrayList: ArrayList<Sound>,
    private val activity: FragmentActivity,
    private val mediaPlayer: MediaPlayer
) : BaseAdapter() {

    private var selectedPosition = -1
    private var currentListened = -1
    private var previousListened = -1
    private var isPlaying = false
    private var TAG = "SoundListAdapter"
    private val mSendSoundUri: SendSoundUri = activity as SendSoundUri

    interface SendSoundUri {
        fun sendSoundUri(input: String?)
    }

    override fun getCount(): Int {
        return arrayList.size
    }

    override fun getItem(i: Int): Any {
        return ""
    }

    override fun getItemId(i: Int): Long {
        return i.toLong()
    }

    private inner class ViewHolder {
        internal var radioButton: RadioButton? = null
        internal var txtName: TextView? = null
        internal var ivPlay: ImageView? = null
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var convertView = convertView
        val viewHolder: ViewHolder
        if (convertView == null) {
            viewHolder = ViewHolder()
            val layoutInflater = context.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater

            convertView = layoutInflater.inflate(layout, null)
            viewHolder.txtName = convertView!!.findViewById(R.id.sound_name)
            viewHolder.radioButton = convertView.findViewById(R.id.sound_radiobutton)
            viewHolder.ivPlay = convertView.findViewById(R.id.ivPlay) as ImageView

            convertView.tag = viewHolder
        } else {
            viewHolder = convertView.tag as ViewHolder
        }

        //check the radio button if both position and selectedPosition matches
        viewHolder.radioButton?.isChecked = (position === selectedPosition)
        // TODO add color to checked circle
        //Set the position tag to both radio button and label
        viewHolder.radioButton?.tag = position
        viewHolder.ivPlay?.tag = position
        viewHolder.txtName?.tag = position

        viewHolder.radioButton?.setOnClickListener { v -> itemCheckChanged(v) }

        viewHolder.txtName?.setOnClickListener { v -> itemCheckChanged(v) }

        val music = arrayList[position]

        viewHolder.txtName!!.text = music.title

        // play music
        viewHolder.ivPlay!!.setOnClickListener {
            previousListened = currentListened
            currentListened = it.tag as Int
            // TODO add black square when playing
            Log.d(TAG, "max items: ${parent.childCount}")
            Log.d(TAG, "previousListened: $previousListened")
            if (previousListened != -1 && previousListened == currentListened && mediaPlayer.isPlaying) {
                mediaPlayer.stop()
            } else {
                mediaPlayer.reset()
                mediaPlayer.setDataSource(context, Uri.parse(music.uri))
                mediaPlayer.prepare()
                mediaPlayer.start()
            }

        }

        return convertView
    }

    private fun getSelectedSound(): Sound? {
        Log.d(TAG, "sending selectedPosition: $selectedPosition")
        if (selectedPosition == -1)
            return null
        return arrayList[selectedPosition]
    }

    private fun itemCheckChanged(v: View) {
        selectedPosition = v.tag as Int
        mSendSoundUri.sendSoundUri(getSelectedSound()?.uri)
        Log.d(TAG, "selectedPosition changed to: $selectedPosition")
        notifyDataSetChanged()
    }
}

是否可以在适配器 class 的可见部分之外获取 ListView 的项目视图?

是否可以获取 Adapter 中可见部分之外的 ListView 的项目视图 class?

不,你不能。 ViewHolder 只存在于可见的项目中。

但是,对于您的情况,您只需要在 getView 函数中设置 ImageView 图像。

    if (currentListened == position) {
       // set here your Stop image 
        viewHolder.ivPlay.setImageResource(R.drawable.stop);
    } else {
       // set here your Play image
        viewHolder.ivPlay.setImageResource(R.drawable.play);
    }

然后,调用notifyDataSetChanged

    viewHolder.ivPlay!!.setOnClickListener {
        ...
        ...
        notifyDataSetChanged();
    }

notifyDataSetChange 将更新所有可见项目。

另一方面,您不需要将 position 保存在 tag 变量中。您始终知道点击了哪个项目,因为您的 onClick 事件是在 getView 函数中设置的。