com.freshdigitable.udonroad.ffab.ActionIndicatorView.java Source code

Java tutorial

Introduction

Here is the source code for com.freshdigitable.udonroad.ffab.ActionIndicatorView.java

Source

/*
 * Copyright (c) 2016. Matsuda, Akihit (akihito104)
 *
 * 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 com.freshdigitable.udonroad.ffab;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.freshdigitable.udonroad.R;
import com.freshdigitable.udonroad.ffab.OnFlingListener.Direction;

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

/**
 * ActionIndicatorView shows action icon of FlingableFAB.
 *
 * Created by akihit on 2016/07/04.
 */
public class ActionIndicatorView extends FrameLayout {
    private final Map<Direction, ImageView> icons = new HashMap<>();
    private final Map<Direction, Drawable> drawables = new HashMap<>();

    public ActionIndicatorView(Context context) {
        this(context, null);
    }

    public ActionIndicatorView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ActionIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        final int padding = getResources().getDimensionPixelSize(R.dimen.grid_margin);
        setPadding(padding, padding, padding, padding);

        final View v = View.inflate(context, R.layout.view_action_indicator, this);
        final ImageView iconUp = (ImageView) v.findViewById(R.id.indicator_up);
        final ImageView iconRight = (ImageView) v.findViewById(R.id.indicator_right);
        final ImageView iconDown = (ImageView) v.findViewById(R.id.indicator_down);
        final ImageView iconLeft = (ImageView) v.findViewById(R.id.indicator_left);
        icons.put(Direction.UP, iconUp);
        icons.put(Direction.RIGHT, iconRight);
        icons.put(Direction.DOWN, iconDown);
        icons.put(Direction.LEFT, iconLeft);
    }

    public void setDrawable(Direction direction, Drawable drawable) {
        drawables.put(direction, drawable);
        if (direction.isOnAxis()) {
            icons.get(direction).setImageDrawable(drawable);
        }
    }

    public void onActionSelected(Direction direction) {
        if (direction == Direction.UNDEFINED) {
            return;
        }
        for (ImageView ic : icons.values()) {
            ic.setVisibility(INVISIBLE);
        }

        if (direction.isOnAxis()) {
            translationTo(direction, TransCoefs.ORIGIN);
        } else {
            final Drawable drawable = drawables.get(direction);
            if (drawable != null) {
                final Direction neighbor = direction.getBothNeighbor()[0];
                icons.get(neighbor).setImageDrawable(drawable);
                translationTo(neighbor, TransCoefs.ORIGIN);
                return;
            }
            if (direction == Direction.UP_RIGHT) {
                translationTo(Direction.UP, TransCoefs.SECOND_QUAD);
                translationTo(Direction.RIGHT, TransCoefs.FORTH_QUAD);
            } else if (direction == Direction.DOWN_RIGHT) {
                translationTo(Direction.RIGHT, TransCoefs.FIRST_QUAD);
                translationTo(Direction.DOWN, TransCoefs.THIRD_QUAD);
            } else if (direction == Direction.DOWN_LEFT) {
                translationTo(Direction.LEFT, TransCoefs.SECOND_QUAD);
                translationTo(Direction.DOWN, TransCoefs.FORTH_QUAD);
            } else if (direction == Direction.UP_LEFT) {
                translationTo(Direction.UP, TransCoefs.FIRST_QUAD);
                translationTo(Direction.LEFT, TransCoefs.THIRD_QUAD);
            }
        }
    }

    private void translationTo(Direction direction, TransCoefs coefs) {
        translationTo(icons.get(direction), coefs);
    }

    private void translationTo(View ic, TransCoefs coefs) {
        final float dX = getPaddingLeft() + coefs.xCoef * calcContentWidth() - calcCenterX(ic);
        final float dY = getPaddingTop() + coefs.yCoef * calcContentHeight() - calcCenterY(ic);
        setTranslation(ic, dX, dY);
        setScale(ic, coefs.scale);
        ic.setVisibility(VISIBLE);
    }

    public void onActionLeave(Direction direction) {
        if (direction == Direction.UNDEFINED) {
            return;
        }
        if (direction.isOnAxis()) {
            resetViewTransforms(direction);
        } else {
            for (Direction d : direction.getBothNeighbor()) {
                resetViewTransforms(d);
            }
        }
        for (Direction d : icons.keySet()) {
            setDrawable(d, drawables.get(d));
        }
        for (ImageView ic : icons.values()) {
            ic.setVisibility(VISIBLE);
        }
    }

    private void resetViewTransforms(@NonNull Direction direction) {
        final ImageView icon = icons.get(direction);
        if (icon != null) {
            setScale(icon, 1);
            setTranslation(icon, 0, 0);
        }
    }

    private static float calcCenterY(View ic) {
        return ic.getY() + ic.getHeight() / 2;
    }

    private static float calcCenterX(View ic) {
        return ic.getX() + ic.getWidth() / 2;
    }

    private float calcContentWidth() {
        return getWidth() - getPaddingRight() - getPaddingLeft();
    }

    private float calcContentHeight() {
        return getHeight() - getPaddingTop() - getPaddingBottom();
    }

    private static void setScale(@NonNull View icon, float scale) {
        ViewCompat.setScaleX(icon, scale);
        ViewCompat.setScaleY(icon, scale);
    }

    private static void setTranslation(View ic, float dX, float dY) {
        ViewCompat.setTranslationX(ic, dX);
        ViewCompat.setTranslationY(ic, dY);
    }

    private enum TransCoefs {
        ORIGIN(0.5f, 0.5f, 2f), FIRST_QUAD(0.75f, 0.25f, 1.5f), SECOND_QUAD(0.25f, 0.25f, 1.5f), THIRD_QUAD(0.25f,
                0.75f, 1.5f), FORTH_QUAD(0.75f, 0.75f, 1.5f),;

        final float xCoef;
        final float yCoef;
        final float scale;

        TransCoefs(float xCoef, float yCoef, float scale) {
            this.xCoef = xCoef;
            this.yCoef = yCoef;
            this.scale = scale;
        }
    }
}