【问题标题】:Calling a Method in a Fragment在片段中调用方法
【发布时间】:2021-10-08 10:38:52
【问题描述】:

我有一个在单击按钮时播放声音的类。我需要在onPause方法中停止播放声音,但我不知道如何调用片段中类的停止函数。

在适配器中我调用 Music(values).playButton() 在片段中我想调用 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 && !mpArray[0].isPlaying) {
        mpArray[0].start()
        return mpArray[0]
    } else if (mpArray.size == 2 && 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 && 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
}

}

【问题讨论】:

  • 您没有Music 类的实例/对象吗?只需使用它来停止播放
  • 使用接口将 Music 类对象传递给片段,然后使用该对象调用 stop 方法。
  • @BilalNaeem 你的意思是类似于 onPause 中的 music.stop() 吗?
  • @GeorgeKusenkov 是的
  • @BilalNaeem 我在适配器中创建了 Music 类的对象。难以在 Fragment 中调用此对象

标签: android android-studio kotlin android-fragments


【解决方案1】:

当您调用Music.play() 时,适配器会从适配器返回一个MediaPlayer 实例,您应该将其发送回fragment 并将其作为局部变量保存在fragment 中。 然后从片段中,使用该 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)
}

【讨论】:

  • 感谢您的回答。我不太明白如何将其发送回片段。在适配器 musicPlayerListener 中声明时,我必须在片段中添加到 recyclerView.adapter。你能告诉我如何将媒体播放器发送到片段吗?
  • 您需要媒体播放器在您设置适配器的同一片段中还是在不同片段中?
  • 我需要从 adperator 获取片段中媒体播放器的链接。场景如下:片段 1 -> 媒体播放器正在播放,转到片段 2 -> 媒体播放器没有播放。不幸的是,我永远无法通过接口实现它。我不得不使用单例。但是我觉得通过界面还是比较正确的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多