I have listView
with ringtones
I need change play_arrow
image to stop
image every time when music started or stoped. When I click play on one image it become stop
image and then I click play on other music item image so previous should become play_arrow
and just clicked one should become stop
. The problem is on getting views by position. Everything works great on first 12 music views. And if I try to get view like this parent.getChildAt(previousListened)
with previousListened > 12
it returns null.
EDIT: add adapter 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()
}
}
Is it possible to get item view of ListView
that is outside of visible part in Adapter class?
Is it possible to get item view of ListView that is outside of visible part in Adapter class?
No, you can't. ViewHolder exists only for visible items.
However, in your case, you only need to set your ImageView
image inside your getView
function.
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);
}
Then, call notifyDataSetChanged
viewHolder.ivPlay!!.setOnClickListener {
...
...
notifyDataSetChanged();
}
notifyDataSetChange
will update all visible items.
On the other hand, you don't need to save position
in tag
variable. You always know which item is clicked because your onClick
events are set in getView
function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.