/** * Method that returns the target view for the current resize frame * * @return The target view */ View findTargetFromResizeFrame() { int count = getChildCount(); for (int i = 0; i < count; i++) { View v = getChildAt(i); if (v.getX() < (mResizeFrame.getX() + (mResizeFrame.getWidth() / 2)) && (v.getX() + v.getWidth()) > (mResizeFrame.getX() + (mResizeFrame.getWidth() / 2)) && v.getY() < (mResizeFrame.getY() + (mResizeFrame.getHeight() / 2)) && (v.getY() + v.getHeight()) > (mResizeFrame.getY() + (mResizeFrame.getHeight() / 2))) { return v; } } return null; }
@Override public void onStartResize(int mode) { if (mResizeFrame == null) return; mOldResizeFrameLocation = new Rect( mResizeFrame.getLeft(), mResizeFrame.getTop(), mResizeFrame.getRight(), mResizeFrame.getBottom()); }
@Override public void onResize(int mode, int delta) { if (mTarget == null) return; if (mResizeFrame == null) return; int w = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight()); int h = getMeasuredHeight() - (getPaddingTop() + getPaddingBottom()); int minWidth = (w / mCols) + (w / mCols) / 2; int minHeight = (h / mRows) + (h / mRows) / 2; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mResizeFrame.getLayoutParams(); switch (mode) { case Gravity.LEFT: float newpos = mResizeFrame.getX() + delta; if ((delta < 0 && newpos < (getPaddingLeft() * -1)) || (delta > 0 && newpos > (mResizeFrame.getX() + params.width - minWidth))) { return; } mResizeFrame.setX(newpos); params.width -= delta; break; case Gravity.RIGHT: if ((delta < 0 && ((params.width + delta) < minWidth)) || (delta > 0 && (mResizeFrame.getX() + delta + params.width) > (getPaddingLeft() + getMeasuredWidth()))) { return; } params.width += delta; break; case Gravity.TOP: newpos = mResizeFrame.getY() + delta; if ((delta < 0 && newpos < (getPaddingTop() * -1)) || (delta > 0 && newpos > (mResizeFrame.getY() + params.height - minHeight))) { return; } mResizeFrame.setY(newpos); params.height -= delta; break; case Gravity.BOTTOM: if ((delta < 0 && ((params.height + delta) < minHeight)) || (delta > 0 && (mResizeFrame.getY() + delta + params.height) > (getPaddingTop() + getMeasuredHeight()))) { return; } params.height += delta; break; default: break; } mResizeFrame.setLayoutParams(params); }
/** * Method that converts the resize frame to a dispostion reference * * @return Disposition The disposition reference */ private Disposition resizerToDisposition() { int w = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight()); int h = getMeasuredHeight() - (getPaddingTop() + getPaddingBottom()); int cw = w / mCols; int ch = h / mRows; // Remove overlapped areas Disposition resizer = new Disposition(); resizer.x = Math.round(mResizeFrame.getX() / cw); resizer.y = Math.round(mResizeFrame.getY() / ch); resizer.w = Math.round(mResizeFrame.getWidth() / cw); resizer.h = Math.round(mResizeFrame.getHeight() / ch); // Fix disposition (limits) resizer.x = Math.max(resizer.x, 0); resizer.y = Math.max(resizer.y, 0); resizer.w = Math.min(resizer.w, mCols - resizer.x); resizer.h = Math.min(resizer.h, mRows - resizer.y); return resizer; }
/** * Method that sets the disposition to draw on this view * * @param dispositions The dispositions to draw * @param cols The number of columns * @param rows The number of rows * @param animate If should animate the view */ public void setDispositions(List<Disposition> dispositions, int cols, int rows, boolean animate) { mDispositions = dispositions; mCols = cols; mRows = rows; // Remove all the current views and add the new ones recreateDispositions(animate); if (mResizeFrame != null) { mResizeFrame.setVisibility(View.GONE); } mChanged = false; }
/** * Method that select a view as the target of to resize * * @param v The target view */ boolean selectTarget(View v) { // Do not do long click if we do not have a target if (mTarget != null && v.equals(mTarget)) return false; if (mResizeFrame == null) return false; // Show the resize frame view just in place of the current clicked view mResizeFrame.hide(); FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) mResizeFrame.getLayoutParams(); int padding = mInternalPadding + mResizeFrame.getNeededPadding(); frameParams.width = v.getWidth() + (padding * 2); frameParams.height = v.getHeight() + (padding * 2); mResizeFrame.setX(v.getX() - padding); mResizeFrame.setY(v.getY() - padding); mResizeFrame.show(); // Save the new view mTarget = v; if (mOnFrameSelectedListener != null) { mOnFrameSelectedListener.onFrameSelectedListener(v); } return true; }
/** Method that request the deletion of the current selected frame */ @SuppressWarnings("boxing") public void deleteCurrentFrame() { if (mTarget == null) return; if (mResizeFrame == null) return; final Disposition targetDisposition = resizerToDisposition(); // Get valid dispositions to move final List<Disposition> adjacents = findAdjacentsDispositions(targetDisposition); if (adjacents == null) { // Nothing to do Toast.makeText( getContext(), R.string.pref_disposition_unable_delete_advise, Toast.LENGTH_SHORT) .show(); return; } // Hide resizer mResizeFrame.setVisibility(View.GONE); // Animate adjacents views List<Animator> animators = new ArrayList<Animator>(); animators.add(ObjectAnimator.ofFloat(mTarget, "scaleX", 1.0f, 0.0f)); animators.add(ObjectAnimator.ofFloat(mTarget, "scaleY", 1.0f, 0.0f)); Disposition first = null; for (Disposition adjacent : adjacents) { // Extract the view and remove from dispositions View v = findViewFromRect(getLocationFromDisposition(adjacent)); mDispositions.remove(adjacent); // Clone first disposition if (first == null) { first = new Disposition(); first.x = adjacent.x; first.y = adjacent.y; first.w = adjacent.w; first.h = adjacent.h; } // Add animators and fix the adjacent if (v != null) { if (first.x < targetDisposition.x) { // From Left to Right int width = mTarget.getWidth() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.WidthEvaluator(v), v.getWidth(), v.getWidth() + width)); // Update the adjacent adjacent.w += targetDisposition.w; mDispositions.add(adjacent); } else if (first.x > targetDisposition.x) { // From Right to Left int width = mTarget.getWidth() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.WidthEvaluator(v), v.getWidth(), v.getWidth() + width)); animators.add(ObjectAnimator.ofFloat(v, "x", v.getX(), mTarget.getX())); // Update the adjacent adjacent.x = targetDisposition.x; adjacent.w += targetDisposition.w; mDispositions.add(adjacent); } else if (first.y < targetDisposition.y) { // From Top to Bottom int height = mTarget.getHeight() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.HeightEvaluator(v), v.getHeight(), v.getHeight() + height)); // Update the adjacent adjacent.h += targetDisposition.h; mDispositions.add(adjacent); } else if (first.y > targetDisposition.y) { // From Bottom to Top int height = mTarget.getHeight() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.HeightEvaluator(v), v.getHeight(), v.getHeight() + height)); animators.add(ObjectAnimator.ofFloat(v, "y", v.getY(), mTarget.getY())); // Update the adjacent adjacent.y = targetDisposition.y; adjacent.h += targetDisposition.h; mDispositions.add(adjacent); } } } if (animators.size() > 0) { AnimatorSet animSet = new AnimatorSet(); animSet.playTogether(animators); animSet.setDuration(getResources().getInteger(R.integer.disposition_hide_anim)); animSet.setInterpolator(new AccelerateInterpolator()); animSet.addListener( new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // Ignore } @Override public void onAnimationRepeat(Animator animation) { // Ignore } @Override public void onAnimationEnd(Animator animation) { finishDeleteAnimation(targetDisposition); } @Override public void onAnimationCancel(Animator animation) { finishDeleteAnimation(targetDisposition); } }); animSet.start(); } }
/** * Method that sets the resize frame view * * @param resizeFrame The resize frame view */ public void setResizeFrame(ResizeFrame resizeFrame) { mResizeFrame = resizeFrame; mResizeFrame.setOnResizeListener(this); }