Reputation: 642
First, none of the solution worked provided on stackoverflow because of either change in the Android or my problem was totally different.
What I want to achive - I want to detect when my view (for example - ThirdFragment) comes in focus and becomes visible to user. Also, it should detect when user swipes away from the current view to next view or previous view.
Why I want to do that? - Well, I am creating a media player in one of the view as shown in the example fragment code and user can play any music listed in the view by tapping on the music in the list but when user swipes to next screen it should stop.
What is the problem? - The problem is mediaplayer doesn't stop right after switching from the view but [***] if I swipe two step away, it stops but not cleanly, it jitters in the background.
What I have tried before - I have tried this setUserVisibleHint but it wasn't working because it has been depricated. onPause, onDetach, onStop none is working as mentioned here[***]
/*------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();
}
}
}
Edit:
Thanks to @ianhanniballake for providing the solution.
It solved my problem "partially". I can stop the mediaplayer but I can't stop my observer observing the event on pause. code update
Upvotes: 1
Views: 2712
Reputation: 200120
You're passing in 0
as the behavior, which corresponds to the deprecated BEHAVIOR_SET_USER_VISIBLE_HINT
. By using that behavior, setUserVisibleHint()
will be called with true
when your fragment becomes the current page and false
when it is not.
If you switch to the not deprecated BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
, then only the current page will get onResume()
. When the page changes, that Fragment will get a callback to onPause()
and the newly active fragment will get a call to onResume()
.
Upvotes: 4