java如何使媒体播放器在按设备后退按钮从片段返回活动时停止
我的问题是,当我按下设备后退按钮时,媒体播放器一直在播放。当按下设备后退按钮时,如何完全销毁碎片、媒体播放器和其中的所有内容,使其在屏幕上不可见
我是编程新手,所以欢迎所有关于如何改进代码的建议和评论。多谢各位
活动:
import 安卓x.appcompat.app.AppCompatActivity;
import 安卓x.fragment.app.FragmentManager;
import 安卓.os.Bundle;
import 安卓.view.View;
import 安卓.widget.Button;
public class MainActivity extends AppCompatActivity {
Button button1;
Button button2;
Button button3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fm= getSupportFragmentManager();
fragment1 fragment = new fragment1();
fm.beginTransaction()
.replace(R.id.container,fragment)
.addToBackStack(null)
.commit();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fm= getSupportFragmentManager();
fragment2 fragment= new fragment2();
fm.beginTransaction()
.replace(R.id.container,fragment)
.addToBackStack(null)
.commit();
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fm= getSupportFragmentManager();
fragment3 fragment= new fragment3();
fm.beginTransaction()
.replace(R.id.container,fragment)
.addToBackStack(null)
.commit();
}
});
}
}
片段:
import 安卓x.fragment.app.Fragment;
import 安卓.media.MediaPlayer;
import 安卓.view.LayoutInflater;
import 安卓.view.ViewGroup;
import 安卓.widget.Button;
import 安卓.os.Bundle;
import 安卓.widget.SeekBar;
import 安卓.os.Handler;
import 安卓.os.Message;
import 安卓.view.View;
import 安卓.widget.TextView;
import java.io.IOException;
public class fragment1 extends Fragment {
MediaPlayer mp;
Button play;
SeekBar seekBar;
TextView elapsedTimeLabel;
TextView remainingTimeLabel;
int totalTime;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_fragment1, container, false);
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource("https://firebasestorage.googleapis.com...");
} catch (IOException e) {
e.printStackTrace();
}
try {
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
final Button play = rootView.findViewById(R.id.play);
elapsedTimeLabel = rootView.findViewById(R.id.elapsedTimeLabel);
remainingTimeLabel = rootView.findViewById(R.id.remainingTimeLabel);
totalTime = mp.getDuration();
mp.seekTo(0);
seekBar = rootView.findViewById(R.id.seekBar);
seekBar.setMax(totalTime);
seekBar.setOnSeekBarChangeListener
(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mp.seekTo(progress);
seekBar.setProgress(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
);
new Thread(new Runnable() {
@Override
public void run() {
while (mp != null) {
try {
Message msg = new Message();
msg.what = mp.getCurrentPosition();
handler.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
}).start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer sound) {
play.setBackgroundResource(R.drawable.play);
}
});
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mp.isPlaying()) {
mp.pause();
play.setBackgroundResource(R.drawable.play);
} else {
mp.start();
play.setBackgroundResource(R.drawable.pause);
}
}
});
return rootView;
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
int currentPosition = msg.what;
seekBar.setProgress(currentPosition);
String elapsedTime = createTimeLabel(currentPosition);
elapsedTimeLabel.setText(elapsedTime);
String remainingTime;
remainingTime = createTimeLabel(totalTime - currentPosition);
remainingTimeLabel.setText("-" + remainingTime);
}
};
public String createTimeLabel(int time) {
String timelabel;
int min = time / 1000 / 60;
int sec = time / 1000 % 60;
timelabel = min + ":";
if (sec < 10) timelabel += "0";
timelabel += sec;
return timelabel;
}
public void play(View view) {
if (mp == null) {
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stopPlayer();
}
});
}
mp.start();
}
public void pause(View view) {
if (mp != null) {
mp.pause();
}
}
private void stopPlayer() {
if (mp != null) {
mp.release();
mp = null;
}
}
}
编辑:
我尝试了提供的解决方案,但不知何故,片段中的mediaplayer没有被破坏。当我回到片段时,其中的seekbar被重置,但音频文件仍在播放。当我再次按“播放”时,它会在上一个文件的基础上再次开始播放,以便同时播放两个文件
# 1 楼答案
在Fragment中,重写OnDestroy函数。然后在调用super之前停止玩家。onDestroy()
# 2 楼答案
每个片段都有一个
onDestroy()
回调,用于在片段从后堆栈弹出并销毁时进行回调。您可以从该方法调用stopPlayer()
# 3 楼答案
不幸的是,由于片段没有
onBackPressed()
方法,因此没有直接的方法可以做到这一点,您必须进行回调并在片段中实现它才能使其工作首先,您需要创建一个实现其接口的接口和类,以拥有一个泛型方法
OnBackPressedListener
打开反压侦听器。java
MainActivity
中,创建侦听器并为其创建一个setter,并在重写它之后在onBackPressed()
方法中使用它李>你的
MainActivity
应该是这样的主要活动。java
Fragment you should implement the
OnBackPressedListener`界面中,使用它停止播放机片段1。java
旁注
fragment1
名称重构为Fragment1
大写F