0

I seem to have an issue with hiding and showing the ActionBar. My app starts with it hidden and I want it to appear back when the users swipes down on any part of the screen and hide it back then the user swipes up.

I have tried implementing this in the following ways:

Method 1: in onCreate

        View mView = getWindow().getDecorView();

        //mView.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE;

        mView.setSystemUiVisibility(uiOptions);


        mView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Toast.makeText(context, "Swiped down", Toast.LENGTH_SHORT).show();
                        //getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
                        getSupportActionBar().show();
                        return true;
                    case MotionEvent.ACTION_UP:
                        Toast.makeText(context, "Swiped up", Toast.LENGTH_SHORT).show();
                        //getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
                        getSupportActionBar().hide();
                        return true;
                    default: return false;
                }
                //return false;
            }
        });

Method 2:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getActionMasked();
        switch (action) {
            case (MotionEvent.ACTION_DOWN):
                Toast.makeText(context, "Swiped down", Toast.LENGTH_SHORT).show();
                getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
                getSupportActionBar().show();
                return true;
            case (MotionEvent.ACTION_UP):
                Toast.makeText(context, "Swiped up", Toast.LENGTH_SHORT).show();
                getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
                getSupportActionBar().hide();
                return true;
            default:
                return super.onTouchEvent(event);
        }  
    }

Now here are the issues:

  1. The function applies only on parts of the screens where I have no buttons or other elements which can be clickable;
  2. Where it applies, it has nothing to do with swipes. It shows the bar as long as I keep the finger pressed on a non-clickable filed in the view.

EDIT:

With the replies from the comment, I managed to make the Action Bar show and hide based on scroll, but I still have the issue with #1, in which I cannot perform the action on any part of the screen.

It works only on the parts where onClickListener is not assessed.

Andy
  • 87
  • 11
  • seems like someone had this problem before. Check [this](https://stackoverflow.com/questions/27297467/detect-if-a-scrollview-is-scrolling-up-or-down-android) thread – alfalfa Jan 21 '19 at 12:49
  • Possible duplicate of [Detect if a ScrollView is scrolling up or down - Android](https://stackoverflow.com/questions/27297467/detect-if-a-scrollview-is-scrolling-up-or-down-android) – Auden Young Jan 21 '19 at 13:02
  • This solved issue number two. But it does not solve the first one. I can only hide/show while moving on a small part of the screen. If I try this over my TextViews, it does nothing. – Andy Jan 21 '19 at 14:00
  • @alfalfa, heather: I managed to solve the second issue, but now onSingleClick and onFling work at the same time and I want them to be exclusive. I have posted more details if you have any ideas. – Andy Feb 06 '19 at 20:54

1 Answers1

0

I have managed to solve the issue after a few days of investigation. Seemed that the best choice was to implement a GestureDetector like this

    public class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {

    private MainGame mainGame;

    MyGestureDetector(MainGame mainGame) {
        this.mainGame = mainGame;
    }

        @Override
        public boolean onDown(MotionEvent e) {
            Log.d("Gesture", "onDown");
            return super.onDown(e);
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.d("Gesture", "onSingleTapConfirmed");
            return true;
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.d("Gesture", "onSingleTapUp");
            return true;
        }

        @Override
        public void onShowPress(MotionEvent e) {
            Log.d("Gesture", "onShowPress");
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.d("Gesture", "onDoubleTap");
            return true;
        }

        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            Log.d("Gesture", "onDoubleTapEvent");
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.d("Gesture", "onLongPress");
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.d("Gesture", "onScroll");
            if (e1.getY() < e2.getY()) {
                Log.d("Gesture", "Scroll Down");
            }
            if (e1.getY() > e1.getY()) {
                Log.d("Gesture", "Scroll Up");
            }
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (e1.getY() < e2.getY()) {
                Log.d("Gesture", "Swipe Down " + e1.getY() + " - " + e2.getY());
                mainGame.getSupportActionBar().hide();
            }
            if (e1.getY() > e2.getY()) {
                Log.d("Gesture", "Swipe Up" + e1.getY() + " - " + e2.getY());
                mainGame.getSupportActionBar().hide();
            }
            return true;
        }
    }

and implement it in my main activity as an onTouch with listeners for each part of the layout in my main activity. In onCreate:

layout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mViewSelected = v;
                mGestureDetector.onTouchEvent(event);
                return false;
            }
        });

        gameScoreP1.setOnTouchListener(this);
        gameScoreP2.setOnTouchListener(this);
        fullNameP1.setOnTouchListener(this);
        fullNameP2.setOnTouchListener(this);

and the method to override the gestures:

 @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (myGestureDetector.onSingleTapConfirmed(event)) {
            switch (v.getId()) {
                case R.id.fullNameP1:
                    diagUtils.changePlayerNameDialog(1, this);
                    return false;
                case R.id.fullNameP2:
                    diagUtils.changePlayerNameDialog(2, this);
                    return false;
                case R.id.gameScoreP1:
                    scoreSetter.manageGameSetPoints(1);
                    return false;
                case R.id.gameScoreP2:
                    scoreSetter.manageGameSetPoints(2);
                    return false;
                default:
                    return false;
            }
        } else return true;
    }

Issue now is that when I perform the fling movement over a view like gameScoreP1 for example, it also detects the click. Is there any way to make these exclusive?

EDIT

Managed to solve the second issue as well by setting the views as clickable like such: fullNameP1.setClickable(true)

Andy
  • 87
  • 11