Search code examples
multithreadingtimerrunnableandroid-handlerandroid-pageradapter

Android pager-adapter timer gets confused on user touch


i have a problem with my Pager adapter timer , when user touches to adapter,and if user slides the image ,its working fine. but ,if he doesn't slide the image , my timer is getting faster and sometimes goes to next image.

here is my pager adapter which i am using in the activity

 pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);



     myPager.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://starts with down

                //Log.e("TOUCH", "DOWN");
            break;
            case MotionEvent.ACTION_MOVE://moves finger
                //todo check ifts working
                if(pagerAdapter.timerworking){
                    Log.d("ACTION_MOVE", "currentPage"+pagerAdapter.currentPage);
                    pagerAdapter.stopTimer();
                }

                //Log.e("TOUCH", "MOVE");
                break;
            case MotionEvent.ACTION_UP://ends with up
                //current +1 e kayitli oldugu icin bir onceki olmali
                Log.d("ACTION_UP", "currentPage"+pagerAdapter.currentPage);
                pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(),  pagerAdapter.currentPage);
                //Log.e("TOUCH", "UP");
                break;
            case MotionEvent.ACTION_CANCEL:
                //Log.e("TOUCH", "CANCEL");
                break;
            default:
                break;
            }

            return false;
        }
    });

here is timer functions of my pager adapter(ImagePager)

 /**
 * this function swipes pages left to right for every 7 seconds
 * @param myPager
 * @param time
 * @param numPages we recommend that it should be as much as much objects.size()
 * @param curPage we recommend that it should start from 0
 * 
 */
public void setTimer(final ViewPager myPager, int time, final int numPages, final int curPage){


        currentPage = curPage;
        final Runnable Update = new Runnable() {
            int NUM_PAGES =numPages;
            public void run() {

                if(timerworking){
                    Log.d("PagerTimer", "currentPage"+currentPage);

                    myPager.setCurrentItem(currentPage, true);
                    currentPage=(currentPage+1)%NUM_PAGES;
                }
            }
        };

        swipeTimer = new Timer();
        swipeTimer.schedule(new TimerTask() {

            @Override
            public void run() {
                handler.post(Update);
            }
        }, 1000, time*1000);//1000 =1 saniyede gecis suresi , 7000 kac saniyede bir degisecek
        timerworking=true;
        Log.d("PagerTimer", "timerRUN");
}

/**
 * its kills runnable
 */
public void stopTimer(){
    //handler.removeCallbacks(null);
    swipeTimer.cancel();
    timerworking=false;
    Log.d("PagerTimer", "timerSTOP");
    /*
    clearTimer();
    swipeTimer=null;
    handler.removeCallbacksAndMessages(null);
    handler.removeCallbacks(null);
    */
}

my intent to make this slider automatically slide for every 7 seconds, if user touches to screen, i want it to stop the counter and when user release touch and goes back to automatically slide (countdown of 7 seconds starts again ).

my problem is when user touches and doesn't slide , it goes to next slide, and its counter gets faster.

EDIT: i have realized that , my timer is controlling 3 threads which changes my adapter quickly.i guess i am creating more threads every time user interrupt


Solution

  • by changing

     pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(),  pagerAdapter.currentPage);
    

    in the case MotionEvent.ACTION_UP to this

    if(!pagerAdapter.timerworking){
    
                        pagerAdapter.setTimer(myPager, 7, pagerAdapter.getCount(), pagerAdapter.currentPage);
                    }
    

    i have prevented multiple threads


    and also added function below to do image pager to get the current item to stay on it.

    public void setOnPageChangeListener(ViewPager myPager){
         myPager.setOnPageChangeListener(new OnPageChangeListener() {
    
                @Override
                public void onPageSelected(int arg0) {
                    //new page is selected , by the user or automatically
                    nextPage=(arg0)%NUM_PAGES;
                    Log.d("OnPageChange", "Selected Page is "+arg0);
                    Log.d("OnPageChange", "currentPage "+currentPage);
    
                }
    
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                }
    
                @Override
                public void onPageScrollStateChanged(int arg0) {
                }
            });
    }
    

    and calling line below , before the myPager.setOnTouchListener , in th activity

      pagerAdapter.setOnPageChangeListener(myPager);