#android #android-studio #kotlin #android-fragments
Вопрос:
У меня есть класс, который воспроизводит звук при нажатии кнопки. Мне нужно остановить воспроизведение звука в методе onPause, но я не знаю, как вызвать функцию остановки класса во фрагменте.
В адаптере я называю музыку(значения).Кнопка воспроизведения() Во фрагменте, который я хочу вызвать Music().stop (), чтобы остановить звук, но для этого класса требуются параметры, которых нет во фрагменте
Как я могу вызвать этот метод во фрагменте?
Классная Музыка
class Music(var button: Button, val context: Context, val resources: Resources, val Id: Int, var buttonArray: MutableList<Button>, val mpArray: MutableList<MediaPlayer>) {
fun play() : MediaPlayer {
if (buttonArray.size >= 2) {
buttonArray.removeFirst()
}
if (mpArray.size >= 2) {
mpArray.removeFirst()
}
mpArray.add(MediaPlayer.create(context, Id))
buttonArray.add(button)
if (mpArray.size == 1 amp;amp; !mpArray[0].isPlaying) {
mpArray[0].start()
return mpArray[0]
} else if (mpArray.size == 2 amp;amp; buttonArray[0] == buttonArray[1]) {
if (mpArray[0].isPlaying) {
mpArray[0].pause()
mpArray[0].reset()
mpArray[0].release()
} else if (!mpArray[1].isPlaying) {
mpArray[1].start()
return mpArray[1]
}
}
if (mpArray.size == 2 amp;amp; buttonArray[0] != buttonArray[1]) {
if (mpArray[0].isPlaying) {
mpArray[0].pause()
mpArray[0].reset()
mpArray[0].release()
mpArray[1].start()
} else if (!mpArray[0].isPlaying) {
mpArray[1].start()
return mpArray[1]
}
}
return MediaPlayer.create(context, Id)
}
fun stop() {
if (play().isPlaying) {
play().stop()
play().release()
}
}
Адаптер
class Adapters(private val cards: List<Card>, val resources: Resources, val context: Context, private val musicPlayerListener: MusicPlayerListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var buttonArray = mutableListOf<Button>()
private var mpArray = mutableListOf<MediaPlayer>()
private lateinit var music: Music
fun playMusic() {
musicPlayerListener.onMusicPlay(music.play())
}
override fun getItemViewType(position: Int): Int = when(cards[position]) {
is Card.AudioButton -> 11
else -> throw IllegalArgumentException("Error")
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return object : RecyclerView.ViewHolder(
when(viewType) {
11 -> LayoutInflater.from(parent.context).inflate(R.layout.in_lesson_audio_button, parent, false)
else -> throw IllegalArgumentException("Error")
}) {
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(val card = cards[position]) {
is Card.AudioButton -> {
val button = holder.itemView.findViewById<Button>(R.id.in_lesson_audio_button)
button.setOnClickListener {
Music(button, context, resources, getAudioId(card.audioButton), buttonArray, mpArray).play()
}
}
}
}
override fun getItemCount() = cards.size
private fun getAudioId(audioElement: String): Int = resources.getIdentifier(audioElement, "raw", context.packageName)
}
Фрагмент
class Fragment : Fragment(), MusicPlayerListener {
private val args: DetailsFragmentArgs by navArgs()
var mMediaPlayer: MediaPlayer? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val binding = inflater.inflate(R.layout.fragment, container, false)
val recyclerView = binding.findViewById<RecyclerView>(R.id.list_view)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = Adapters(parseLesson(resources,R.xml.text), resources, requireContext() )
return binding
}
override fun onPause() {
super.onPause()
mMediaPlayer?.stop()
}
override fun onMusicPlay(mediaPlayer: MediaPlayer) {
mMediaPlayer = mediaPlayer
}
}
Комментарии:
1. Разве у вас нет экземпляра/объекта
Music
класса? Просто используйте его, чтобы остановить воспроизведение2. используйте интерфейс для передачи объекта музыкального класса фрагменту, а затем вызовите метод stop, используя этот объект.
3. @BilalNaeem Ты имеешь в виду что-то вроде этой музыки.остановись() в онПаузе?
4. @GeorgeKusenkov да
5. @BilalNaeem Я создаю объект Музыкального класса в Адаптере. Возникли трудности с вызовом этого объекта во фрагменте
Ответ №1:
Из адаптера при вызове Music.play()
он вернет экземпляр MediaPlayer , вы должны отправить его обратно во фрагмент и сохранить его во фрагменте в качестве локальной переменной. Затем из фрагмента используйте этот экземпляр MediaPlayer, чтобы вызвать stop()
его.
class ExampleAdapter(private val musicPlayerListener: MusicPlayerListener) {
private lateinit var music: Music
fun playMusic() {
musicPlayerListener.onMusicPlay(music.play())
}
}
class ExampleFragment : MusicPlayerListener {
var mMediaPlayer: MediaPlayer? = null
override fun onMusicPlay(mediaPlayer: MediaPlayer) {
mMediaPlayer = mediaPlayer
}
override fun onPause() {
super.onPause()
mMediaPlayer?.stop()
}
}
interface MusicPlayerListener {
fun onMusicPlay(mediaPlayer: MediaPlayer)
}
Комментарии:
1. Спасибо вам за ваш ответ. Я не совсем понимаю, как отправить это обратно в фрагмент. При объявлении в адаптере musicPlayerListener я должен добавить в RecyclerView.adapter фрагмент. Можете ли вы сказать мне, как отправить медиаплеер на фрагмент?
2. Вам нужен медиаплеер в том же фрагменте, где вы установили адаптер, или в другом?
3. Мне нужно поймать ссылку медиаплеера во фрагменте из адператора. Сценарий выглядит следующим образом: фрагмент 1 -> медиаплеер воспроизводится, перейдите к фрагменту 2 ->> медиаплеер не воспроизводится. К сожалению, я так и не смог реализовать его через интерфейс. Мне пришлось использовать синглтон. Но я думаю, что через интерфейс это все-таки правильнее