SoundPool 与 ImageView 的用法类似 Switch
SoundPool with ImageView Usage Like Switch
我在编写我的应用程序时卡住了,我找不到解决该问题的任何来源。
问题:我想使用图像视图作为开关。当我点击 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_width="match_parent"
android:layout_height="wrap_content"
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_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivMixCardImages"
android:layout_width="match_parent"
android:layout_height="0dp"
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_width="0dp"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
对于初次使用 soundpool 的用户来说,这是一个常见问题。如果您仔细查看 soundpool 的文档,播放使用参数“soundID”,而停止使用参数“streamID”。很容易忽略这一点,并像您的代码一样对这两个命令使用从加载函数返回的 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()
}
}
}
}
我在编写我的应用程序时卡住了,我找不到解决该问题的任何来源。
问题:我想使用图像视图作为开关。当我点击 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_width="match_parent"
android:layout_height="wrap_content"
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_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivMixCardImages"
android:layout_width="match_parent"
android:layout_height="0dp"
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_width="0dp"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
对于初次使用 soundpool 的用户来说,这是一个常见问题。如果您仔细查看 soundpool 的文档,播放使用参数“soundID”,而停止使用参数“streamID”。很容易忽略这一点,并像您的代码一样对这两个命令使用从加载函数返回的 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()
}
}
}
}