Как получить представление внутри класса адаптера, который не находится в видимой части ListView?- Котлин - PullRequest
0 голосов
/ 07 мая 2019

У меня есть listView с мелодиями звонка

listView

Мне нужно изменить play_arrow изображение на stop изображение каждый раз, когда музыка запускается или останавливается.Когда я нажимаю кнопку воспроизведения на одном изображении, оно становится stop изображением, а затем я нажимаю кнопку воспроизведения на другом изображении музыкального элемента, поэтому предыдущее должно становиться play_arrow, а при щелчке одно становится stop.Проблема в том, чтобы получить взгляды по позиции.Все отлично работает на первых 12 музыкальных просмотров.И если я пытаюсь получить вид, подобный этому parent.getChildAt(previousListened) с previousListened > 12, он возвращает ноль.

РЕДАКТИРОВАТЬ: добавить класс адаптера

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()
    }
}

Возможно липолучить представление элемента ListView, которое находится за пределами видимой части в классе адаптера?

1 Ответ

1 голос
/ 08 мая 2019

Возможно ли получить представление элемента ListView, которое находится за пределами видимой части в классе адаптера?

Нет, ты не можешь. ViewHolder существует только для видимых элементов.

Тем не менее, в вашем случае вам нужно всего лишь установить ваше изображение ImageView в вашей функции getView.

    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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...