SoundPool 与 ImageView 的用法类似 Switch

Posted

技术标签:

【中文标题】SoundPool 与 ImageView 的用法类似 Switch【英文标题】:SoundPool with ImageView Usage Like Switch 【发布时间】:2021-03-09 20:12:11 【问题描述】:

我在编写应用程序时卡住了,我找不到任何解决该问题的资源。

问题:我想使用 imageview 作为开关。当我点击 imageView 我想启动我的 SoundPool.Player,如果我再次点击 imageView 那么它应该停止。

当我点击 imageView 时我可以启动声音,但我无法停止它。

class PlayerPool() 

lateinit var poolPlayer : SoundPool
var playerId : Int = 0

companion object 

    const val pageTag = "PlayerPool"
    var instance: PlayerPool? = null

    fun getInstance(context:Context): PlayerPool? 
        if(instance == null)
            instance = PlayerPool()
        return instance
    



fun poolStarter(ctx : Context, position: Int)

    poolPlayer = SoundPool.Builder().setMaxStreams(10).build()
    val poolSounds = poolPlayer.load(ctx,position,1)

    poolPlayer.setOnLoadCompleteListener  soundPool, sampleId, status ->

        playerId = poolPlayer.play(poolSounds, 0.1f, 0.1f, 1, 0, 1f)

    



fun poolPausePlayer()

        poolPlayer.stop(playerId)


class MixFragmentAdapter(
val mixList: ArrayList<SoundModel>,
val mixListener:RowClickListener<SoundModel>
) : BaseRecyclerAdapter<SoundModel,RowFragmentMixBinding>() 

override val layoutRes: Int
    get() = R.layout.row_fragment_mix
override val arrayList: ArrayList<SoundModel>
    get() = mixList

override fun bindView(
    binding: RowFragmentMixBinding,
    currentData: SoundModel,
    position: Int
) 

    binding.ivMixCardImages.setImageResource(mixList[position].soundImage)
    binding.root.setOnClickListener 

        mixListener.onClick(position, item = mixList[position])

        binding.switchMusicControl.setOnCheckedChangeListener  buttonView, isChecked ->

            if (isChecked)

                PlayerPool.getInstance(binding.ivMixCardImages.context)!!.poolStarter(binding.ivMixCardImages.context,position)

            
            else

                PlayerPool.getInstance(binding.ivMixCardImages.context)!!.poolPausePlayer()

            


        


    

<androidx.cardview.widget.CardView
    android:layout_
    android:layout_
    android:layout_margin="6dp"
    app:cardCornerRadius="20dp"
    app:cardBackgroundColor="#7E57C2"
    app:cardElevation="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvMixSounds" >
    
    <androidx.constraintlayout.widget.ConstraintLayout 
        android:layout_
        android:layout_>

        <ImageView
            android:id="@+id/ivMixCardImages"
            android:layout_
            android:layout_
            android:padding="10dp"
            android:backgroundTint="@android:color/white"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintBottom_toTopOf="@+id/tvCardInformation"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvMixCardInformation"
            app:layout_constraintTop_toTopOf="parent"
            android:src="@drawable/ic_fire" />


        <TextView
            android:id="@+id/tvMixCardInformation"
            android:layout_
            android:layout_
            android:layout_marginTop="10dp"
            android:textSize="16sp"
            android:textStyle="bold"
            android:gravity="center"
            android:visibility="gone"
            android:text="Ateş!"
            app:layout_constraintTop_toBottomOf="@id/ivMixCardImages"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Switch
            android:id="@+id/switchMusicControl"
            android:layout_
            android:layout_
            android:visibility="gone"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

【问题讨论】:

要确定问题是否与点击或其他问题有关,请执行以下操作lifeCycleScope.launch delay(2000) PlayerPool.getI...//the pause 【参考方案1】:

对于第一次使用 soundpool 的用户来说,这是一个常见问题。如果您仔细查看 soundpool 的文档,play 使用参数“soundID”,而 stop 使用参数“streamID”。很容易忽略这一点,并使用从 load 函数返回的 soundID 用于两个命令,就像您的代码一样。我什至见过 android 教程示例弄错了。而是使用这些命令:

s1 = sound.load(Main.this, R.raw.mosq1, 1);  
if (l1==true)p1=sound.play(s1, 1, 1, 0, rep, 1);     
sound.stop(p1);

必须确保p1 是正确的。

关于您的代码:

    fun poolStarter(ctx : Context, position: Int)
    ....
    poolPlayer.setOnLoadCompleteListener  soundPool, sampleId, status ->

        playerId = poolPlayer.play(poolSounds, 0.1f, 0.1f, 1, 0, 1f)

    

    fun poolPausePlayer()
            poolPlayer.stop(playerId)
    

在使用的时候,一定要保证playerId是一样的。

尝试在 MixFragmentAdapter 中更改您的代码:

    lateinit var p:PlayerPool
    override fun bindView(
        binding: RowFragmentMixBinding,
        currentData: SoundModel,
        position: Int
    ) 

        var context = binding.ivMixCardImages.context
        p =PlayerPool.getInstance(context)!!
        binding.ivMixCardImages.setImageResource(mixList[position].soundImage)
        binding.root.setOnClickListener 
            mixListener.onClick(position, item = mixList[position])
            binding.switchMusicControl.setOnCheckedChangeListener  buttonView, isChecked ->
                if (isChecked)
                    p.poolStarter(context, position )
                
                else
                    p.poolPausePlayer()
                
            

        
    

【讨论】:

对不起,我试过你的代码示例。 "p.poolStarter()" 返回 "kotlin.unit" 而不是 Int 。我无法解决问题所在,顺便说一下,我是编码新手。老实说,我很困惑,因为我找不到任何关于 SoundPool 足够好的文档。 p:PlayerPool 更改为全局变量并在外部初始化它就可以了。已更新代码可能会解决问题。但是“p.poolStarter()”似乎没有返回,如果出现问题可以发布代码或错误日志。

以上是关于SoundPool 与 ImageView 的用法类似 Switch的主要内容,如果未能解决你的问题,请参考以下文章

SoundPool 中的流音量与 AudioManager 中的音量

SoundPool 没有播放?

onTouch 与多点触控和 SoundPool 运动事件

使用SoundPool播放音效

Soundpool 停止问题?

SoundPool play() 块渲染