org.opensilk.common.widget.FlingyFabLayout.java Source code

Java tutorial

Introduction

Here is the source code for org.opensilk.common.widget.FlingyFabLayout.java

Source

/*
 * Copyright (C) 2014 OpenSilk Productions LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.opensilk.common.widget;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

/**
 * Created by drew on 10/14/14.
 */
public abstract class FlingyFabLayout extends RelativeLayout {

    protected enum Direction {
        UP, DOWN, LEFT, RIGHT,
    }

    final ViewDragHelper dragHelper;

    int verticalRange;
    int horizontalRange;
    int draggingState;

    public FlingyFabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        dragHelper = ViewDragHelper.create(this, new DragHelperCallback());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return dragHelper.shouldInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        dragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        verticalRange = h;
        horizontalRange = w;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    /**
     * Called when child is release, override to perform actions
     */
    protected void onFabFling(View child, Direction direction) {

    }

    public abstract boolean canCaptureView(View child, int pointerId);

    private class DragHelperCallback extends ViewDragHelper.Callback {

        int startPosTop;
        int startPosLeft;

        @Override
        public void onViewDragStateChanged(int state) {
            super.onViewDragStateChanged(state);
            if (state == draggingState)
                return;
            draggingState = state;
        }

        @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            startPosTop = capturedChild.getTop();
            startPosLeft = capturedChild.getLeft();
            //            Timber.d("onViewCaptured startPos x=%d, y=%d", startPosTop, startPosLeft);
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            //            Timber.d( "onViewReleased(xvel=%f, yvel=%f", xvel, yvel);
            int endPosTop = releasedChild.getTop();
            int entPosLeft = releasedChild.getLeft();
            int dTop = startPosTop - endPosTop;
            int dLeft = startPosLeft - entPosLeft;
            //            Timber.d( "Direction dTop=%d dLeft=%d", dTop, dLeft);
            String dir = "";
            if (Math.abs(dTop) > Math.abs(dLeft)) {
                //VERTICAL
                dir += "VERTICAL";
                if (dTop > 0) {
                    //UP
                    dir += " UP";
                    onFabFling(releasedChild, Direction.UP);
                } else {
                    //DOWN
                    dir += " DOWN";
                    onFabFling(releasedChild, Direction.DOWN);
                }
            } else {
                //HORIZONTAL
                dir += "HORIZONTAL";
                if (dLeft > 0) {
                    //LEFT
                    dir += " LEFT";
                    onFabFling(releasedChild, Direction.LEFT);
                } else {
                    //RIGHT
                    dir += " RIGHT";
                    onFabFling(releasedChild, Direction.RIGHT);
                }
            }
            //            Timber.d( "Overall Direction = %s", dir);
            dragHelper.settleCapturedViewAt(startPosLeft, startPosTop);
            invalidate();
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return horizontalRange;
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            return verticalRange;
        }

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return canCaptureView(child, pointerId);
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return top;
        }
    }

}