Depth-LIB-Android- icon indicating copy to clipboard operation
Depth-LIB-Android- copied to clipboard

[Help] - DepthFAB

Open MSay2 opened this issue 8 years ago • 1 comments

Hello

I added a new JAVA file that I named "DepthFAB". It works fine but I tried to put the "StateListAnimator" function on my main XML file but this function is completely ignored. (Although "OnClickListener" works)

My code:

<no.agens.depth.lib.DepthFAB
		android:id="@+id/fab_container"
		android:layout_width="56dp"
		android:layout_height="56dp"
		android:layout_alignParentRight="true"
		android:layout_marginRight="16dp"
		android:layout_marginTop="232dp"
		android:background="@drawable/circle"
		android:src="@drawable/ic_launcher"
		android:elevation="9dp"
		android:layerType="hardware"
		android:stateListAnimator="@animator/raise"
		app:custom_elevation="6dp"
		app:edge_color="?android:attr/colorAccent"
		app:is_circle="true">

	</no.agens.depth.lib.DepthFAB>
package no.agens.depth.lib;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.RelativeLayout;
import android.widget.Checkable;
import android.widget.ImageButton;

import no.agens.depth.lib.R;

public class DepthFAB extends ImageButton implements Checkable
{
	public static final int DEFAULT_EDGE_COLOR = Color.WHITE;
    public static final int DEFAULT_THICKNESS = 2;
	
	private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };

    private boolean isChecked = false;
    private int minOffset;
	
    Paint edgePaint = new Paint();
	
	@Override
    public boolean hasOverlappingRendering() 
	{
        return false;
    }
	
	public Paint getEdgePaint()
	{
        return edgePaint;
    }


    public void setEdgePaint(Paint edgePaint)
	{
        this.edgePaint = edgePaint;
    }

    private void initView(AttributeSet attrs) 
	{

        edgePaint.setColor(DEFAULT_EDGE_COLOR);
        edgePaint.setAntiAlias(true);
        if (attrs != null)
		{
            TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.DepthView);
            edgePaint.setColor(arr.getInt(R.styleable.DepthView_edge_color, DEFAULT_EDGE_COLOR));
            setIsCircle(arr.getBoolean(R.styleable.DepthView_is_circle, false));
            depth = arr.getDimension(R.styleable.DepthView_depth, DEFAULT_THICKNESS * getResources().getDisplayMetrics().density);
            customShadowElevation = arr.getDimension(R.styleable.DepthView_custom_elevation, 0);
        }
		else
		{
            edgePaint.setColor(DEFAULT_EDGE_COLOR);
            depth = DEFAULT_THICKNESS * getResources().getDisplayMetrics().density;
        }
		
        setOutlineProvider(new ViewOutlineProvider() 
		{
			@Override
			public void getOutline(View view, Outline outline)
			{ }
		});
    }
	
	public DepthFAB(Context context)
	{
		super(context);
		initView(null);
	}

	public DepthFAB(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		initView(attrs);
	}

    public DepthFAB(Context context, AttributeSet attrs, int defStyleAttr)
	{
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }

    private float depth;

    public float getDepth() 
	{
        return depth;
    }

    public void setDepth(float depth) 
	{
        this.depth = depth;
        ((View)getParent()).invalidate();
    }

    public boolean isCircle() 
	{
        return isCircle;
    }

    public void setIsCircle(boolean isCircle)
	{
        this.isCircle = isCircle;
    }

    private boolean isCircle = false;

    float[] prevSrc = new float[8];

    public boolean calculateBounds()
	{
        float[] src = new float[8];
        float[] dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};
        Matrix matrix = getMatrix();

        matrix.mapPoints(src, dst);
        topLeft.x = src[0] + getLeft();
        topLeft.y = src[1] + getTop();
        topRight.x = src[2] + getLeft();
        topRight.y = src[3] + getTop();

        bottomLeft.x = src[4] + getLeft();
        bottomLeft.y = src[5] + getTop();
        bottomRight.x = src[6] + getLeft();
        bottomRight.y = src[7] + getTop();
        boolean returnValue = hasMatrixChanged(src);
        prevSrc = src;
        float percentFrom90X = (getRotationX()) / 90f;
        float percentFrom90Y = (-getRotationY()) / 90f;


        matrix.postTranslate(percentFrom90Y * getDepth(), percentFrom90X * getDepth());
        src = new float[8];
        dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};
        matrix.mapPoints(src, dst);

        topLeftBack.x = src[0] + getLeft();
        topLeftBack.y = src[1] + getTop();
        topRightBack.x = src[2] + getLeft();
        topRightBack.y = src[3] + getTop();

        bottomLeftBack.x = src[4] + getLeft();
        bottomLeftBack.y = src[5] + getTop();
        bottomRightBack.x = src[6] + getLeft();
        bottomRightBack.y = src[7] + getTop();
        customShadow.calculateBounds(this);

        return returnValue;
    }

    boolean hasMatrixChanged(float[] newSrc)
	{
        for (int i = 0; i < 8; i++) 
		{
            if (newSrc[i] != prevSrc[i])
                return true;
        }
        return false;
    }

    public PointF getTopLeft()
	{
        return topLeft;
    }

    public PointF getTopRight()
	{
        return topRight;
    }

    public PointF getBottomLeft()
	{
        return bottomLeft;
    }

    public PointF getBottomRight() 
	{
        return bottomRight;
    }

    public PointF getTopLeftBack() 
	{
        return topLeftBack;
    }

    public PointF getTopRightBack() 
	{
        return topRightBack;
    }

    public PointF getBottomLeftBack() 
	{
        return bottomLeftBack;
    }

    public PointF getBottomRightBack()
	{
        return bottomRightBack;
    }

    PointF topLeft = new PointF(0, 0);
    PointF topRight = new PointF(0, 0);
    PointF bottomLeft = new PointF(0, 0);
    PointF bottomRight = new PointF(0, 0);


    PointF topLeftBack = new PointF(0, 0);
    PointF topRightBack = new PointF(0, 0);
    PointF bottomLeftBack = new PointF(0, 0);
    PointF bottomRightBack = new PointF(0, 0);


    private CustomShadow customShadow = new CustomShadow();

    public CustomShadow getCustomShadow()
	{
        return customShadow;
    }

    public void setCustomShadowElevation(float customShadowElevation)
	{
        this.customShadowElevation = customShadowElevation;
        ((View)getParent()).invalidate();
    }

    public float getCustomShadowElevation() 
	{
        return customShadowElevation;
    }

    float customShadowElevation;

    class CustomShadow 
	{
        public static final float DEFAULT_SHADOW_PADDING = 10f;
        PointF topLeftBack = new PointF(0, 0);
        PointF topRightBack = new PointF(0, 0);
        PointF bottomLeftBack = new PointF(0, 0);
        PointF bottomRightBack = new PointF(0, 0);
        int padding;

        public boolean calculateBounds(DepthFAB target) 
		{
            float[] src = new float[8];
            float density = getResources().getDisplayMetrics().density;
            float offsetY = customShadowElevation;
            float offsetX = customShadowElevation / 5;
            padding = (int) (customShadowElevation / 4f + DEFAULT_SHADOW_PADDING * density);

            float[] dst = new float[]{-padding, -padding, target.getWidth() + padding, -padding, -padding, target.getHeight() + padding, target.getWidth() + padding, target.getHeight() + padding};
            Matrix matrix = getMatrix();
            matrix.mapPoints(src, dst);

            topLeftBack.x = src[0] + target.getLeft() + offsetX;
            topLeftBack.y = src[1] + target.getTop() + offsetY;
            topRightBack.x = src[2] + target.getLeft() + offsetX;
            topRightBack.y = src[3] + target.getTop() + offsetY;

            bottomLeftBack.x = src[4] + target.getLeft() + offsetX;
            bottomLeftBack.y = src[5] + target.getTop() + offsetY;
            bottomRightBack.x = src[6] + target.getLeft() + offsetX;
            bottomRightBack.y = src[7] + target.getTop() + offsetY;

            return false;
        }

        Matrix matrix = new Matrix();

        public void drawShadow(Canvas canvas, DepthFAB dl, Drawable shadow) 
		{
            shadow.setBounds(-padding, -padding, dl.getWidth() + padding, dl.getHeight() + padding);
            float[] src = new float[]{0, 0, dl.getWidth(), 0, dl.getWidth(), dl.getHeight(), 0, dl.getHeight()};
            float[] dst = new float[]{topLeftBack.x, topLeftBack.y, topRightBack.x, topRightBack.y, bottomRightBack.x, bottomRightBack.y, bottomLeftBack.x, bottomLeftBack.y};
            int count = canvas.save();
            matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
            canvas.concat(matrix);
            shadow.draw(canvas);
            canvas.restoreToCount(count);
        }
    }
	
	public void setOffset(int offset)
	{
        if (offset != getTranslationY())
		{
            offset = Math.max(minOffset, offset);
            setTranslationY(offset);
        }
    }

    public void setMinOffset(int minOffset) 
	{
        this.minOffset = minOffset;
    }

    public boolean isChecked() 
	{
        return isChecked;
    }

    public void setChecked(boolean isChecked) 
	{
        if (this.isChecked != isChecked) 
		{
            this.isChecked = isChecked;
            refreshDrawableState();
        }
    }

    public void toggle() 
	{
        setChecked(!isChecked);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace)
	{
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) 
		{
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }
}

This remains in the realm of possible ? Can you help me please ?

MSay2 avatar Apr 28 '17 20:04 MSay2

Hey, could you post the StateListAnimator as well?

danielzeller avatar Nov 05 '18 12:11 danielzeller