Tag Archives: UI

greenHome (How to share MotionEvents)

click to enlarge

This semester at Virginia Tech, a friend and I lucked out with the opportunity to join up with a professor doing research in how to use smartphone features to save energy. We’re using things like the light sensor, the accelerometer, and the GPS to save energy in neat ways. However, the first app to come out uses none of these. Think of it as an advanced Hello World.

The idea behind greenHome is to give the user energy saving tips depending on their location in the house. It starts with a homescreen that lets the user pick what room they’d like tips about, then brings up a list of tips. We let the user navigate through these in some cool ways.

click to enlarge

The user can navigate through tips in this activity by either touching the left and right arrows at the top, or flicking left or right, as long as the flick is in the content. We used a custom ScrollView nested inside of a custom ViewFlipper to accomplish this with nice animations. I’ll post a tutorial on how to use a ViewFlipper soon.

What’s cool is that we share touch events between the ViewFlipper and the Scrollview, which is a bit tricker than you’d think.

//flipper is my custom ViewFlipper
flipper.setOnTouchListener(new MyOnTouchListener());
public class MyOnTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent e) {
        //give the scroller it's data
        //sc1 is the first child view of flipper
        if (flipper.getCurrentView().getId() == R.id.sc1)
        //sc2 is the second child view
        else if (flipper.getCurrentView().getId() == R.id.sc2)
        //reset on release
        if (e.getAction() == MotionEvent.ACTION_UP)
            firstTouch = true;
        //check for a flick...
        return true;

The above code has some weird aspects. Stepping through it, we

  • Set the ViewFlipper’s OnTouchListener to MyOnTouchListener.
  • In the onTouch() method, we begin by handing down the touch data given to us (since we’re the parent in the layout) to one of our visible children (sc1 or sc2) by calling the child’s onTouchEvent.
  • Take care of flipping (I’ve taken that specific code out for simplicity).
  • Return true.

The un-important looking return true is actually very important. It turns out that if a view’s onTouch() method returns true, that means that this event has found it’s home, and it does not need to continue to other view’s. Logically, I would think that I’d want to return false here, since I’d love not to have to give out the event to my children myself, it would seem that Android would do that for me. However, I tried that and it didn’t work. Perhaps the event didn’t get handed to my ViewFlipper before it’s children.

For mine to work correctly, my ViewFlipper’s onTouch() had to give the event to a child, then return true. Also, my children’s onTouch() had to return false.