Create a Simple Android Gestures Detection App in Less Than 30 Minutes!

0
Shares
Create a Simple Android Gestures Detection App in Less Than 30 Minutes!
5 (100%) 2 votes

Android Tutorial Gesture Recognization

The Android SDK supports a number of Android Gestures since version 1.6 that you can detect, and allow you to tailor them in different ways to interact with them. The common touch events like scrolls, double tap, pinch are known as gestures.

As you might know, mobile technology has become a huge part and it is now main focus of developers. People interact with their smartphones in a numerous ways, from simple touches to dragging views.

In this Android Gestures tutorial, we’ll demonstrate how to create Android gestures detection app. Don’t worry. It’s as easy as 1-2-3.

Let’s Get Started

Create a new project in Android studio.

For Drag and Drop Gesture:

  • Implement view.onDragListner
  • Handle events of onDrag method.
DragEvent.ACTION_DRAG_STARTED:

DragEvent.ACTION_DRAG_ENTERED:

DragEvent.ACTION_DRAG_EXITED:

DragEvent.ACTION_DROP:

DragEvent.ACTION_DRAG_ENDED:

 

  • Set Listner in to View

 

view.setOnDragListener(new MyDragListener());

For Pinch Zoom Gesture

  • Implement view.OnTouchListener
  • Handle events of OnTouch method.
MotionEvent.ACTION_DOWN:

MotionEvent.ACTION_POINTER_DOWN:

MotionEvent.ACTION_MOVE:

MotionEvent.ACTION_UP:

MotionEvent.ACTION_POINTER_UP:
  • Set Listener in to view.
view.setOnTouchListener(new MyDragListener());
  • Find distance between two finger in MotionEvent.Action_Move:
float distx, disty;
float distCurrent;
 
distx = event.getX(0) - event.getX(1);
disty = event.getY(0) – event.getY(1);
distCurrent = (float) Math.sqrt(distx * distx + disty * disty);
  • Set Scale to Bitmap
float curScale = distCurrent / dist0;
if (curScale < 0.1) {
    curScale = 0.1f;
}
Bitmap resizedBitmap;
int newHeight = (int) (bmpHeight * curScale);
int newWidth = (int) (bmpWidth * curScale);
resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
ivObject.setImageBitmap(resizedBitmap);

For Rotate Gesture:

  • Implement View.OnTouchListener
  • Handle Events of OnTouch method
MotionEvent.ACTION_DOWN:

MotionEvent.ACTION_POINTER_DOWN:

MotionEvent.ACTION_MOVE:

MotionEvent.ACTION_UP:

MotionEvent.ACTION_POINTER_UP:
  • Set Listener in to View
view.setOnTouchListener(new MyDragListener());
  • Calculate rotation between points in MotionEvent.ACTION_MOVE:
private float fX, fY, sX, sY;
private int ptrID1, ptrID2;
private float mAngle;
if (ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID) {
    float nfX, nfY, nsX, nsY;
    nsX = event.getX(event.findPointerIndex(ptrID1));
    nsY = event.getY(event.findPointerIndex(ptrID1));
    nfX = event.getX(event.findPointerIndex(ptrID2));
    nfY = event.getY(event.findPointerIndex(ptrID2));
    mAngle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);  
}  
private float angleBetweenLines(float fX, float fY, float sX, float sY, float nfX, float nfY, float nsX, float nsY) {
    float angle1 = (float) Math.atan2((fY - sY), (fX - sX));
    float angle2 = (float) Math.atan2((nfY - nsY), (nfX - nsX));
    float angle = ((float) Math.toDegrees(angle1 - angle2)) % 360;
    if (angle < -180.f) angle += 360.0f; if (angle > 180.f) angle -= 360.0f;
    return angle;
}

Start Code Integration

  • MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void onDragDemoClick(View view) {
        Intent iPanGesture =  new Intent(MainActivity.this , DragDropGestureActivity.class);
        startActivity(iPanGesture);
    }
    public void onPinchZoomClick(View view) {
        Intent iPanGesture =  new Intent(MainActivity.this , PinchZoomGestureActivity.class);
        startActivity(iPanGesture);
    }
    public void onRotateClick(View view) {
        Intent iPanGesture =  new Intent(MainActivity.this , RotateGestureActivity.class);
        startActivity(iPanGesture);
    }
}
  • Activity_main.xml
 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gesturedemo.MainActivity">
    <Button
        android:id="@+id/btnDrop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:onClick="onDragDemoClick"
        android:text="Drag And Drop"
        android:textColor="@android:color/white"
        android:textSize="18sp" />
    <Button
        android:id="@+id/btnPinchZoom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnDrop"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimary"
        android:onClick="onPinchZoomClick"
        android:text="Pinch Zoom"
        android:textColor="@android:color/white"
        android:textSize="18sp" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnPinchZoom"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimary"
        android:onClick="onRotateClick"
        android:text="Rotate"
        android:textColor="@android:color/white"
        android:textSize="18sp" />
</RelativeLayout>
  • DragDropGestureActivity.java
public class DragDropGestureActivity extends AppCompatActivity {
    private TextView tvDragMe;
    private ImageView ivDustBin;
    private ImageView ivDust;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_drop_gesture);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        initControls();
    }
    private void initControls() {
        tvDragMe = (TextView) findViewById(R.id.tvDragMe);
        ivDustBin = (ImageView) findViewById(R.id.ivDustBin);
        ivDust = (ImageView) findViewById(R.id.ivDust);
        ivDust.setOnTouchListener(new MyTouchListener());
        ivDustBin.setOnDragListener(new MyDragListener());
    }
    private final class MyTouchListener implements View.OnTouchListener {
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                ClipData data = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                view.startDrag(data, shadowBuilder, view, 0);
                view.setVisibility(View.INVISIBLE);
                return true;
            } else {
                return false;
            }
        }
    }
    private class MyDragListener implements View.OnDragListener {
        int resAct = R.drawable.dust_act;
        int resNormal = R.drawable.dust_normal;
        @Override
        public boolean onDrag(View v, DragEvent event) {
            int action = event.getAction();
            switch (action) {
                case DragEvent.ACTION_DRAG_STARTED:
                    // do nothing
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    ((ImageView) v).setImageResource(resAct);
                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                    ((ImageView) v).setImageResource(resNormal);
                    break;
                case DragEvent.ACTION_DROP:
                    ((ImageView) v).setImageResource(resAct);
                    tvDragMe.setVisibility(View.GONE);
                    // Display toast
                    showToast("Dropped into dustbin!");
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    if (event.getResult()) { // drop succeeded
                        ((ImageView) v).setImageResource(resAct);
                    } else { // drop failed
                        final View draggedView = (View) event.getLocalState();
                        draggedView.post(new Runnable() {
                            @Override
                            public void run() {
                                draggedView.setVisibility(View.VISIBLE);
                            }
                        });
                        ((ImageView) v).setImageResource(resNormal);
                    }
                default:
                    break;
            }
            return true;
        }
    }
    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}
  • activity_drag_drop_gesture.xml
 <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.gesturedemo.DragDropGestureActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_drag_drop_gesture" />
</android.support.design.widget.CoordinatorLayout>
  • content_drag_drop_gesture.xml
<<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_pan_gesture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary_trans"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.gesturedemo.DragDropGestureActivity"
    tools:showIn="@layout/activity_drag_drop_gesture">
    <TextView
        android:id="@+id/tvDragMe"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/ivDust"
        android:layout_marginTop="10dp"
        android:text="Drop it into dustbin"
        android:textColor="#ffffff" />
    <ImageView
        android:id="@+id/ivDustBin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:src="@drawable/dust_normal" />
    <ImageView
        android:id="@+id/ivDust"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/waste_paper" />
</RelativeLayout>
  • PinchZoomGestureActivity.java
public class PinchZoomGestureActivity extends AppCompatActivity {
    private ImageView ivObject;
    private TextView tvEvent;
    Bitmap bitmap;
    int bmpWidth, bmpHeight;
    //Touch event related variables
    int touchState;
    final int IDLE = 0;
    final int TOUCH = 1;
    final int PINCH = 2;
    float dist0, distCurrent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pinch_zoom_gesture);
        initControls();
    }
    private void initControls() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ivObject = (ImageView) findViewById(R.id.ivObject);
        tvEvent = (TextView) findViewById(R.id.tvEvent);
        
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        bmpWidth = bitmap.getWidth();
        bmpHeight = bitmap.getHeight();
        distCurrent = 1; //Dummy default distance
        dist0 = 1;   //Dummy default distance
        drawMatrix();
        ivObject.setOnTouchListener(MyOnTouchListener);
        touchState = IDLE;
    }
    private void drawMatrix() {
        float curScale = distCurrent / dist0;
        if (curScale < 0.1) {
            curScale = 0.1f;
        }
        Bitmap resizedBitmap;
        int newHeight = (int) (bmpHeight * curScale);
        int newWidth = (int) (bmpWidth * curScale);
        resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
        ivObject.setImageBitmap(resizedBitmap);
    }
    View.OnTouchListener MyOnTouchListener
            = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            // TODO Auto-generated method stub
            float distx, disty;
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    //A pressed gesture has started, the motion contains the initial starting location.
                    tvEvent.setText("ACTION_DOWN");
                    touchState = TOUCH;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    //A non-primary pointer has gone down.
                    tvEvent.setText("ACTION_POINTER_DOWN");
                    touchState = PINCH;
                    //Get the distance when the second pointer touch
                    distx = event.getX(0) - event.getX(1);
                    disty = event.getY(0) - event.getY(1);
                    dist0 = (float) Math.sqrt(distx * distx + disty * disty);
                    break;
                case MotionEvent.ACTION_MOVE:
                    //A change has happened during a press gesture (between ACTION_DOWN and ACTION_UP).
                    tvEvent.setText("ACTION_MOVE");
                    if (touchState == PINCH) {
                        //Get the current distance
                        distx = event.getX(0) - event.getX(1);
                        disty = event.getY(0) - event.getY(1);
                        distCurrent = (float) Math.sqrt(distx * distx + disty * disty);
                        drawMatrix();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    //A pressed gesture has finished.
                    tvEvent.setText("ACTION_UP");
                    touchState = IDLE;
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    //A non-primary pointer has gone up.
                    tvEvent.setText("ACTION_POINTER_UP");
                    touchState = TOUCH;
                    break;
            }
            return true;
        }
    };
}
  • activity_pinch_zoom_gesture.xml
 <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.gesturedemo.PinchZoomGestureActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_pinch_zoom_gesture" />
</android.support.design.widget.CoordinatorLayout>
  • Content_pinch_zoom_gesture.xml
 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_resize_gesture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.gesturedemo.PinchZoomGestureActivity"
    tools:showIn="@layout/activity_pinch_zoom_gesture">
    <TextView
        android:id="@+id/tvEvent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorPrimary"
        android:textSize="16sp" />
    <ImageView
        android:id="@+id/ivObject"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/ic_launcher" />
</RelativeLayout>
  • RotationGestureDetector.java
public class RotationGestureDetector {
        private static final int INVALID_POINTER_ID = -1;
        private float fX, fY, sX, sY;
        private int ptrID1, ptrID2;
        private float mAngle;
        private OnRotationGestureListener mListener;
        public float getAngle() {
            return mAngle;
        }
        public RotationGestureDetector(OnRotationGestureListener listener) {
            mListener = listener;
            ptrID1 = INVALID_POINTER_ID;
            ptrID2 = INVALID_POINTER_ID;
        }
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    ptrID1 = event.getPointerId(event.getActionIndex());
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    ptrID2 = event.getPointerId(event.getActionIndex());
                    sX = event.getX(event.findPointerIndex(ptrID1));
                    sY = event.getY(event.findPointerIndex(ptrID1));
                    fX = event.getX(event.findPointerIndex(ptrID2));
                    fY = event.getY(event.findPointerIndex(ptrID2));
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID) {
                        float nfX, nfY, nsX, nsY;
                        nsX = event.getX(event.findPointerIndex(ptrID1));
                        nsY = event.getY(event.findPointerIndex(ptrID1));
                        nfX = event.getX(event.findPointerIndex(ptrID2));
                        nfY = event.getY(event.findPointerIndex(ptrID2));
                        mAngle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);
                        if (mListener != null) {
                            mListener.OnRotation(this);
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    ptrID1 = INVALID_POINTER_ID;
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    ptrID2 = INVALID_POINTER_ID;
                    break;
                case MotionEvent.ACTION_CANCEL:
                    ptrID1 = INVALID_POINTER_ID;
                    ptrID2 = INVALID_POINTER_ID;
                    break;
            }
            return true;
        }
        private float angleBetweenLines(float fX, float fY, float sX, float sY, float nfX, float nfY, float nsX, float nsY) {
            float angle1 = (float) Math.atan2((fY - sY), (fX - sX));
            float angle2 = (float) Math.atan2((nfY - nsY), (nfX - nsX));
            float angle = ((float) Math.toDegrees(angle1 - angle2)) % 360;
            if (angle < -180.f) angle += 360.0f; if (angle > 180.f) angle -= 360.0f;
            return angle;
        }
        public interface OnRotationGestureListener {
            public void OnRotation(RotationGestureDetector rotationDetector);
        }
    }
  • RotateGestureActivity.java
public class RotateGestureActivity extends AppCompatActivity implements RotationGestureDetector.OnRotationGestureListener {
    private RotationGestureDetector mRotationDetector;
    private ImageView ivObject;
    private float angle = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rotate_gesture);
        initControls();
    }
    private void initControls() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ivObject = (ImageView) findViewById(R.id.ivObject);
        mRotationDetector = new RotationGestureDetector(this);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mRotationDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
    @Override
    public void OnRotation(RotationGestureDetector rotationDetector) {
        Log.d("RotationGestureDetector", "Rotation: " + Float.toString(angle));
        rotate(0 - angle, 0 - rotationDetector.getAngle());
        angle = rotationDetector.getAngle();
    }
    private void rotate(Float angle, float degree) {
        final RotateAnimation rotateAnim = new RotateAnimation(angle, degree,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        rotateAnim.setDuration(0);
        rotateAnim.setFillAfter(true);
        ivObject.startAnimation(rotateAnim);
    }
}
  • activity_rotate_gesture.xml
 <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.gesturedemo.RotateGestureActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_rotate_gesture" />
</android.support.design.widget.CoordinatorLayout>
  • content_rotate_gesture.xml
 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_resize_gesture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.gesturedemo.PinchZoomGestureActivity"
    tools:showIn="@layout/activity_pinch_zoom_gesture">
    <TextView
        android:id="@+id/tvEvent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorPrimary"
        android:textSize="16sp" />
    <ImageView
        android:id="@+id/ivObject"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:scaleType="matrix"
        android:src="@drawable/ic_launcher" />
</RelativeLayout>

string.xml

  <resources>
    <string name="app_name">GestureDemo</string>
    <string name="title_activity_pan_gesture">Drag Drop Gesture</string>
    <string name="title_activity_resize_gesture">Pinch Zoom Gesture</string>
    <string name="hello">Hellow</string>
    <string name="title_activity_rotate_gesture">Rotate Gesture</string>
</resources>

Completed!

Here’s how it will look like once you run the demo.

If you face any problems implementing them, you can contact our developers for help.

And if you want to explore gestures deeply, and implement more customized gestures for your native Android app, Hire Android app developer from us.

We’ve already worked on this feature with our various clients. And needless to say, implementing gesture recognition feature is a great way to easing interaction devices and it can create a richer UX that strive and understand the human “language”.

Grab a free copy of Android Gestures demo from Github.

This page was last edited on November 18th, 2016, at 16:46.
 
0
Shares
 

Want to Create Gesture-based Mobile App? Contact Us Now.

Get your free consultation now