1

I want horizontal swipe gestures to control media player seek like mx player. I have tried gesture detector but didn't work like mx player. Any kind of help will be highly appreciated.

This is the class with gesture detector and scale gesture detector. With gesture detector horizontal scroll i cant get responsive scroll.

     public class OnSwipeTouchListener  implements View.OnTouchListener {


                private static final int SWIPE_THRESHOLD = 60;//threshold of swipe
                public static final int SWIPE_LEFT = 1;
                public static final int SWIPE_RIGHT = 2;
                private final GestureDetector gestureDetector;
                ScaleGestureDetector mgesturedetector;
                Context context;


                private boolean isSingleTouch;
                private float width, height = 0;
                private float scale = 1.0f;
                private float minScale = 0.8f;
                private float maxScale = 4.0f;

                int amount  = 0;






                public OnSwipeTouchListener(Context ctx) {
                    gestureDetector = new GestureDetector(ctx, new GestureListener(ctx));
                    mgesturedetector = new ScaleGestureDetector(ctx , new ScaleListener(ctx));
                    this.context = ctx;
                }



                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {


                    if(motionEvent.getPointerCount()>1)
                    {
                        mgesturedetector.onTouchEvent(motionEvent);
                    }
                    else
                        {
                        gestureDetector.onTouchEvent(motionEvent);
                    }
                    ontouch(view,motionEvent);
                    return true;
                }

                public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

                    private Context mContext;


                    public ScaleListener(Context context) {

                        this.mContext = context;


                    }


                    @Override
                    public boolean onScaleBegin(ScaleGestureDetector detector) {

                        onscalebegin();
                        return true;
                    }

                    @Override
                    public void onScaleEnd(ScaleGestureDetector detector) {
                        onscalend(scale);
                    }

                    @Override
                    public boolean onScale(ScaleGestureDetector detector) {




                        scale *= detector.getScaleFactor();
                        scale = (scale < 0.8f ? 0.8f : scale); // prevent our view from becoming too small //
                        scale = ((float)((int)(scale * 100))) / 100;


                        onscale(scale);

                        return true;
                    }

                }


                private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

                    private static final int SWIPE_THRESHOLD = 60;
                    private Context context;



                    public GestureListener(Context context) {
                        this.context = context;


                    }


                    @Override
                    public boolean onDoubleTap(MotionEvent e) {
                        ondoubletap();

                        return false;
                    }

                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }

                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent e) {
                       onsingleTapConfirmed();
                        return false;
                    }


                    @Override
                    public boolean onScroll(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {


                            float deltaX = e1.getRawX() - e2.getRawX();
                            float deltaY = e1.getRawY() - e2.getRawY();




                                if (Math.abs(deltaY) > SWIPE_THRESHOLD) {
                                    if (e1.getX() < getDeviceWidth(context) /2) {//left edge
                                        onVerticalScroll(deltaY / getDeviceHeight(context), SWIPE_LEFT);
                                    } else if (e1.getX() > getDeviceWidth(context) /2) {//right edge
                                        onVerticalScroll(deltaY / getDeviceHeight(context), SWIPE_RIGHT);
                                    }
                            }

                        return true;
                    }




                }



                void onsingleTapConfirmed(){}
                boolean ontouch(View view, MotionEvent event){
                    return false;
                }

                void ondoubletap(){}
                public void onHorizontalScrollRight(float percent) {}
                public void onHorizontalScrollLeft() {}


                void onVerticalScroll(float percent, int direction){}

                void onscale(Float scale){}
                void onscalebegin(){}
                void onscalend(float scale){}
                void onscroll(float x , float y){}
                void onscrollend(){}


            }



        this is the MediaPlayerActivity code in which above class is implemented:








     view.setOnTouchListener(new OnSwipeTouchListener(this){



                @Override
                void onscalebegin() {
                    isScrolling = true;
                }

                @Override
                void onscalend(float scale) {
                    isScrolling = false;
                    scale2 = scale;


                }

                @Override
                void onscale(Float scale) {

                    onScale(scale);
                }

                @Override
                boolean ontouch(View view,MotionEvent event) {

                    int action = (MotionEventCompat.getActionMasked(event)  );

                    float currentX      = 0.0f;
                    float currentY      = 0.0f;

                    float current_diffX = 0.0f;
                    float current_diffY = 0.0f;
                    boolean result = false;





                    if (event.getPointerCount() > 1) {
                        isScrolling = true;


                    }


                    switch (action ) {
                        case MotionEvent.ACTION_UP:
                            mCurVolume = -1;
                            mCurBrightness = -1;
                            mCenterLayout.setVisibility(GONE);
                            brightnesswrapper.setVisibility(GONE);
                            volumewrapper.setVisibility(GONE);

                            isScrolling = false;
                            verticalscroll = false;
                            horizontalscroll = false;

                            result =true;
                            break;
    //
                        case MotionEvent.ACTION_DOWN: {






                            if(!isScrolling && !verticalscroll) {
                                baseX = event.getX();
                                baseY = event.getY();

                            }

                            result = true;


                        }
                        break;

    ////
                        case MotionEvent.ACTION_MOVE: {

                            if(!verticalscroll && !isScrolling  ) {


                                if (event.getPressure() > 0.9f) {
    //                        horizontalscroll = true;
                                    currentX = event.getX();
                                    currentY = event.getY();

                                    current_diffX = currentX - baseX;
                                    current_diffY = currentY - baseY;

                                    if (swipe == LEFT_SWIPE) {

                                        if (currentX > previousX) {


                                            //If here, then horizontal swipe has been reversed
                                            swipe = RIGHT_SWIPE;

                                            //Overwrite base coordinate
                                            baseX = previousX;

                                            //Recalculate Difference
                                            current_diffX = currentX - baseX;
                                        } else {
                                            //NOP - Intentionally kept empty
                                        }
                                    } else if (swipe == RIGHT_SWIPE) {
                                        if (currentX < previousX) {

                                            //If here, then horizontal swipe has been reversed
                                            swipe = LEFT_SWIPE;

                                            //Overwrite base coordinate
                                            baseX = previousX;

                                            //Recalculate Difference
                                            current_diffX = currentX - baseX;
                                        } else {
                                            //NOP - Intentionally kept empty
                                        }
                                    } else {
                                        //If here, then it's a fresh swipe event, so compare with base coordinates
                                        if (currentX < baseX) {
                                            swipe = LEFT_SWIPE;
                                        } else if (currentX > baseX) {
                                            swipe = RIGHT_SWIPE;
                                        } else {
                                            //NOP - Intentionally kept empty
                                        }
                                    }
                                    previousX = currentX;
                                    previousY = currentY;

                                    if (Math.abs(current_diffX) > Math.abs(current_diffY)) {
                                        //It's a horizontal swipe
                                        if (Math.abs(current_diffX) > 200f) {
                                            if (current_diffX > 0) {

                                                seekForWard();

                                                horizontalscroll = true;
                                            } else {
                                                seekBackWard();
                                                horizontalscroll = true;
                                            }
                                        }
                                    }

                                }
                            }

                            result = true;
                            break;

                        }







                    default:


                        result = false;
                        break;


                    }

                    return result;



                }


                @Override
                public void onsingleTapConfirmed() {

                    if(!isScrolling && !verticalscroll)
                    {
                        toggleControllerView();
                    }
                }

                @Override
                void ondoubletap() {

                    doPauseResume();
                }

               }

                @Override
                void onVerticalScroll(float percent, int direction) {

                    if (!isScrolling && !horizontalscroll)
                    {
                        verticalscroll= true;

                        if (direction == ViewGestureListener.SWIPE_LEFT) {

                            mCenterImage.setImageResource(R.drawable.video_bright_bg);
                            updateBrightness(percent * 2);

                        } else {

                            mCenterImage.setImageResource(R.drawable.video_volume_bg);
                            updateVolume(percent * 2);

                        }


                }
                }




      private void seekForWard() {
                if (mMediaPlayer == null) {
                    return;
                }

                int position = mMediaPlayer.getCurrentPosition();

                pos += PROGRESS_SEEK ;
                mMediaPlayer.seekTo(pos);
                setSeekProgress();

            }




  private void seekBackWard() {
            if (mMediaPlayer == null) {
                return;
            }

            int position = mMediaPlayer.getCurrentPosition();
            pos -= PROGRESS_SEEK + (1000 * position/mMediaPlayer.getDuration());
            mMediaPlayer.seekTo(pos);

            setSeekProgress();

        }


    private int setSeekProgress() {
            if (mMediaPlayer == null || mIsDragging) {
                return 0;
            }

            int position = mMediaPlayer.getCurrentPosition();
            int duration = mMediaPlayer.getDuration();
            if (mSeekBar != null) {
                if (duration > 0) {
                    long pos = 1000L * position / duration;
                    mSeekBar.setProgress( (int) pos );
                }

            }

                mEndTime.setText(stringToTime(duration));
                mCurrentTime.setText(stringToTime(position));




            return position;
        }

This class is used in handler in handlemsg function to update seekbar every second.

I cant resolve the issue. For the horizontal scroll of gesture detector i implemented it but it doesnt detect instantly if the scroll is reversed , it detects the reverse scroll when finger crosses the point where scroll was initialized.

  • When you gesture detector didn't work for you can you give more detail to what exactly didn't work? – cincy_anddeveloper Jan 25 '18 at 14:21
  • I have tried onTouchEvent of the view i nearly had it done with ACTION_MOVE but video gets 1 or 2 second forward giving delay of some miliseconds – user8324061 Jan 25 '18 at 14:23
  • What skip duration are you calculating inside of onTouchEvent: ACTION_MOVE? – cincy_anddeveloper Jan 25 '18 at 14:25
  • I have 2 methods seekforward and seekbackward which adds and subtratcs 1000 in the current position – user8324061 Jan 25 '18 at 14:26
  • What are you having trouble with exactly? It sounds like you have the correct logic. What delay are you experiencing? Does the video stutter or does the audio delay? – cincy_anddeveloper Jan 25 '18 at 14:30
  • Video stutter giving a delay – user8324061 Jan 25 '18 at 14:31
  • I have implemented vertical scroll with gesture detector in seperate class and it works fine but from the same method when i implement horizontal scroll it does not detect instantly when scroll is reversed. it detects the reverse when the finger crosses back the point where the scroll was initialized. I want just like mx player horizontal scroll or samsung media player scroll. – user8324061 Jan 25 '18 at 14:32
  • I have a class OnSwipeTouchListener implemets View.onTouchListener And on Activity i implement it as view.setontouchlistener In onswipetouchlistner i have implemented gesture detetector and sacle gesture detetctor. In activity where this class is implemented in that part i have implemented horizontal scroll for seek but video stutter at the end – user8324061 Jan 25 '18 at 14:37
  • I think that i am have not implemented the seekbar right with the video But i am confused Help me with this I want gestures responsive like mx player – user8324061 Jan 25 '18 at 14:39
  • I will need to definitely need to see code and maybe video to of the problem so I can better assist you. – cincy_anddeveloper Jan 25 '18 at 14:40
  • Where did you get code for OnSwipeTouchListener? – cincy_anddeveloper Jan 25 '18 at 14:41
  • Ok sir let me show you the code – user8324061 Jan 25 '18 at 14:42
  • The base structure i got from stackoverflow but i made some changes to it for scalegesture – user8324061 Jan 25 '18 at 14:42
  • See this https://pastebin.com/VV07GrvN – user8324061 Jan 25 '18 at 14:51
  • Please add your code to the your question and don't post a link. – cincy_anddeveloper Jan 25 '18 at 14:52
  • Looks like one of your problems is the fact that you are implemented the swipe detection inside of onScroll callback instead of onFling()... Swiping is a fling action not a scroll action. Second, you are only listening to vertical scrolls and completely ignoring the horizontal scrolls. – cincy_anddeveloper Jan 25 '18 at 14:59
  • when i implement horizontal scroll it does not detect instantly when scroll is reversed. it detects the reverse when the finger crosses back the point where the scroll was initialized. – user8324061 Jan 25 '18 at 15:06
  • But sir onFling detects the swipe when the swipe is completed doesnt it? – user8324061 Jan 25 '18 at 15:07
  • I see what you are saying. I believe the issue is with how GestureDetector detects scrolls. Try tracking the deltas between the initial down X and Y inside of onTouchEvent(...). You'll wanna add a special check to determine if a scroll is more vertical than it is horizontal. This can be done using a Math.max() on the deltaX and deltaY – cincy_anddeveloper Jan 25 '18 at 15:28
  • I have uploaded complete code sir. Please review it and guide me. Thank you – user8324061 Jan 25 '18 at 16:23
  • I want to move the seekbar according to the finger movement responsively. I have set the seekbar.max(1000); – user8324061 Jan 25 '18 at 16:24
  • Is onScroll(...) not getting called at all for horizontal scroll or is it only giving you negative values? Can you add a log statement that prints out the values of deltaX and deltaY. – cincy_anddeveloper Jan 25 '18 at 16:26
  • Sir horizontal scroll is working correctly but the issue in onScroll method for horizontal scrolling is that it does not detect when the swipe is reversed without lifting the finger until the finger crosses the point where the scroll was initialized – user8324061 Jan 25 '18 at 16:28
  • For example if user started to scroll right from the centre of the screen and after some distance he reverses it and starts scrolling from right to left without lifting the finger up but onscroll will not detect it until the finger of the user starts covering distance from the centre of the screen to the left – user8324061 Jan 25 '18 at 16:30
  • Just so I'm clear, if you drag to the left or the right starting at the center, everything works as expected? But when dragging to either the left or right direction and then reversing the direction and never raising your finger, the gesture detector will not call onScroll until the finger has crossed the initial touch location aka the center of the screen? – cincy_anddeveloper Jan 25 '18 at 16:48
  • Yes exactly sir – user8324061 Jan 25 '18 at 16:49
  • And does it do the same for vertical scrolls? It should. – cincy_anddeveloper Jan 25 '18 at 16:50
  • No sir vertical scroll works as expected – user8324061 Jan 25 '18 at 16:50
  • I also implemented the same method as vertical scroll but it works as i told you – user8324061 Jan 25 '18 at 16:51
  • I just looked through the source code for GestureDetector.onTouchEvent(...) and you should get the same issue in both vertical as in horizontal. I'd recommend you place a break point inside of your onTouchEvent and step through while you are in the middle of a reversed horizontal drag to find out there the detector is throwing away the event. – cincy_anddeveloper Jan 25 '18 at 17:00
  • I tried that too sir In the logcat it shows the values when the finger crosses the point of start – user8324061 Jan 25 '18 at 17:02
  • Im really stuck into this and i have to complete the app sir – user8324061 Jan 25 '18 at 17:02
  • If it helps, I'd recommend coping the source code of GestureDetector and adding it to your project and then using that class, so you can place log statements inside of onTouchEvent and you can figure our exactly what is going. This will make debugging significantly easier. – cincy_anddeveloper Jan 25 '18 at 17:02
  • But if you see my code under ACTION_MOVE it works as i expected but the video stutter when i click the view once aur click exactky after dragging – user8324061 Jan 25 '18 at 17:04
  • As for updating your Seekbar. I'd worry about getting the swipe gesture working because it'll be very easy to handle updating you complete a swipe gesture. – cincy_anddeveloper Jan 25 '18 at 17:05
  • Ok sir i will get back to you after trying the google source code with logcat readings – user8324061 Jan 25 '18 at 17:07
  • Okay, I apologize I think I see the source of your problem. First with the jitter when clicking the View once. The touch screens will measure a single tap no matter how minute as a move event because there are several pixels being touched by your finger. So you will always always see a ACTION_DOWN then immediately after an ACTION_MOVE and finally an ACTION_UP. That why the framework has a concept of touch slops to prevent accidental move detection. Second, your code is never calling your GestureDetector because you override onTouchEvent of OnSwipeDetector and you never call super.onTouchEvent. – cincy_anddeveloper Jan 25 '18 at 17:18
  • So i should call return super.onTouchEvent in the onTouchEvent of the view? In the default part of the switch statement. Will it help with the jitter? – user8324061 Jan 25 '18 at 17:22
  • To help with the jitter doing how your currently doing it, you need to have a touch slop that you use to compare against the deltaY and deltaX. But if you wanna use gesture detector, when you add the OnSwipeGestureDetector, don't override onTouchEvent() and just implement onScroll(...) and do your checks against the deltaX and deltaY to detect the scroll direction and handle adjusting the volume or playback. You can completely remove your the onTouchEvent() implementation and use the one provided in OnSwipeGestureDetector. – cincy_anddeveloper Jan 25 '18 at 17:28
  • Can you please elaborate it sir? – user8324061 Jan 25 '18 at 17:38
  • I've given you all of the information I can. This comment thread has become very much of a discuss and won't be very useful to others. If you want to enter a private discussion, maybe I can assist you more. – cincy_anddeveloper Jan 25 '18 at 17:48
  • Its done sir. With gesturedetector – user8324061 Jan 25 '18 at 17:53

1 Answers1

1

Swipe Left or Right with you increase and decrease your value like a volume up dawn, skip some duration of video, increase and decrease brightness by swipe in mostly use in photo editing app

Here i was perform swipe event on Image view

actionImage.setOnTouchListener(new View.OnTouchListener(){
 @Override
 public boolean onTouch (View v, MotionEvent event){

 switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        initialX = event.getX();
        initialY = event.getY();
        return true;

    case MotionEvent.ACTION_UP:
        opacityText.setVisibility(GONE);
        old = 0.0f;
        return true;

    case MotionEvent.ACTION_MOVE:
        currentX = event.getX();
        currentY = event.getY();

        if (initialX > currentX) {
            Log.e("TOUCH", "Left");
            opacityText.setVisibility(VISIBLE);
            float New = (initialX - currentX) * 100 / 1000;
            condition = condition2 - ((New <= old) ? 0 : (New - old));
            condition2 = (condition <= 0) ? 0 : condition;
            Log.e("INT", "" + condition);
            opacityText.setText("Opacity " + (condition2) + "%");
            old = (initialX - currentX) * 100 / 1000;
        }

        if (initialX < currentX) {
            Log.e("TOUCH", "RIGHT");
            opacityText.setVisibility(VISIBLE);
            float New = (currentX - initialX) * 100 / 1000;
            condition = condition2 + ((New <= old) ? 0 : (New - old));
            condition2 = (condition >= 100) ? 100 : condition;
            Log.e("INT", "" + condition);
            opacityText.setText("Opacity " + (condition2) + "%");
            old = (currentX - initialX) * 100 / 1000;
        }
        return true;

}
Sanjay Hadiya
  • 864
  • 9
  • 21