如何将 "stop mediaplayer" 添加到导航后退按钮

How to add "stop mediaplayer" to a navigation back button

我是 android 工作室的新手,很抱歉,如果这是一个非常菜鸟的问题,但我无法在网上找到答案。非常感谢任何帮助!

我构建了一个有两个屏幕的小应用程序:一个主屏幕,一个第二屏幕。主屏幕仅用于导航到屏幕二。从其他屏幕,您可以 play/pause/stop 特定歌曲,或返回主屏幕。

我遇到的问题是当我导航到第二个屏幕时,当我按下“后退”按钮返回主屏幕时,我不知道如何向这个按钮添加“停止”方法.我已经按照一些在线教程设置了 mediacontroller,效果很好,但我被卡住了。

所以,我只需要将 onStop() 方法添加到后退按钮,这样当用户离开媒体播放器屏幕时,播放就会停止。

这是我的代码:

主要activity(播放、暂停、停止、stopPlayer、onStop方法)

 public void play(View v){
        if(player == null){
            player = MediaPlayer.create(this, R.raw.testmeditatie);
            player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopPlayer();
                }
            });
        }

    player.start();
}

public void pause(View v){
    if(player!= null){
        player.pause();
    }
}

public void stop(View v){
    stopPlayer();
}

private void stopPlayer(){
    if(player!=null){
        player.release();
        player = null;
        Toast.makeText(this, "MediaPlayer released", Toast.LENGTH_SHORT).show();
    }

}

@Override
protected void onStop() {

    super.onStop();
    stopPlayer();
}

第一个片段代码:

public class FirstFragment extends Fragment {
@Override
public View onCreateView(
        LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState


) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_first, container, false);
}

public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    super.onStop();

    view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            NavHostFragment.findNavController(FirstFragment.this)
                    .navigate(R.id.action_FirstFragment_to_SecondFragment);
        }
    });
    
}

第二个片段:

public class SecondFragment extends Fragment {

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false);
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavHostFragment.findNavController(SecondFragment.this)
                        .navigate(R.id.action_SecondFragment_to_FirstFragment);
            }
        });
    }

第二个按钮fragment.xml

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Play"
    android:onClick="play"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pause"
    android:onClick="pause"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Stop"
    android:onClick="stop"/>


<Button
    android:id="@+id/button_second"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/previous"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

只需覆盖 onBackPressed() 并调用 stopPlayer() 来释放媒体资源。

@Override
public void onBackPressed() {
    stopPlayer();
    super.onBackPressed();
}

更新:

因为您正在使用导航组件,所以 onBackPressed() 不会从第二个片段调用,除非您明确调用它。

为此,您可以创建一个由第二个片段实现的侦听器接口:

public interface IOnBackPressed {
    void onBackPressed();
}

然后在Second Fragment中实现:

public class SecondFragment extends Fragment implements IOnBackPressed {

    @Override
    public void onBackPressed() {
        stopPlayer();
    }

// rest of your code

}

然后你需要在按下后退按钮时显式调用第二个片段的onBackPressed();但这是在 MainActivity 中的 onBackPressed() 中触发的,如下所示:

public class MainActivity extends AppCompatActivity {

    @Override
    public void onBackPressed() {
        NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().getPrimaryNavigationFragment();

        if (navHostFragment != null) {
           // Getting the current fragment in the navGraph
           Fragment currentFragment = navHostFragment.getChildFragmentManager()
                                                     .getFragments().get(0); 
        
            /* Check if the Current fragment implements IOnBackPressed so it
               needs to consume the back before the MainActivity */
            if (currentFragment instanceof IOnBackPressed)
               ((IOnBackPressed) currentFragment).onBackPressed();
         }

         super.onBackPressed();

    }

// rest of your code

}

So, all I need is to add the onStop() method to the back button, so that when the user navigates away from the mediaplayer screen, the playing stops.

嗯,现在是了解 Android 生命周期的好时机。简而言之,当当前屏幕变得不可见时(比如您将应用程序置于后台),Lifecycle 方法之一 onStop() 将被调用,因此我们可以在其中做一些事情。

  1. 将所有MediaPlayer相关代码移动到SecondFragment.

  2. onStop() 中停止你的 MediaPlayer:

     override fun onStop() {
         super.onStop()
    
         stopPlayer()
     }
    

演示:https://youtu.be/XfadYTxKK3s

生命周期教程:https://youtu.be/UJN3AL4tiqw