How to control scrolling of your android app from volume button ?
Many times users want to operate their mobile only with a single hand, particularly in reading app. In all such scenario, a very useful feature is to scroll using volume buttons of device i.e volume up for scrolling upwards and press volume down to scroll down the reading content or any scrollable Android view.
In this post we will explore how to achieve this feature. this post assumes you know how to create the new project in the android studio.
In Android most widely used scrollable view are NestedScrollView, ScrollView, RecyclerView and ListView. we will start with NestedScrollView.
Sample app Available on github.com.
Implement following method in your activity...
onKeyDown(int keyCode, KeyEvent event)
onKeyUp(int keyCode, KeyEvent event)
onKeyLongPress(int keyCode, KeyEvent event)
In keyDown, we have to do nothing special if it's a Volume UP or Volume Down Key Event then start tracking your event for the corresponding key up event.
In keyUpEvent, if it's a Volume UP and it is not a long press then just scroll your nestedScrollView one page UP by calling NestedScrollView.pageScroll(View.FOCUS_UP) and also consider the expansion state of AppBarLayout if it is present in your activity's layout.
if it's a Volume DOWN and it is not a long press then scroll your nestedScrollView one page DOWN by calling mNestedScrollView.pageScroll(View.FOCUS_DOWN).
Instead of calling pageScroll() which is just scrolling your view by single page Up or DOWN you can also use smoothScrollTo(int x, int y) where x and y represent the scroll on X and Y axis respectively, using this method you can control the scrolling length on a single event.
In this post we will explore how to achieve this feature. this post assumes you know how to create the new project in the android studio.
In Android most widely used scrollable view are NestedScrollView, ScrollView, RecyclerView and ListView. we will start with NestedScrollView.
Sample app Available on github.com.
Implement following method in your activity...
onKeyDown(int keyCode, KeyEvent event)
onKeyUp(int keyCode, KeyEvent event)
onKeyLongPress(int keyCode, KeyEvent event)
In keyDown, we have to do nothing special if it's a Volume UP or Volume Down Key Event then start tracking your event for the corresponding key up event.
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { event.startTracking(); return true; } return false; }
In keyUpEvent, if it's a Volume UP and it is not a long press then just scroll your nestedScrollView one page UP by calling NestedScrollView.pageScroll(View.FOCUS_UP) and also consider the expansion state of AppBarLayout if it is present in your activity's layout.
if it's a Volume DOWN and it is not a long press then scroll your nestedScrollView one page DOWN by calling mNestedScrollView.pageScroll(View.FOCUS_DOWN).
Instead of calling pageScroll() which is just scrolling your view by single page Up or DOWN you can also use smoothScrollTo(int x, int y) where x and y represent the scroll on X and Y axis respectively, using this method you can control the scrolling length on a single event.
public boolean onKeyUp(int keyCode, KeyEvent event) { if (mNestedScrollView == null) { return false; } boolean notLongPress = (event.getFlags() & KeyEvent.FLAG_CANCELED_LONG_PRESS) == 0; if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && notLongPress) { if (!mNestedScrollView.pageScroll(View.FOCUS_UP) && mAppBarLayout != null) { mAppBarLayout.setExpanded(true, true); } return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && notLongPress) { if (mAppBarLayout != null && mAppBarLayout.getHeight() == mAppBarLayout.getBottom()) { mAppBarLayout.setExpanded(false, true); } else { return mNestedScrollView.pageScroll(View.FOCUS_DOWN); } return true; } return false; }
In keyLongPressEvent, right now I am just handling the volume Up in which NestedScrollView getting scrolled up to its topmost frame by calling mNestedScrollView.smoothScrollTo(0, 0);
but you can change its implementation as per your need.
public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { if (mAppBarLayout != null) { mAppBarLayout.setExpanded(true, true); } if (mNestedScrollView != null) { mNestedScrollView.smoothScrollTo(0, 0); } return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { //Do Nothing return true; } return false; }Download sample App or Visit Github page
Comments
Post a Comment