I need to implement a gallery which scrolls one item at a time, and which can do 'autoscroll': i.e. every couple of seconds, it automatically scrolls to the next item.
As per this thread: Android: Programmatically animate between images in Gallery widget, I extended Gallery, overriding onFling to ignore the fling event and instead simulate a DPAD arrow left or right in order to move a single item at a time:
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int kEvent;
if(isScrollingLeft(e1, e2)){ //Check if scrolling left
kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
}
else{ //Otherwise scrolling right
kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
}
onKeyDown(kEvent, null);
return true;
}
This works well. For the auto scroll, I create a handler and postDelayed a runnable which simulates the same DPAD key press in the same way:
handler.postDelayed(new Runnable() {
public void run() {
onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
}
}, AUTO_SCROLL_INTERVAL);
but this doesn't do anything!!
I know the runnable gets executed as expected at the correct interval, since I logged it and confirmed this, but the onKeyDown does not cause the gallery to scroll or switch items. Why would this work in one method and not another? I tried to call my onFling instead, to no avail. Also tried to dispatchKeyEvent, but no luck.
I really need to get this going, but I also really want to understand why the same code doesn't yield the same results in two different places... Does this have something to do with how Android views handle input events? I looked into the Gallery code for clues, but found nothing! It seems as though it should work.
Please, I'm stumped... any ideas?
Thanks
So, it turns out that the original logic I had does work. A custom gallery implementing that logic but stripped of everything else in my class (below) works as expected, so it must be something else in my class that is causing this problem.
Thanks for your help HighFlyer :)
At the very least I learned about reflection... which is a very cool feature of Java.
public class CustomGallery extends Gallery {
private Handler handler;
public CustomGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
handler = new Handler();
postDelayedScrollNext();
}
private void postDelayedScrollNext() {
handler.postDelayed(new Runnable() {
public void run() {
postDelayedScrollNext();
Log.d("CustomGallery", "dpad RIGHT");
onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
}
}, 1000);
}
private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) {
return e2.getX() > e1.getX();
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int kEvent;
if (isScrollingLeft(e1, e2)) {
Log.d("CustomGallery", "fling LEFT");
kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
} else {
Log.d("CustomGallery", "fling LEFT");
kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
}
onKeyDown(kEvent, null);
return true;
}
Note for future visitors: a better solution in situations like this (full-view gallery) is to use a ViewPager
. It works like a gallery, but properly implements a setCurrentItem()
method for smooth scrolling. With the compatibility package, it works for API 4 (Android 1.6!) and up, so everyone can use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With