Search code examples
androiddrawgesture

Gesture automatically draws itself


I've seen it on Dolphin Browser. There're some gestures that're already created by default. They will redraw themselves so that users know where to begin drawing. I've noticed that in Gesture object, there's a method named toPath(). But I have no clue how to use it and I'm not sure if I'm on the right track. Can somebody tell me how to do it? Thanks. You can take a look at the picture below.

enter image description here


Solution

  • First of all I would suggest to take a look at GestureBuilder app from SDK samples. It has exactly that is shown in your question (small gesture thumbnails).

    I've slightly extended that example to make usage of Gesture APIs more clear:

    Add the following code into GestureBuilderActivity from GeatureBuilder sample:

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
    
        final Intent intent = new Intent(getApplicationContext(), ShowGestureActivity.class);
    
        intent.putExtra(ShowGestureActivity.GESTURE_NAME_EXTRA, ((NamedGesture)v.getTag()).name);
        startActivity(intent);
    }
    

    It will launch new test activity ShowGestureActivity:

    public class ShowGestureActivity extends Activity {
        public static final String GESTURE_NAME_EXTRA = "gesture_extra";
        private Gesture mGesture = null;
        private FrameLayout mContainer;
        private MyPathView mMyPathView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.show_gesture);
    
            final ArrayList<Gesture> gestures = GestureBuilderActivity.getStore()
                    .getGestures(getIntent().getStringExtra(GESTURE_NAME_EXTRA));
    
            if (gestures.size() == 1) {
                mGesture = gestures.get(0);
            } else {
                Toast.makeText(getApplicationContext(), "No gesture available!", Toast.LENGTH_LONG).show();
            }
    
            mContainer = (FrameLayout) findViewById(R.id.container);
            mMyPathView = (MyPathView) findViewById(R.id.myPathView);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.show_gesture_menu, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            final int id = item.getItemId();
    
            if (mGesture == null) {
                return false;
            }
    
            switch (id) {
                case R.id.action_show_gesture_bmp:
                    final Bitmap gestureBmp = mGesture.toBitmap(mContainer.getWidth(), mContainer.getHeight(),
                            getResources().getDimensionPixelSize(R.dimen.gesture_thumbnail_inset), Color.YELLOW);
    
                    mMyPathView.setVisibility(View.GONE);
                    mContainer.setBackground(new BitmapDrawable(getResources(), gestureBmp));
                    return true;
    
                case R.id.action_show_gesture_path:
                    mMyPathView.setPath(mGesture.toPath(mContainer.getWidth(), mContainer.getHeight(),
                            getResources().getDimensionPixelSize(R.dimen.gesture_thumbnail_inset), 10));
                    mMyPathView.setVisibility(View.VISIBLE);
                    mContainer.setBackground(null);
                    return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }
    

    In onOptionsItemSelected you can see usage of both Gesture methods available for drawing. Seems toBitmap is quite clear (GesturesBuilder app itself uses that method for gestures thumbnails display in the list). Regarding toPath: it provides you with the path which corresponds to the Gesture. After that you can use that path for drawing as you want. MyPathView from test activity above provides easiest way of doing so:

    public class MyPathView extends View {
        private Paint mPaint;
        private Path mPath = null;
    
        public MyPathView(Context context) {
            super(context);
            init(null, 0);
        }
    
        public MyPathView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs, 0);
        }
    
        public MyPathView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs, defStyle);
        }
    
        private void init(AttributeSet attrs, int defStyle) {
            mPaint = new Paint();
            mPaint.setColor(Color.YELLOW);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.paint_width));
        }
    
        public void setPath(final Path path) {
            mPath = path;
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            if (mPath != null) {
                canvas.drawPath(mPath, mPaint);
            }
        }
    }
    

    And xml is (just to make example easy to compile):

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container">
    
        <com.sandrstar.testapp.test.MyPathView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/myPathView"
            android:visibility="gone"/>
    </FrameLayout>
    

    If you want to apply some kind of animation to gesture drawing, you need to get path, create custom view as described above and apply some animation method, e.g. like one described here Draw path on canvas with animation