如何检查 Fragment 在 ViewPager 中是否可见?

How to check if a Fragment is visible in a ViewPager?

首先,none 在 Whosebug 上提供的解决方案有效,因为 Android 发生了变化,或者我的问题完全不同。

我想要实现的目标 - 我想检测我的视图(例如 ThirdFragment)何时聚焦并对用户可见。此外,它应该检测用户何时从当前视图滑动到下一个视图或上一个视图。

我为什么要这样做? - 好吧,我正在一个视图中创建一个媒体播放器,如示例片段代码所示,用户可以通过点击列表中的音乐来播放视图中列出的任何音乐,但是当用户滑动到下一个时屏幕它应该停止。

有什么问题吗? - 问题是媒体播放器在从视图切换后不会立即停止,但是 [***] 如果我滑动两步,它会停止但不干净,它在后台抖动。

我之前尝试过的 - 我已经尝试过 setUserVisibleHint 但它没有用,因为它已被删除。 onPause、onDetach、onStop none 正在按照此处所述进行工作[***]

/*------Home ViewPager----- */

public class HomeFragment extends Fragment {

    private ViewPager viewPager; 

    private String[] titles = {"First","Second","Third","Fourth"};

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView subtitle = getActivity().findViewById(R.id.toolbar_right_subtitle);
        subtitle.setText(titles[0]);
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

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

        /* pages */
        viewPager = view.findViewById(R.id.interfaces);
        InterfaceAdapter interfacePagerAdapter = new InterfaceAdapter(getActivity().getSupportFragmentManager(),0);
        viewPager.setAdapter(interfacePagerAdapter);
        viewPager.setCurrentItem(0);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                TextView subtitle = getActivity().findViewById(R.id.toolbar_right_subtitle);
                subtitle.setText(titles[position]); 
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    } 
}

    /*---------- My Fragment Adapter --------- */

    public class InterfaceAdapter extends FragmentStatePagerAdapter {

        public InterfaceAdapter(@NonNull FragmentManager fm, int behavior) {
            super(fm, behavior);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            switch (position){
                case 0:
                    return new FirstFragment();
                case 1:
                    return new SecondFragment();
                case 2:
                    return new ThirdFragment();
                case 3:
                    return new FourthFragment();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 4;
        }
    }


/*---------- One of my Fragment --------- */

public class ThirdFragment extends Fragment {

    //------Media Player ----------
    private MusicAdapter musicAdapter;
    private List<SongData> songsList;
    private ListView listView;
    private static MediaPlayer mediaPlayer;
    private Handler handler = new Handler();
    private Runnable runnable;
    private ImageView playButton, prevButton, nextButton;
    private SeekBar seekbarPayer;
    private TextView playerTime,songTitle;
    private int pos = 0;

    public ThirdFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        eventViewModels = new ViewModelProvider((FragmentActivity) getContext()).get(EventViewModels.class);
        mediaPlayer = new MediaPlayer();
        getAllSongs();
        return inflater.inflate(R.layout.fragment_focus, container, false);
    }

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

        //--------Music Player---------------
        mediaPlayer = new MediaPlayer();
        playButton = view.findViewById(R.id.playpause_player);
        prevButton = view.findViewById(R.id.prev_player);
        nextButton = view.findViewById(R.id.next_player);
        seekbarPayer = view.findViewById(R.id.seekbar_player);
        playerTime = view.findViewById(R.id.playertime);
        songTitle = view.findViewById(R.id.songname);
        songTitle.setSelected(true);

        songsList = new ArrayList<>();
        musicAdapter = new MusicAdapter(getActivity(), songsList);
        listView = view.findViewById(R.id.songList);
        listView.setAdapter(musicAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                pos = position;
                playMusicFile(songsList.get(position).getUri(),songsList.get(position).getTitle());
            }
        });

        //play or pause music
        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playPause();
            }
        });

        //next music
        nextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pos < songsList.size() - 1) {
                    pos++;
                } else {
                    pos = 0;
                }
                playMusicFile(songsList.get(pos).getUri(),songsList.get(pos).getTitle());
            }
        });

        //next music
        prevButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pos > 0) {
                    pos--;
                } else {
                    pos = songsList.size() - 1;
                }
                playMusicFile(songsList.get(pos).getUri(),songsList.get(pos).getTitle());
            }
        });
    } 

     @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        eventViewModels.getTrigger().observe((LifecycleOwner) getContext(), new Observer<Integer>() {
            @Override
            public void onChanged(@Nullable final Integer val) {
                assert val!=null;
                Log.d("ObserverValue",val+"");
            }
        });
    }




    @Override
    public void onStart() {
        super.onStart();
        getAllSongs();
        Log.d("SystemStatus","Start"); 
    } 

    @Override
    public void onResume() {
        super.onResume();
        getAllSongs();
        Log.d("SystemStatus","Resume"); 
    } 

    @Override
    public void onStop() {
        super.onStop();
        stopPlayer();
        Log.d("SystemStatus","Stop"); 
    }

    @Override
    public void onDetach() {
        super.onDetach();
        stopPlayer();
        Log.d("SystemStatus","Detach");
    }

    @Override
    public void onPause() {
        super.onPause();
        stopPlayer();
        Log.d("SystemStatus","Pause");   



    if (eventViewModels != null && eventViewModels.getTrigger().hasObservers()) {
     eventViewModels.getTrigger().removeObservers(this);
 } 
        }

    //---Media Player-----

    private void getAllSongs() {
       /*
        * get all songs and add it into songlist
        */
    }

    private void playMusicFile(String filePath,final String title){
        if(mediaPlayer!=null) {
            mediaPlayer.reset();
            try {
                mediaPlayer.setDataSource(filePath);
                mediaPlayer.prepareAsync();
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mp.start(); 
                    }
                });
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) { 
                        stopPlayer();
                    }
                }); 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 

    private void playPause() {
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start(); 
        }else {
            mediaPlayer.pause(); 
        }
    }

    private void stopPlayer() {
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
            mediaPlayer.reset(); 
        }
    } 

}

编辑:

感谢@ianhanniballake 提供解决方案。

它解决了我的问题"partially"。我可以停止媒体播放器,但无法阻止我的观察者暂停观察事件。 代码更新

您将 0 作为行为传递,这对应于已弃用的 BEHAVIOR_SET_USER_VISIBLE_HINT。通过使用该行为,当您的片段成为当前页面时,将使用 true 调用 setUserVisibleHint(),如果不是,则使用 false 调用。

如果切换到未弃用的 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,则只有当前页面会获得 onResume()。当页面更改时,该片段将回调 onPause(),新激活的片段将调用 onResume().