Saturday, March 3, 2012

Extending interaction of views with gestures

Hi,
in this post i will talk about extending the interaction of an existing view with gestures. For example, you have a view that provides specific interaction like a ListView providing  you to select an element, or an EditText allowing you to enter text.
I will use an EditText widget and extend it with a swiping gesture to remove its content (screenshot below).

Okay, let's get started. First of all we create a simple
swipe-from-right-to-left gesture with the Gestures Builder (a good tutorial on how to add gestures in Android can be found here). We will call the gesture "clear_text".

After that is done, we will have an XML called "swipe_edit_text.xml" that describes the layout of our view.


<?xml version="1.0" encoding="utf-8"?>  
 <android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"  
   android:id="@+id/gesture_overlay"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:eventsInterceptionEnabled="true"  
   android:uncertainGestureColor="@android:color/transparent" >  
   <EditText  
     android:id="@+id/edit_text"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content" />  
 </android.gesture.GestureOverlayView>  

Important here is the line below to still allow the usual interaction of our view we are extending.
   android:eventsInterceptionEnabled="true"

Next we come to the code. Create a class SwipableEditText.
public class SwipableEditText extends FrameLayout {

 
 // the library to load the gestures
 private GestureLibrary mLibrary;

 // the gesture overlay
 private GestureOverlayView mGestureOverlay;
        // the view we are extending with gestures
 private EditText mEditText;
 
 public SwipableEditText(Context context) {
  this(context, null);
 }

 public SwipableEditText(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public SwipableEditText(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  
  // inflate the layout
  final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  FrameLayout li = (FrameLayout) inflater.inflate(R.layout.swipe_edit_text, this);
  mGestureOverlay = (GestureOverlayView) li.findViewById(R.id.gesture_overlay);
  mEditText = (EditText) li.findViewById(R.id.edit_text);
  
  // load the gestures
  mLibrary = GestureLibraries.fromRawResource(context, R.raw.gestures);
  if (!mLibrary.load())
   return;
  init();
 }
 
 private void init() {
  mGestureOverlay.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {
   

   @Override
   public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {

    ArrayList predictions = mLibrary.recognize(gesture);
    for (Prediction p : predictions) {
     // gesture accepted
     if (p.score > 1.0) {
       // user performed swipe gesture
       if (p.name.equalsIgnoreCase("clear_text")) {
        mEditText.setText("");
       }
      }
     }
    }
  });
 }
}

The swipe gesture performs the deletion of the text in the EditText Widget.
And that's it. Now you can integrate your view into any activity.
The code can be downloaded here.

Happy Coding.

No comments:

Post a Comment