Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6a463a9 authored by Romain Guy's avatar Romain Guy
Browse files

Add a new API to ListView: setGestures(int). This allows developers to enable...

Add a new API to ListView: setGestures(int). This allows developers to enable gestures to jump inside the list or filter it. This change also introduces a new XML attribute to control this API. It also adds the ability to theme the GestureOverlayView from the gestures library. Finally, this adds a new VERSION header to the binary format used to store the letters for the recognizer.
parent cfcc0df2
Loading
Loading
Loading
Loading
+165 −87
Original line number Diff line number Diff line
@@ -3584,17 +3584,6 @@
 visibility="public"
>
</field>
<field name="donut_resource_pad39"
 type="int"
 transient="false"
 volatile="false"
 value="16843385"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad4"
 type="int"
 transient="false"
@@ -3606,61 +3595,6 @@
 visibility="public"
>
</field>
<field name="donut_resource_pad40"
 type="int"
 transient="false"
 volatile="false"
 value="16843384"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad41"
 type="int"
 transient="false"
 volatile="false"
 value="16843383"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad42"
 type="int"
 transient="false"
 volatile="false"
 value="16843382"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad43"
 type="int"
 transient="false"
 volatile="false"
 value="16843381"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad44"
 type="int"
 transient="false"
 volatile="false"
 value="16843380"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="donut_resource_pad5"
 type="int"
 transient="false"
@@ -4134,6 +4068,28 @@
 visibility="public"
>
</field>
<field name="fadeDuration"
 type="int"
 transient="false"
 volatile="false"
 value="16843384"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="fadeOffset"
 type="int"
 transient="false"
 volatile="false"
 value="16843383"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="fadingEdge"
 type="int"
 transient="false"
@@ -4453,6 +4409,39 @@
 visibility="public"
>
</field>
<field name="gestureColor"
 type="int"
 transient="false"
 volatile="false"
 value="16843381"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="gestureStrokeWidth"
 type="int"
 transient="false"
 volatile="false"
 value="16843380"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="gestures"
 type="int"
 transient="false"
 volatile="false"
 value="16843385"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="gradientRadius"
 type="int"
 transient="false"
@@ -8853,6 +8842,17 @@
 visibility="public"
>
</field>
<field name="uncertainGestureColor"
 type="int"
 transient="false"
 volatile="false"
 value="16843382"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="unselectedAlpha"
 type="int"
 transient="false"
@@ -46572,6 +46572,20 @@
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</constructor>
<constructor name="GestureOverlayView"
 type="android.gesture.GestureOverlayView"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<parameter name="defStyle" type="int">
</parameter>
</constructor>
<method name="addOnGestureListener"
 return="void"
 abstract="false"
@@ -46653,6 +46667,19 @@
 visibility="public"
>
</method>
<method name="processEvent"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="event" type="android.view.MotionEvent">
</parameter>
</method>
<method name="removeOnGestureListener"
 return="void"
 abstract="false"
@@ -46718,27 +46745,6 @@
<parameter name="color" type="int">
</parameter>
</method>
<field name="DEFAULT_GESTURE_COLOR"
 type="int"
 transient="false"
 volatile="false"
 value="-256"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="DEFAULT_UNCERTAIN_GESTURE_COLOR"
 type="int"
 transient="false"
 volatile="false"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<interface name="GestureOverlayView.OnGestureListener"
 abstract="true"
@@ -159466,6 +159472,17 @@
 visibility="public"
>
</method>
<method name="getGestures"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getListPaddingBottom"
 return="int"
 abstract="false"
@@ -159839,6 +159856,19 @@
<parameter name="filterText" type="java.lang.String">
</parameter>
</method>
<method name="setGestures"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="gestures" type="int">
</parameter>
</method>
<method name="setOnScrollListener"
 return="void"
 abstract="false"
@@ -159984,6 +160014,39 @@
<parameter name="dr" type="android.graphics.drawable.Drawable">
</parameter>
</method>
<field name="GESTURES_FILTER"
 type="int"
 transient="false"
 volatile="false"
 value="2"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="GESTURES_JUMP"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="GESTURES_NONE"
 type="int"
 transient="false"
 volatile="false"
 value="0"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="TRANSCRIPT_MODE_ALWAYS_SCROLL"
 type="int"
 transient="false"
@@ -168608,6 +168671,21 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="width" type="int">
</parameter>
<parameter name="height" type="int">
</parameter>
</method>
<method name="update"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="x" type="int">
</parameter>
<parameter name="y" type="int">
+151 −94
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008-2009 The Android Open Source Project
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -17,62 +17,54 @@
package android.gesture;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Color;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.internal.R;

import java.util.ArrayList;

/**
 * A (transparent) overlay for gesture input that can be placed on top of other
 * widgets. The view can also be opaque.
 * widgets.
 *
 * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeWidth
 * @attr ref android.R.styleable#GestureOverlayView_gestureColor
 * @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor
 * @attr ref android.R.styleable#GestureOverlayView_fadeDuration
 * @attr ref android.R.styleable#GestureOverlayView_fadeOffset
 */

public class GestureOverlayView extends View {
    static final float TOUCH_TOLERANCE = 3;

    // TODO: Move all these values into XML attributes
    private static final int TRANSPARENT_BACKGROUND = 0x00000000;

    // TODO: SHOULD BE A TOTAL DURATION
    private static final float FADING_ALPHA_CHANGE = 0.15f;
    private static final long FADING_OFFSET = 300;
    private static final long FADING_REFRESHING_RATE = 16;

    private static final int GESTURE_STROKE_WIDTH = 12;
    private static final boolean GESTURE_RENDERING_ANTIALIAS = true;

    private static final boolean DITHER_FLAG = true;

    public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00;
    public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0);

    private static final int REFRESH_RANGE = 10;

    private static final BlurMaskFilter BLUR_MASK_FILTER =
            new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);

    private Paint mGesturePaint;

    private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    private Bitmap mBitmap; // with transparent background
    private Bitmap mBitmap;
    private Canvas mBitmapCanvas;

    private int mCertainGestureColor = DEFAULT_GESTURE_COLOR;
    private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR;
    private long mFadeDuration = 300;
    private long mFadeOffset = 300;
    private long mFadingStart;

    // for rendering immediate ink feedback
    private Rect mInvalidRect = new Rect();
    private float mGestureStroke = 12.0f;
    private int mCertainGestureColor = 0xFFFFFF00;
    private int mUncertainGestureColor = 0x3CFFFF00;
    private int mInvalidateExtraBorder = 10;

    private Path mPath;
    // for rendering immediate ink feedback
    private final Rect mInvalidRect = new Rect();
    private final Path mPath = new Path();

    private float mX;
    private float mY;
@@ -84,26 +76,32 @@ public class GestureOverlayView extends View {
    private Gesture mCurrentGesture = null;

    // TODO: Make this a list of WeakReferences
    private final ArrayList<OnGestureListener> mOnGestureListeners = new ArrayList<OnGestureListener>();
    private ArrayList<GesturePoint> mPointBuffer = null;
    private final ArrayList<OnGestureListener> mOnGestureListeners =
            new ArrayList<OnGestureListener>();
    private final ArrayList<GesturePoint> mPointBuffer = new ArrayList<GesturePoint>(100);

    // fading out effect
    private boolean mIsFadingOut = false;
    private float mFadingAlpha = 1;

    private Handler mHandler = new Handler();
    private final AccelerateDecelerateInterpolator mInterpolator =
            new AccelerateDecelerateInterpolator();

    private final Runnable mFadingOut = new Runnable() {
        public void run() {
            if (mIsFadingOut) {
                mFadingAlpha -= FADING_ALPHA_CHANGE;
                if (mFadingAlpha <= 0) {
                final long now = AnimationUtils.currentAnimationTimeMillis();
                final long duration = now - mFadingStart;

                if (duration > mFadeDuration) {
                    mIsFadingOut = false;
                    mPath = null;
                    mPath.rewind();
                    mCurrentGesture = null;
                    mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
                } else {
                    mHandler.postDelayed(this, FADING_REFRESHING_RATE);
                    float interpolatedTime = Math.max(0.0f,
                            Math.min(1.0f, duration / (float) mFadeDuration));
                    mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime);
                    postDelayed(this, 16);
                }
                invalidate();
            }
@@ -116,7 +114,27 @@ public class GestureOverlayView extends View {
    }

    public GestureOverlayView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this(context, attrs, com.android.internal.R.attr.gestureOverlayViewStyle);
    }

    public GestureOverlayView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.GestureOverlayView, defStyle, 0);

        mGestureStroke = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
                mGestureStroke);
        mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1);
        mCertainGestureColor = a.getColor(R.styleable.GestureOverlayView_gestureColor,
                mCertainGestureColor);
        mUncertainGestureColor = a.getColor(R.styleable.GestureOverlayView_uncertainGestureColor,
                mUncertainGestureColor);
        mFadeDuration = a.getInt(R.styleable.GestureOverlayView_fadeDuration, (int) mFadeDuration);
        mFadeOffset = a.getInt(R.styleable.GestureOverlayView_fadeOffset, (int) mFadeOffset);

        a.recycle();

        init();
    }

@@ -139,6 +157,7 @@ public class GestureOverlayView extends View {
            mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
            mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
        }
        invalidate();
    }

    public void setGestureColor(int color) {
@@ -157,6 +176,16 @@ public class GestureOverlayView extends View {
        return mCertainGestureColor;
    }

    public float getGestureStroke() {
        return mGestureStroke;
    }

    public void setGestureStroke(float gestureStroke) {
        mGestureStroke = gestureStroke;
        mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1);
        mGesturePaint.setStrokeWidth(mGestureStroke);
    }

    /**
     * Set the gesture to be shown in the view
     * 
@@ -182,14 +211,12 @@ public class GestureOverlayView extends View {

        final Paint gesturePaint = mGesturePaint;
        gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
        gesturePaint.setColor(DEFAULT_GESTURE_COLOR);
        gesturePaint.setColor(mCertainGestureColor);
        gesturePaint.setStyle(Paint.Style.STROKE);
        gesturePaint.setStrokeJoin(Paint.Join.ROUND);
        gesturePaint.setStrokeCap(Paint.Cap.ROUND);
        gesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
        gesturePaint.setStrokeWidth(mGestureStroke);
        gesturePaint.setDither(DITHER_FLAG);

        mPath = null;
    }

    @Override
@@ -226,6 +253,10 @@ public class GestureOverlayView extends View {
        mOnGestureListeners.remove(listener);
    }

    public void removeAllOnGestureListeners() {
        mOnGestureListeners.clear();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
@@ -240,10 +271,8 @@ public class GestureOverlayView extends View {
        }

        // draw the current stroke
        if (mPath != null) {
        canvas.drawPath(mPath, mGesturePaint);
    }
    }

    /**
     * Clear up the overlay
@@ -253,12 +282,13 @@ public class GestureOverlayView extends View {
     */
    public void clear(boolean fadeOut) {
        if (fadeOut) {
            mFadingAlpha = 1;
            mFadingAlpha = 1.0f;
            mIsFadingOut = true;
            mHandler.removeCallbacks(mFadingOut);
            mHandler.postDelayed(mFadingOut, FADING_OFFSET);
            removeCallbacks(mFadingOut);
            mFadingStart = AnimationUtils.currentAnimationTimeMillis() + mFadeOffset;
            postDelayed(mFadingOut, mFadeOffset);
        } else {
            mPath = null;
            mPath.rewind();
            mCurrentGesture = null;
            if (mBitmap != null) {
                mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
@@ -269,7 +299,7 @@ public class GestureOverlayView extends View {

    public void cancelFadingOut() {
        mIsFadingOut = false;
        mHandler.removeCallbacks(mFadingOut);
        removeCallbacks(mFadingOut);
    }

    @Override
@@ -278,6 +308,12 @@ public class GestureOverlayView extends View {
            return true;
        }

        processEvent(event);

        return true;
    }

    public void processEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Rect rect = touchStart(event);
@@ -290,12 +326,14 @@ public class GestureOverlayView extends View {
                }
                break;
            case MotionEvent.ACTION_UP:
                touchUp(event);
                touchUp(event, false);
                invalidate();
                break;
            case MotionEvent.ACTION_CANCEL:
                touchUp(event, true);
                invalidate();
                break;
        }

        return true;
    }

    private Rect touchStart(MotionEvent event) {
@@ -310,7 +348,7 @@ public class GestureOverlayView extends View {
        // if there is fading out going on, stop it.
        if (mIsFadingOut) {
            mIsFadingOut = false;
            mHandler.removeCallbacks(mFadingOut);
            removeCallbacks(mFadingOut);
            mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
            mCurrentGesture = null;
        }
@@ -325,14 +363,13 @@ public class GestureOverlayView extends View {
            mCurrentGesture = new Gesture();
        }

        mPointBuffer = new ArrayList<GesturePoint>();
        mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));

        mPath = new Path();
        mPath.rewind();
        mPath.moveTo(x, y);

        mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE,
                (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE);
        mInvalidRect.set((int) x - mInvalidateExtraBorder, (int) y - mInvalidateExtraBorder,
                (int) x + mInvalidateExtraBorder, (int) y + mInvalidateExtraBorder);
        
        mCurveEndX = x;
        mCurveEndY = y;
@@ -343,37 +380,48 @@ public class GestureOverlayView extends View {
    private Rect touchMove(MotionEvent event) {
        Rect areaToRefresh = null;
        
        float x = event.getX();
        float y = event.getY();
        final float x = event.getX();
        final float y = event.getY();

        final float previousX = mX;
        final float previousY = mY;

        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        final float dx = Math.abs(x - previousX);
        final float dy = Math.abs(y - previousY);
        
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        if (dx >= GestureStroke.TOUCH_TOLERANCE || dy >= GestureStroke.TOUCH_TOLERANCE) {
            areaToRefresh = mInvalidRect;

            // start with the curve end
            mInvalidRect.set((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
                    (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);
            areaToRefresh.set(
                    (int) mCurveEndX - mInvalidateExtraBorder,
                    (int) mCurveEndY - mInvalidateExtraBorder,
                    (int) mCurveEndX + mInvalidateExtraBorder,
                    (int) mCurveEndY + mInvalidateExtraBorder);
            
            mCurveEndX = (x + previousX) / 2;
            mCurveEndY = (y + previousY) / 2;

            mCurveEndX  = (x + mX) / 2;
            mCurveEndY = (y + mY) / 2;
            mPath.quadTo(mX, mY, mCurveEndX, mCurveEndY);
            mPath.quadTo(previousX, previousY, mCurveEndX, mCurveEndY);
            
            // union with the control point of the new curve
            mInvalidRect.union((int) mX - REFRESH_RANGE, (int) mY - REFRESH_RANGE,
                    (int) mX + REFRESH_RANGE, (int) mY + REFRESH_RANGE);
            areaToRefresh.union(
                    (int) previousX - mInvalidateExtraBorder,
                    (int) previousY - mInvalidateExtraBorder,
                    (int) previousX + mInvalidateExtraBorder,
                    (int) previousY + mInvalidateExtraBorder);
            
            // union with the end point of the new curve
            mInvalidRect.union((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
                    (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);

            areaToRefresh = mInvalidRect;
            areaToRefresh.union(
                    (int) mCurveEndX - mInvalidateExtraBorder,
                    (int) mCurveEndY - mInvalidateExtraBorder,
                    (int) mCurveEndX + mInvalidateExtraBorder,
                    (int) mCurveEndY + mInvalidateExtraBorder);

            mX = x;
            mY = y;
        }


        mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));

        // pass the event to handlers
@@ -386,34 +434,43 @@ public class GestureOverlayView extends View {
        return areaToRefresh;
    }

    private void touchUp(MotionEvent event) {
    private void touchUp(MotionEvent event, boolean cancel) {
        // add the stroke to the current gesture
        mCurrentGesture.addStroke(new GestureStroke(mPointBuffer));

        // add the stroke to the double buffer
        mGesturePaint.setMaskFilter(BLUR_MASK_FILTER);
        mBitmapCanvas.drawPath(mPath, mGesturePaint);
        mGesturePaint.setMaskFilter(null);

        if (!cancel) {
            // pass the event to handlers
            final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
            final int count = listeners.size();
            for (int i = 0; i < count; i++) {
                listeners.get(i).onGestureEnded(this, event);
            }
        } else {
            // pass the event to handlers
            final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
            final int count = listeners.size();
            for (int i = 0; i < count; i++) {
                listeners.get(i).onGestureCancelled(this, event);
            }
        }

        mPath = null;        
        mPointBuffer = null;
        mPath.rewind();
        mPointBuffer.clear();
    }

    /**
     * An interface for processing gesture events
     */
    public static interface OnGestureListener {
        public void onGestureStarted(GestureOverlayView overlay, MotionEvent event);
        void onGestureStarted(GestureOverlayView overlay, MotionEvent event);

        void onGesture(GestureOverlayView overlay, MotionEvent event);

        public void onGesture(GestureOverlayView overlay, MotionEvent event);
        void onGestureEnded(GestureOverlayView overlay, MotionEvent event);

        public void onGestureEnded(GestureOverlayView overlay, MotionEvent event);
        void onGestureCancelled(GestureOverlayView overlay, MotionEvent event);
    }
}
+5 −3
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008-2009 The Android Open Source Project
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@ import java.util.ArrayList;
 * A gesture stroke started on a touch down and ended on a touch up.
 */
public class GestureStroke {
    static final float TOUCH_TOLERANCE = 3;

    public final RectF boundingBox;

    public final float length;
@@ -156,8 +158,8 @@ public class GestureStroke {
            } else {
                float dx = Math.abs(x - mX);
                float dy = Math.abs(y - mY);
                if (dx >= GestureOverlayView.TOUCH_TOLERANCE ||
                        dy >= GestureOverlayView.TOUCH_TOLERANCE) {
                if (dx >= TOUCH_TOLERANCE ||
                        dy >= TOUCH_TOLERANCE) {
                    path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
                    mX = x;
                    mY = y;
+38 −31
Original line number Diff line number Diff line
@@ -45,18 +45,16 @@ public class LetterRecognizer {
    
    private GestureLibrary mGestureLibrary;

    private final Comparator<Prediction> mComparator = new PredictionComparator();

    private static class SigmoidUnit {
        final float[] mWeights;

        private boolean mComputed;
        private float mResult;

        SigmoidUnit(float[] weights) {
            mWeights = weights;
        }

        private float compute(float[] inputs) {
            if (!mComputed) {
            float sum = 0;

            final int count = inputs.length;
@@ -67,10 +65,7 @@ public class LetterRecognizer {
            }
            sum += weights[weights.length - 1];

                mResult = 1.0f / (float) (1 + Math.exp(-sum));
                mComputed = true;
            }
            return mResult;
            return 1.0f / (float) (1 + Math.exp(-sum));
        }
    }

@@ -91,16 +86,25 @@ public class LetterRecognizer {
    }

    public ArrayList<Prediction> recognize(Gesture gesture) {
        return recognize(gesture, null);
    }

    public ArrayList<Prediction> recognize(Gesture gesture, ArrayList<Prediction> predictions) {
        float[] query = GestureUtilities.spatialSampling(gesture, mPatchSize);
        ArrayList<Prediction> predictions = classify(query);
        predictions = classify(query, predictions);
        adjustPrediction(gesture, predictions);
        return predictions;
    }

    private ArrayList<Prediction> classify(float[] vector) {
    private ArrayList<Prediction> classify(float[] vector, ArrayList<Prediction> predictions) {
        if (predictions == null) {
            predictions = new ArrayList<Prediction>();
        } else {
            predictions.clear();
        }

        final float[] intermediateOutput = compute(mHiddenLayer, vector);
        final float[] output = compute(mOutputLayer, intermediateOutput);
        final ArrayList<Prediction> predictions = new ArrayList<Prediction>();

        double sum = 0;

@@ -117,19 +121,8 @@ public class LetterRecognizer {
            predictions.get(i).score /= sum;
        }

        Collections.sort(predictions, new Comparator<Prediction>() {
            public int compare(Prediction object1, Prediction object2) {
                double score1 = object1.score;
                double score2 = object2.score;
                if (score1 > score2) {
                    return -1;
                } else if (score1 < score2) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });
        Collections.sort(predictions, mComparator);

        return predictions;
    }

@@ -270,4 +263,18 @@ public class LetterRecognizer {
            }
        }
    }

    private static class PredictionComparator implements Comparator<Prediction> {
        public int compare(Prediction object1, Prediction object2) {
            double score1 = object1.score;
            double score2 = object2.score;
            if (score1 > score2) {
                return -1;
            } else if (score1 < score2) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}
+9 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading