Android Open Source - android-sholi Interceptor Frame Layout






From Project

Back to project page android-sholi.

License

The source code is released under:

GNU General Public License

If you think the Android project android-sholi listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * ShoLi, a simple tool to produce short lists.
 * Copyright (C) 2014  David Soulayrol//from  w w w  . j  a  v  a2s  . c  o  m
 *
 * ShoLi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ShoLi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package name.soulayrol.rhaa.widget;

import android.content.Context;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;

import java.util.HashMap;
import java.util.Map;

import name.soulayrol.rhaa.sholi.data.Action;


/**
 * A FrameLayout able to intercept multi-touch gestures.
 */
public class InterceptorFrameLayout extends FrameLayout {

    public enum Gesture {
        SINGLE_TAP,
        FLING_TO_LEFT,
        FLING_TO_RIGHT,
    }

    public interface Listener {
        public void execute(Action action);
    }

    Listener _listener;

    private Map<Gesture, Action> _actions;

    private int _touchSlope;

    private int _minFlingVelocity;

    /**
     * The information detailing the current gesture.
     *
     * If this object is null, then no gesture has been detected
     * and the event shall be dispatched downward.
     */
    private EventTracker _eventTracker;

    public InterceptorFrameLayout(Context context, android.util.AttributeSet set) {
        super(context, set);

        ViewConfiguration vc = ViewConfiguration.get(context);

        _actions = new HashMap<Gesture, Action>();
        _touchSlope = vc.getScaledTouchSlop();
        _minFlingVelocity = vc.getScaledMinimumFlingVelocity();
    }

    public void startInterception(Listener listener) {
        _listener = listener;
    }

    public void configure(Gesture gesture, Action action) {
        _actions.put(gesture, action);
    }

    public void ignore(Gesture gesture) {
        _actions.remove(gesture);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (_listener == null)
            return false;

        switch (event.getActionMasked()) {
            // Always handle the case of the touch gesture being complete.
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                _eventTracker = null;
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                _eventTracker = new EventTracker(event);
                break;
        }

        return _eventTracker != null;
    }

    public boolean onTouchEvent(MotionEvent event) {
        if (_eventTracker != null) {
            _eventTracker = _eventTracker.update(event);
        }
        return _eventTracker != null;
    }

    private void execute(Gesture gesture) {
        if (_actions.containsKey(gesture))
            _listener.execute(_actions.get(gesture));
    }

    private class EventTracker {

        private int _id;

        private float _startX;

        private float _startY;

        private VelocityTracker _vTracker;

        public EventTracker(MotionEvent event) {
            final int idx = event.getActionIndex();
            _startX = event.getX(idx);
            _startY = event.getY(idx);
            _id = event.getPointerId(idx);
            _vTracker = VelocityTracker.obtain();
            _vTracker.addMovement(event);
        }

        public EventTracker update(MotionEvent event) {
            switch (event.getActionMasked()) {
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    return null;
                case MotionEvent.ACTION_POINTER_UP:
                    _vTracker.addMovement(event);
                    handleGesture(event);
                    return null;
                case MotionEvent.ACTION_MOVE:
                    _vTracker.addMovement(event);
                    break;
            }
            return this;
        }

        private void handleGesture(MotionEvent event) {
            int i = event.findPointerIndex(_id);
            int dx = (int) (event.getX(i) - _startX);
            int dy = (int) (event.getY(i) - _startY);
            if (Math.abs(dx) < _touchSlope && Math.abs(dy) < _touchSlope) {
                execute(Gesture.SINGLE_TAP);
            } else if (Math.abs(dy) < Math.abs(dx / 5)) {
                _vTracker.computeCurrentVelocity(1000);
                if (Math.abs(_vTracker.getXVelocity()) > _minFlingVelocity) {
                    execute((dx < 0)? Gesture.FLING_TO_LEFT: Gesture.FLING_TO_RIGHT);
                }
            }
            _vTracker.recycle();
            _vTracker = null;
        }
    }
}




Java Source Code List

name.soulayrol.rhaa.sholi.AbstractListFragment.java
name.soulayrol.rhaa.sholi.CheckingFragment.java
name.soulayrol.rhaa.sholi.DataOverviewActivity.java
name.soulayrol.rhaa.sholi.DataOverviewFragment.java
name.soulayrol.rhaa.sholi.EditFragment.java
name.soulayrol.rhaa.sholi.ImportFragment.java
name.soulayrol.rhaa.sholi.MainActivity.java
name.soulayrol.rhaa.sholi.SettingsActivity.java
name.soulayrol.rhaa.sholi.SettingsFragment.java
name.soulayrol.rhaa.sholi.data.AbstractLazyListAdapter.java
name.soulayrol.rhaa.sholi.data.Action.java
name.soulayrol.rhaa.sholi.data.ItemLazyListAdapter.java
name.soulayrol.rhaa.sholi.data.Operations.java
name.soulayrol.rhaa.sholi.data.model.Checkable.java
name.soulayrol.rhaa.sholi.data.model.PersistentObject.java
name.soulayrol.rhaa.sholi.model.Generator.java
name.soulayrol.rhaa.widget.InterceptorFrameLayout.java