com.woxthebox.draglistview.DragItem.java Source code

Java tutorial

Introduction

Here is the source code for com.woxthebox.draglistview.DragItem.java

Source

/**
 * Copyright 2014 Magnus Woxblom
 * <p/>
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.woxthebox.draglistview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.PropertyValuesHolder;

public class DragItem {
    protected static final int ANIMATION_DURATION = 250;
    private View mDragView;

    private float mOffsetX;
    private float mOffsetY;
    private float mPosX;
    private float mPosY;
    private float mPosTouchDx;
    private float mPosTouchDy;
    private float mAnimationDx;
    private float mAnimationDy;
    private boolean mCanDragHorizontally = true;
    private boolean mSnapToTouch = true;

    public DragItem(Context context) {
        mDragView = new View(context);
        hide();
    }

    public DragItem(Context context, int layoutId) {
        mDragView = View.inflate(context, layoutId, null);
        hide();
    }

    public void onBindDragView(View clickedView, View dragView) {
        Bitmap bitmap = Bitmap.createBitmap(clickedView.getWidth(), clickedView.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        clickedView.draw(canvas);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            dragView.setBackground(new BitmapDrawable(clickedView.getResources(), bitmap));
        } else {
            //noinspection deprecation
            dragView.setBackgroundDrawable(new BitmapDrawable(clickedView.getResources(), bitmap));
        }
    }

    public void onMeasureDragView(View clickedView, View dragView) {
        dragView.setLayoutParams(
                new FrameLayout.LayoutParams(clickedView.getMeasuredWidth(), clickedView.getMeasuredHeight()));
        int widthSpec = View.MeasureSpec.makeMeasureSpec(clickedView.getMeasuredWidth(), View.MeasureSpec.EXACTLY);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(clickedView.getMeasuredHeight(),
                View.MeasureSpec.EXACTLY);
        dragView.measure(widthSpec, heightSpec);
    }

    public void onStartDragAnimation(View dragView) {
    }

    public void onEndDragAnimation(View dragView) {
    }

    boolean canDragHorizontally() {
        return mCanDragHorizontally;
    }

    void setCanDragHorizontally(boolean canDragHorizontally) {
        mCanDragHorizontally = canDragHorizontally;
    }

    boolean isSnapToTouch() {
        return mSnapToTouch;
    }

    void setSnapToTouch(boolean snapToTouch) {
        mSnapToTouch = snapToTouch;
    }

    View getDragItemView() {
        return mDragView;
    }

    void show() {
        mDragView.setVisibility(View.VISIBLE);
    }

    void hide() {
        mDragView.setVisibility(View.GONE);
    }

    void startDrag(View startFromView, float touchX, float touchY) {
        show();
        onBindDragView(startFromView, mDragView);
        onMeasureDragView(startFromView, mDragView);
        onStartDragAnimation(mDragView);

        float startX = ViewCompat.getX(startFromView)
                - (mDragView.getMeasuredWidth() - startFromView.getMeasuredWidth()) / 2
                + mDragView.getMeasuredWidth() / 2;
        float startY = ViewCompat.getY(startFromView)
                - (mDragView.getMeasuredHeight() - startFromView.getMeasuredHeight()) / 2
                + mDragView.getMeasuredHeight() / 2;

        if (mSnapToTouch) {
            mPosTouchDx = 0;
            mPosTouchDy = 0;
            setPosition(touchX, touchY);
            setAnimationDx(startX - touchX);
            setAnimationDY(startY - touchY);

            PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("AnimationDx", mAnimationDx, 0);
            PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("AnimationDY", mAnimationDy, 0);
            ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY);
            anim.setInterpolator(new DecelerateInterpolator());
            anim.setDuration(ANIMATION_DURATION);
            anim.start();
        } else {
            mPosTouchDx = startX - touchX;
            mPosTouchDy = startY - touchY;
            setPosition(touchX, touchY);
        }
    }

    void endDrag(View endToView, AnimatorListenerAdapter listener) {
        onEndDragAnimation(mDragView);

        float endX = ViewCompat.getX(endToView) - (mDragView.getMeasuredWidth() - endToView.getMeasuredWidth()) / 2
                + mDragView.getMeasuredWidth() / 2;
        float endY = ViewCompat.getY(endToView)
                - (mDragView.getMeasuredHeight() - endToView.getMeasuredHeight()) / 2
                + mDragView.getMeasuredHeight() / 2;
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("X", mPosX, endX);
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("Y", mPosY, endY);
        ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY);
        anim.setInterpolator(new DecelerateInterpolator());
        anim.setDuration(ANIMATION_DURATION);
        anim.addListener(listener);
        anim.start();
    }

    void setAnimationDx(float x) {
        mAnimationDx = x;
        updatePosition();
    }

    void setAnimationDY(float y) {
        mAnimationDy = y;
        updatePosition();
    }

    @SuppressWarnings("unused")
    void setX(float x) {
        mPosX = x;
        updatePosition();
    }

    @SuppressWarnings("unused")
    void setY(float y) {
        mPosY = y;
        updatePosition();
    }

    float getX() {
        return mPosX;
    }

    float getY() {
        return mPosY;
    }

    void setPosition(float touchX, float touchY) {
        mPosX = touchX + mPosTouchDx;
        mPosY = touchY + mPosTouchDy;
        updatePosition();
    }

    void setOffset(float offsetX, float offsetY) {
        mOffsetX = offsetX;
        mOffsetY = offsetY;
        updatePosition();
    }

    void updatePosition() {
        if (mCanDragHorizontally) {
            ViewCompat.setX(mDragView, mPosX + mOffsetX + mAnimationDx - mDragView.getMeasuredWidth() / 2);
        }

        ViewCompat.setY(mDragView, mPosY + mOffsetY + mAnimationDy - mDragView.getMeasuredHeight() / 2);
        mDragView.invalidate();
    }
}