I have an android project that is using fragments and a viewpager.
I am using a separate countdown timer for every page, that only runs when the view of the page is 'onscreen'. At first the time for every page is the same, but after a while page 1 might be 20 seconds left, page 2 60 seconds and so on.
My problem is that I don't know how to save the remaining time, the moment the user swipes to the next page. I am using a onpagestatelistener that has the following code, but this is saving the new value of questionId and the old value of the new time. How do I refer to the value of the questionId and the matching newtime-value of the page that was in view before the user swiped?
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
saveTime();
}
}
public void onPageScrolled(int position, float arg1, int arg2) {}
public void onPageSelected(int pos) {
questionId = mQuestions.get(pos).getNr()
runTime();
}
});
public void saveTime(){
mQuestions.get(questionId).setTime(newTime);
}
public void runTime(){
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
mTimer = new CountDownTimer(90000, 1000) {//MillisInFuture, countDownInterval
public void onTick(long millisUntilFinished) {
newTime = (millisUntilFinished/1000);
}
public void onFinish() {
}
}.start();
}
First of all you can use SharedPreferences.
Besides, of course you can save data in adapter which you use for ViewPager, you can save this data in DB or create some singleInstance in your parent Activity or Fragment.
Related
CONTEXT:
I have one activity, 4 fragments and a viewPager (each page consists of one fragment). Each fragment contains a list of short sounds (max 5 seconds each). The expected behavior is: if the user clicks on a sound on a certain page and the sound did not finish playing, if the user swipes to another page, the media player will be released, thus the sound will stop playing.
ISSUE:
When swiping left or right, the method onPause or onStop are not called (since the viewPager by definition loads the current, the previous and the next page), thus the media player playing the sound from the last page does not stop on swipe.
RESEARCH:
I have searched a lot on multiple posts, related to onPageChangeListener, setOffScreenPageLimit, set MediaPlayer not in fragment but in the activity (not possible in my case, since I have lists of sounds with adapter). Here are some links that I researched but did not solve my problem: ViewPager swipe previous sound, Multiple video players in viewpager in android, Android MediaPlayer on ViewPager blocking UI transition and no callback for initial page loads, How to handle MediaPlayer object inside a fragment inside view pager, Using Viewpager with MediaPlayer
SUGGESTIONS?: if you have any suggestions on how to tackle this issue, it would be highly appreciated! Thanks!
You can create a Callback interface on your MainActivity with a method onPageChanged() like this:
public interface Callback {
void onPageChanged();
}
Then, you can use this OnPageChangeListener:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int currentPage = 0;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Fragment fragment = adapter.getItem(currentPage);
if (fragment instanceof Callback &&
currentPage != position) {
((Callback)adapter.getItem(currentPage)).onPageChanged();
}
currentPage = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Each and every Fragment in your ViewPager can be created like this:
public class TestFragment extends Fragment implements MainActivity.Callback {
private void releaseMediaPlayer() {
// ...
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// ...
}
#Override
public void onPageChanged() {
releaseMediaPlayer();
// You can do more things here
}
}
After doing that, every time that you change the Fragment on the ViewPager it will be calling the onPageChanged method on the previous Fragment, and in there you can release your media player and do any other operation that you require.
private int currentPos = 0;
private int prevPos = -1;
global variable
I am getting same problem. I have take two method play and stop in fragment. and call below code in onPageSelected(int position)
new Thread(new Runnable() {
#Override
public void run() {
try {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
prevPos = currentPos;
currentPos = position;
MyFragment fragment = (MainFragment) getChildFragmentManager().
findFragmentByTag("android:switcher:" + R.id.viewPagerVideo + ":" + prevPos);
if (fragment != null) {
fragment.stop();
}
fragment = (MyFragment) getChildFragmentManager().
findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + currentPos);
if (fragment != null) {
fragment.play(mListUrl.get(position));
}
}
});
} catch (Exception ignore) {
}
}
}).start();
Consider you making the fragment itself an OnPageChangeListener. Then you can set the listener when you attach the page. This will allow you to pass the page change information to the fragment. You are allowed to have more than one OnPageChangeListener. Hope that helps.
EDIT:
Consider something like this.
public class PageFragment extends Fragment implements ViewPager.OnPageChangeListener {
ViewPager pager;
public void onPageScrollStateChanged (int state){
// reset the player if needed. you can do this since player object is in this class
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
....
pager = (ViewPager) getActivity().findViewById(ViewPagerId);
pager.addOnPageChangeListener(this);
....
}
#Override
public void onDestroyView (){
....
pager.removeOnPageChangeListener(this);
....
}
}
Hi I am using ViewPager for auto swiping of 10 Text Quotes.When I open a app it starts from IMAGE1.Then it is keep on swiping upto the 10th quote.Let us consider,the viewpager showing 5th quote. Now I close it. When I open the app again it is starts from the first quote. But I need to show 6th Quote.
How do I resume the quote from where I have left before.
Quote 1:
Quote 5:
Quote 6:
UPDATE
int count=0;
int pager_position;
private void setTime_ToSlide() {
TextSlideShowAdapter adapter = new TextSlideShowAdapter(MainActivity.this, title1, title2);
myPager = (ViewPager) findViewById(R.id.reviewpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
Log.e("TEST", "Title Value Main " + title1 + " Title 2" + title2);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (count1 <= 56) {
myPager.setCurrentItem(count1);
pager_position = myPager.getCurrentItem();
Log.e("Get current item", String.valueOf(myPager.getCurrentItem()));
count1++;
} else {
count1 = 0;
myPager.setCurrentItem(count1);
}
}
});
}
}, 500, 3000);
}
#Override
protected void onPause() {
super.onPause();
saveCurrentPagePosition();
Log.e("Get SharedPreference ", String.valueOf(pager_position));
}
#Override
protected void onResume() {
super.onResume();
//...
setCurrentPagePosition();
}
private void setCurrentPagePosition() {
myPager.setCurrentItem(pager_position);
}
private void saveCurrentPagePosition() {
// store current page position in shared preference
SharedPreferences.Editor editor = pref.edit();
editor.putInt("PagerPosition", pager_position);
editor.commit();
}
store your page position in sharedpreferences in onPause method and when you come back to app get page value from preferences and use that value to set current item
viewPager.setCurrentItem(postion from preferences);
As Ajinkya said store the current position of your pager in shared preference in onPause() of your Activity/Fragment.
#Override
public void onPause() {
super.onPause();
saveCurrentPagePosition();
}
Fetch the stored position in your Activity/Fragment onResume() and set the current position for ViewPager like
#Override
protected void onResume() {
super.onResume();
//...
setCurrentPagePosition();
}
Helper methods -
private void setCurrentPagePosition() {
// fetch from shared prefs or set default as 0
viewPager.setCurrentItem(postion_from_preferences);
}
private void saveCurrentPagePosition() {
// store current page position in shared preference
}
At the moment, i have a viewpager,when page scroll,i have load api for get new information.
But in the first load viewpager,progress loading display two twice because it load first page and next page.
I only want to load the first page in viewpager.
How must I do?
best way is to create one interface. and implement this interface to all fragment.
e.g.
public interface FragmentInterface {
void fragmentBecameVisible();
}
in ur viewpager activity put like this e.g
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener(){
#Override
public void onPageSelected(int position){
FragmentInterface fragment = (FragmentInterface) mAdapter.instantiateItem(viewPager, position);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2){
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
in your fragment like
public class TestFragmet extends Fragment implements FragmentInterface {
#Override
public void fragmentBecameVisible() {
// your task to execute
}
}
Put OffScreenPageLimit to ZERO. It won't load other fragments.
viewPager.setOffscreenPageLimit(0);
I am using FragmentStatePagerAdapter and I need to get the current fragment. So every time I swipe to a new page I need to get some data from that fragment.
So this is what I did on pageChange:
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
Log.v("vp id",String.valueOf(mViewPager.getId()));
ArticleSwipableObjectFragment fragment =
(ArticleSwipableObjectFragment) getFragmentManager().findFragmentByTag(
"android:switcher:"+R.id.pager+":"+mViewPager.getCurrentItem());
if(fragment != null) // could be null if not instantiated yet
{
if(fragment.getView() != null)
{
String shareUrl = fragment.getShareUrl();
android.util.Log.v("share url",shareUrl);
}
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
Though I receive fragment as null.
Any suggestions where I am going wrong?
Try the following:
(<yourFragmentType>)pageradapter.getItem(myViewPager.getCurrentItem());
that will get the object in the Array that the adapter has a reference to.
Please use Interface and callBack method then resolve your problem.
hi mate i have to know when a page is no longer the current.
i think that i have to use Listener, i see that exist:
#Override
public void onPageSelected(int position) {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
but there arent listener to know when page X is no longer active
I think you can use onPageScrolled method to understand that the active page was changed.
From the documentation:
This method will be invoked when the current page is scrolled, either as part of a
programmatically initiated smooth scroll or a user initiated touch scroll.
Therefore onPageScrolled method should do the trick.
Not sure what you mean by "no longer active" but the onPageSelected gives the new index so you could do something like this:
private currentPage = 0;
public void onPageSelected(int position) {
if(position != currentPage){ //page has changed to
currentPage = position;
}
}