andbook!.pdf - Learning Android Get an anddev.org - Android-Shirt Back to index
anddev.org Header Logo
FAQ Search Top rated articles Browse Feeds anddev.org - Authors Contact Details Register Log in

[Custom Widget] - HandyFlipper: makes everything flip


 
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials
Author Message
mmin18
Junior Developer
Junior Developer


Joined: 03 Feb 2008
Posts: 19
Location: China

PostPosted: Fri Apr 18, 2008 9:13 am    Post subject: [Custom Widget] - HandyFlipper: makes everything flip Reply with quote

HandyFlipper is a custom widget inherited from ViewAnimator. Is is first designed to use in my project handyCalc.
Here is a demo to show how it works. (sorry about the color, it's a gif)

Or you can watch the handyCalc video demo in http://www.anddev.org/my_submission_is_a_calculator-t1704.html

There is some other widget in android.widget that you can flip, like Spinner, Gallery. In Spinner, you cannot flip if it's child is focusable, like a button in a Spinner.

Now i'll just show you how to use it. you can view the code below or download a package and import in your eclipse to run it yourself: http://www.anddev.org/files/handycalc_library_155.zip

It's just a layout file to make it work:
XML:
<?xml version="1.0" encoding="utf-8"?>
<org.mmin.handycalc.HandyFlipper xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:handy="http://schemas.android.com/apk/res/org.mmin.handycalc"
     handy:flipHorizontal="true"
     handy:flipVertical="true"
     handy:circle="true"
     handy:motionSpeed="60"
     handy:motionInterval="500"
     handy:motionDistance="60"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     >

<!--
     motionSpeed is the minimum distance(in pixel) between the last ACTION_MOVE and ACTION_UP event
     motionInterval is the maximum milliseconds between ACTION_DOWN and ACTION_UP event
     motionDistance is the minimum distance(in pixel) between ACTION_DOWN and ACTION_UP event
 -->

     
     <TextView
          android:text="1 / 3\nflip left|right, up|down"
          android:textSize="36sp"
          android:textAlign="center"
          android:background="#6FFF"
          android:layout_width="fill_parent"
          android:layout_height="300px"
          />

     
     <EditText
          android:text="2 / 3\nthis is a EditText which you cannot flip in Spinner"
          android:textSize="36sp"
          android:textAlign="center"
          android:layout_width="fill_parent"
          android:layout_height="300px"
          />

     
     <Button
          android:text="3 / 3\nthis is a Button"
          android:textSize="36sp"
          android:textAlign="center"
          android:layout_width="fill_parent"
          android:layout_height="300px"
          />

     
</org.mmin.handycalc.HandyFlipper>


Next section I'll show you how to make this custom widget.



handyCalc Library.zip
 Description:
handyCalc library with samples

Download
 Filename:  handyCalc Library.zip
 Filesize:  21.82 KB
 Downloaded:  89 Time(s)


HandyFlip.gif
 Description:
flip demo

Download
 Filename:  HandyFlip.gif
 Filesize:  121.43 KB
 Downloaded:  75 Time(s)

Back to top
View user's profile Send private message Send e-mail
mmin18
Junior Developer
Junior Developer


Joined: 03 Feb 2008
Posts: 19
Location: China

PostPosted: Fri Apr 18, 2008 9:30 am    Post subject: Reply with quote

This is the java class for HandyFlipper. I hide most of the code just leave the most essential methods to make ViewAnimator flipable.

Java:
package org.mmin.handycalc;

import ...;

public class HandyFlipper extends ViewAnimator {

// To view the full code, download the archive file http://www.anddev.org/files/handycalc_library_155.zip and import it in eclipse.

     MotionEvent motionDown, motionPrev;
     boolean motionCanceled;

     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
          if (event.getAction() == MotionEvent.ACTION_DOWN) {
               motionDown = event;
               motionPrev = event;
               motionCanceled = false;
               // just record the ACTION_DOWN event and return false. the event will dispatch as a normal way.
               return false;
          }
          if (motionCanceled)
               return true; // canceled, then the child no need to process it.
          if (event.getAction() == MotionEvent.ACTION_MOVE) {
               motionPrev = event;
               // just record the ACTION_MOVE event and return false. the event will dispatch as a normal way.
               return false;
          }
          if (event.getAction() == MotionEvent.ACTION_UP) {
               if (motionDown == null || motionPrev == null)
                    return false;
               long time = event.getEventTime() - motionDown.getEventTime();
               if (time > motionInterval)
                    return false;
               // the event's getX will be modify when deliver to child. so use getRawX instead
               float dx = event.getRawX() - motionDown.getRawX();
               float absDx = Math.abs(dx);
               float dy = event.getRawY() - motionDown.getRawY();
               float absDy = Math.abs(dy);
               float abs = Math.max(absDx, absDy);
               if (abs < motionDistance)
                    return false;
               float v = Math.abs(abs) * 1000 / time;
               if (v < motionSpeed) {
                    motionPrev = event;
                    return false;
               } else {
                    // start to flip. if it return true, the child will receive a event with MotionEvent.ACTION_CANCEL instead of MotionEvent.ACTION_UP
                    // so make sure your custom widget will handle MotionEvent.ACTION_CANCEL
                    motionDown = null;
                    motionPrev = null;
                    motionCanceled = true;
                    if (abs == absDx) {
                         if (!flipHorizontal)
                              return false;
                         if (dx < 0)
                              return moveRight();
                         else
                              return moveLeft();
                    } else {
                         if (!flipVertical)
                              return false;
                         if (dy < 0)
                              return moveDown();
                         else
                              return moveUp();
                    }
               }
          } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
               motionDown = null;
               motionPrev = null;
               return false;
          }
          return false;
     }

     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
          super.dispatchTouchEvent(ev);
          // always return true to tell the parent the event is processed
          return true;
     }

     @Override
     public boolean onTouchEvent(MotionEvent event) {
          this.onInterceptTouchEvent(event);
          // always return true to tell the parent the event is processed
          return true;
     }
}


Other codes and resources like attrs and anims can be found in the archive file
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


© 2007, Android Development Community
All rights reserved.
Powered by phpBB.