// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.geocities.com/kpdus/jad.html // Decompiler options: braces fieldsfirst space lnc package com.jmedeisis.draglinearlayout; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; import android.support.v4.view.MotionEventCompat; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewTreeObserver; import android.widget.LinearLayout; import android.widget.ScrollView; public class DragLinearLayout extends LinearLayout { private class DragHandleOnTouchListener implements android.view.View.OnTouchListener { final DragLinearLayout this$0; private final View view; public boolean onTouch(View view1, MotionEvent motionevent) { if (MotionEventCompat.getActionMasked(motionevent) == 0) { startDetectingDrag(view); } return false; } public DragHandleOnTouchListener(View view1) { this$0 = DragLinearLayout.this; super(); view = view1; } } private class DragItem { private boolean detecting; private boolean dragging; private int height; private int position; private ValueAnimator settleAnimation; private int startTop; private int startVisibility; private int targetTopOffset; final DragLinearLayout this$0; private int totalDragOffset; private View view; private BitmapDrawable viewDrawable; public void onDragStart() { view.setVisibility(4); dragging = true; } public void onDragStop() { dragging = false; } public void setTotalOffset(int i) { totalDragOffset = i; updateTargetTop(); } public boolean settling() { return settleAnimation != null; } public void startDetectingOnPossibleDrag(View view1, int i) { view = view1; startVisibility = view1.getVisibility(); viewDrawable = getDragDrawable(view1); position = i; startTop = view1.getTop(); height = view1.getHeight(); totalDragOffset = 0; targetTopOffset = 0; settleAnimation = null; detecting = true; } public void stopDetecting() { detecting = false; if (view != null) { view.setVisibility(startVisibility); } view = null; startVisibility = -1; viewDrawable = null; position = -1; startTop = -1; height = -1; totalDragOffset = 0; targetTopOffset = 0; if (settleAnimation != null) { settleAnimation.end(); } settleAnimation = null; } public void updateTargetTop() { targetTopOffset = (startTop - view.getTop()) + totalDragOffset; } /* static int access$1002(DragItem dragitem, int i) { dragitem.position = i; return i; } */ /* static ValueAnimator access$302(DragItem dragitem, ValueAnimator valueanimator) { dragitem.settleAnimation = valueanimator; return valueanimator; } */ public DragItem() { this$0 = DragLinearLayout.this; super(); stopDetecting(); } } private class DraggableChild { private ValueAnimator swapAnimation; final DragLinearLayout this$0; public void cancelExistingAnimation() { if (swapAnimation != null) { swapAnimation.cancel(); } } public void endExistingAnimation() { if (swapAnimation != null) { swapAnimation.end(); } } /* static ValueAnimator access$1502(DraggableChild draggablechild, ValueAnimator valueanimator) { draggablechild.swapAnimation = valueanimator; return valueanimator; } */ private DraggableChild() { this$0 = DragLinearLayout.this; super(); } } public static interface OnViewSwapListener { public abstract void onSwap(View view, int i, View view1, int j); } private static final int DEFAULT_SCROLL_SENSITIVE_AREA_HEIGHT_DP = 48; private static final int INVALID_POINTER_ID = -1; private static final String LOG_TAG = com/jmedeisis/draglinearlayout/DragLinearLayout.getSimpleName(); private static final int MAX_DRAG_SCROLL_SPEED = 16; private static final long MAX_SWITCH_DURATION = 300L; private static final long MIN_SWITCH_DURATION = 150L; private static final float NOMINAL_DISTANCE = 20F; private static final long NOMINAL_SWITCH_DURATION = 150L; private int activePointerId; private ScrollView containerScrollView; private int downY; private final Drawable dragBottomShadowDrawable; private final int dragShadowHeight; private final Drawable dragTopShadowDrawable; private Runnable dragUpdater; private final SparseArray draggableChildren; private final DragItem draggedItem; private final float nominalDistanceScaled; private int scrollSensitiveAreaHeight; private final int slop; private OnViewSwapListener swapListener; public DragLinearLayout(Context context) { this(context, null); } public DragLinearLayout(Context context, AttributeSet attributeset) { Resources resources; super(context, attributeset); downY = -1; activePointerId = -1; setOrientation(1); draggableChildren = new SparseArray(); draggedItem = new DragItem(); slop = ViewConfiguration.get(context).getScaledTouchSlop(); resources = getResources(); dragTopShadowDrawable = ContextCompat.getDrawable(context, R.drawable.ab_solid_shadow_holo_flipped); dragBottomShadowDrawable = ContextCompat.getDrawable(context, R.drawable.ab_solid_shadow_holo); dragShadowHeight = resources.getDimensionPixelSize(R.dimen.downwards_drop_shadow_height); context = context.getTheme().obtainStyledAttributes(attributeset, R.styleable.DragLinearLayout, 0, 0); scrollSensitiveAreaHeight = context.getDimensionPixelSize(R.styleable.DragLinearLayout_scrollSensitiveHeight, (int)(48F * resources.getDisplayMetrics().density + 0.5F)); context.recycle(); nominalDistanceScaled = (int)(20F * resources.getDisplayMetrics().density + 0.5F); return; attributeset; context.recycle(); throw attributeset; } private static Bitmap getBitmapFromView(View view) { Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), android.graphics.Bitmap.Config.ARGB_8888); view.draw(new Canvas(bitmap)); return bitmap; } private BitmapDrawable getDragDrawable(View view) { int i = view.getTop(); int j = view.getLeft(); Object obj = getBitmapFromView(view); obj = new BitmapDrawable(getResources(), ((Bitmap) (obj))); ((BitmapDrawable) (obj)).setBounds(new Rect(j, i, view.getWidth() + j, view.getHeight() + i)); return ((BitmapDrawable) (obj)); } private long getTranslateAnimationDuration(float f) { return Math.min(300L, Math.max(150L, (long)((150F * Math.abs(f)) / nominalDistanceScaled))); } private void handleContainerScroll(final int delta) { if (containerScrollView != null) { final int startScrollY = containerScrollView.getScrollY(); delta = (getTop() - startScrollY) + delta; int i = containerScrollView.getHeight(); if (delta < scrollSensitiveAreaHeight) { delta = (int)(-16F * smootherStep(scrollSensitiveAreaHeight, 0.0F, delta)); } else if (delta > i - scrollSensitiveAreaHeight) { delta = (int)(16F * smootherStep(i - scrollSensitiveAreaHeight, i, delta)); } else { delta = 0; } containerScrollView.removeCallbacks(dragUpdater); containerScrollView.smoothScrollBy(0, delta); dragUpdater = new Runnable() { final DragLinearLayout this$0; final int val$delta; final int val$startScrollY; public void run() { if (draggedItem.dragging && startScrollY != containerScrollView.getScrollY()) { onDrag(draggedItem.totalDragOffset + delta); } } { this$0 = DragLinearLayout.this; startScrollY = i; delta = j; super(); } }; containerScrollView.post(dragUpdater); } } private int nextDraggablePosition(int i) { i = draggableChildren.indexOfKey(i); if (i < -1 || i > draggableChildren.size() - 2) { return -1; } else { return draggableChildren.keyAt(i + 1); } } private void onDrag(int i) { draggedItem.setTotalOffset(i); invalidate(); int j = draggedItem.startTop + draggedItem.totalDragOffset; handleContainerScroll(j); int k = nextDraggablePosition(draggedItem.position); int l = previousDraggablePosition(draggedItem.position); final ViewTreeObserver switchViewObserver = getChildAt(k); View view = getChildAt(l); if (switchViewObserver != null && draggedItem.height + j > switchViewObserver.getTop() + switchViewObserver.getHeight() / 2) { i = 1; } else { i = 0; } if (view != null && j < view.getTop() + view.getHeight() / 2) { j = 1; } else { j = 0; } if (i != 0 || j != 0) { final float switchViewStartY; final Object switchView; final int originalPosition; if (i != 0) { switchView = switchViewObserver; } else { switchView = view; } originalPosition = draggedItem.position; if (i != 0) { j = k; } else { j = l; } ((DraggableChild)draggableChildren.get(j)).cancelExistingAnimation(); switchViewStartY = ((View) (switchView)).getY(); if (swapListener != null) { swapListener.onSwap(draggedItem.view, draggedItem.position, ((View) (switchView)), j); } if (i != 0) { removeViewAt(originalPosition); removeViewAt(j - 1); addView(switchViewObserver, originalPosition); addView(draggedItem.view, j); } else { removeViewAt(j); removeViewAt(originalPosition - 1); addView(draggedItem.view, j); addView(view, originalPosition); } draggedItem.position = j; switchViewObserver = ((View) (switchView)).getViewTreeObserver(); switchViewObserver.addOnPreDrawListener(new android.view.ViewTreeObserver.OnPreDrawListener() { final DragLinearLayout this$0; final int val$originalPosition; final View val$switchView; final ViewTreeObserver val$switchViewObserver; final float val$switchViewStartY; public boolean onPreDraw() { switchViewObserver.removeOnPreDrawListener(this); ObjectAnimator objectanimator = ObjectAnimator.ofFloat(switchView, "y", new float[] { switchViewStartY, (float)switchView.getTop() }).setDuration(getTranslateAnimationDuration((float)switchView.getTop() - switchViewStartY)); objectanimator.addListener(objectanimator. new AnimatorListenerAdapter() { final _cls3 this$1; final ObjectAnimator val$switchAnimator; public void onAnimationEnd(Animator animator) { ((DraggableChild)draggableChildren.get(originalPosition)).swapAnimation = null; } public void onAnimationStart(Animator animator) { ((DraggableChild)draggableChildren.get(originalPosition)).swapAnimation = switchAnimator; } { this$1 = final__pcls3; switchAnimator = ObjectAnimator.this; super(); } }); objectanimator.start(); return true; } { this$0 = DragLinearLayout.this; switchViewObserver = viewtreeobserver; switchView = view; switchViewStartY = f; originalPosition = i; super(); } }); switchView = draggedItem.view.getViewTreeObserver(); ((ViewTreeObserver) (switchView)).addOnPreDrawListener(new android.view.ViewTreeObserver.OnPreDrawListener() { final DragLinearLayout this$0; final ViewTreeObserver val$observer; public boolean onPreDraw() { observer.removeOnPreDrawListener(this); draggedItem.updateTargetTop(); if (draggedItem.settling()) { Log.d(DragLinearLayout.LOG_TAG, "Updating settle animation"); draggedItem.settleAnimation.removeAllListeners(); draggedItem.settleAnimation.cancel(); onDragStop(); } return true; } { this$0 = DragLinearLayout.this; observer = viewtreeobserver; super(); } }); } } private void onDragStop() { draggedItem.settleAnimation = ValueAnimator.ofFloat(new float[] { (float)draggedItem.totalDragOffset, (float)(draggedItem.totalDragOffset - draggedItem.targetTopOffset) }).setDuration(getTranslateAnimationDuration(draggedItem.targetTopOffset)); draggedItem.settleAnimation.addUpdateListener(new android.animation.ValueAnimator.AnimatorUpdateListener() { final DragLinearLayout this$0; public void onAnimationUpdate(ValueAnimator valueanimator) { if (!draggedItem.detecting) { return; } draggedItem.setTotalOffset(((Float)valueanimator.getAnimatedValue()).intValue()); int i = (int)((1.0F - valueanimator.getAnimatedFraction()) * 255F); if (dragTopShadowDrawable != null) { dragTopShadowDrawable.setAlpha(i); } dragBottomShadowDrawable.setAlpha(i); invalidate(); } { this$0 = DragLinearLayout.this; super(); } }); draggedItem.settleAnimation.addListener(new AnimatorListenerAdapter() { final DragLinearLayout this$0; public void onAnimationEnd(Animator animator) { if (!draggedItem.detecting) { return; } draggedItem.settleAnimation = null; draggedItem.stopDetecting(); if (dragTopShadowDrawable != null) { dragTopShadowDrawable.setAlpha(255); } dragBottomShadowDrawable.setAlpha(255); } public void onAnimationStart(Animator animator) { draggedItem.onDragStop(); } { this$0 = DragLinearLayout.this; super(); } }); draggedItem.settleAnimation.start(); } private void onTouchEnd() { downY = -1; activePointerId = -1; } private int previousDraggablePosition(int i) { i = draggableChildren.indexOfKey(i); if (i < 1 || i > draggableChildren.size()) { return -1; } else { return draggableChildren.keyAt(i - 1); } } private static float smootherStep(float f, float f1, float f2) { f = Math.max(0.0F, Math.min((f2 - f) / (f1 - f), 1.0F)); return f * f * f * ((6F * f - 15F) * f + 10F); } private void startDetectingDrag(View view) { if (draggedItem.detecting) { return; } else { int i = indexOfChild(view); ((DraggableChild)draggableChildren.get(i)).endExistingAnimation(); draggedItem.startDetectingOnPossibleDrag(view, i); return; } } private void startDrag() { draggedItem.onDragStart(); requestDisallowInterceptTouchEvent(true); } public void addDragView(View view, View view1) { addView(view); setViewDraggable(view, view1); } public void addDragView(View view, View view1, int i) { addView(view, i); for (int j = draggableChildren.size() - 1; j >= 0; j--) { int k = draggableChildren.keyAt(j); if (k >= i) { draggableChildren.put(k + 1, draggableChildren.get(k)); } } setViewDraggable(view, view1); } protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (draggedItem.detecting && (draggedItem.dragging || draggedItem.settling())) { canvas.save(); canvas.translate(0.0F, draggedItem.totalDragOffset); draggedItem.viewDrawable.draw(canvas); int i = draggedItem.viewDrawable.getBounds().left; int j = draggedItem.viewDrawable.getBounds().right; int k = draggedItem.viewDrawable.getBounds().top; int l = draggedItem.viewDrawable.getBounds().bottom; dragBottomShadowDrawable.setBounds(i, l, j, dragShadowHeight + l); dragBottomShadowDrawable.draw(canvas); if (dragTopShadowDrawable != null) { dragTopShadowDrawable.setBounds(i, k - dragShadowHeight, j, k); dragTopShadowDrawable.draw(canvas); } canvas.restore(); } } public int getScrollSensitiveHeight() { return scrollSensitiveAreaHeight; } public boolean onInterceptTouchEvent(MotionEvent motionevent) { MotionEventCompat.getActionMasked(motionevent); JVM INSTR tableswitch 0 6: default 48 // 0 50 // 1 150 // 2 81 // 3 150 // 4 48 // 5 48 // 6 135; goto _L1 _L2 _L3 _L4 _L3 _L1 _L1 _L5 _L1: return false; _L2: if (!draggedItem.detecting) { downY = (int)MotionEventCompat.getY(motionevent, 0); activePointerId = MotionEventCompat.getPointerId(motionevent, 0); return false; } continue; /* Loop/switch isn't completed */ _L4: if (draggedItem.detecting && -1 != activePointerId && Math.abs(MotionEventCompat.getY(motionevent, motionevent.findPointerIndex(activePointerId)) - (float)downY) > (float)slop) { startDrag(); return true; } continue; /* Loop/switch isn't completed */ _L5: if (MotionEventCompat.getPointerId(motionevent, MotionEventCompat.getActionIndex(motionevent)) != activePointerId) { continue; /* Loop/switch isn't completed */ } _L3: onTouchEnd(); if (draggedItem.detecting) { draggedItem.stopDetecting(); return false; } if (true) goto _L1; else goto _L6 _L6: } public boolean onTouchEvent(MotionEvent motionevent) { boolean flag = true; MotionEventCompat.getActionMasked(motionevent); JVM INSTR tableswitch 0 6: default 48 // 0 52 // 1 137 // 2 80 // 3 137 // 4 48 // 5 48 // 6 122; goto _L1 _L2 _L3 _L4 _L3 _L1 _L1 _L5 _L1: flag = false; _L7: return flag; _L2: if (!draggedItem.detecting || draggedItem.settling()) { return false; } else { startDrag(); return true; } _L4: if (!draggedItem.dragging || -1 == activePointerId) goto _L1; else goto _L6 _L6: onDrag((int)MotionEventCompat.getY(motionevent, motionevent.findPointerIndex(activePointerId)) - downY); return true; _L5: if (MotionEventCompat.getPointerId(motionevent, MotionEventCompat.getActionIndex(motionevent)) != activePointerId) goto _L1; else goto _L3 _L3: onTouchEnd(); if (draggedItem.dragging) { onDragStop(); return true; } if (draggedItem.detecting) { draggedItem.stopDetecting(); return true; } goto _L7 } public void removeDragView(View view) { if (this == view.getParent()) { int j = indexOfChild(view); removeView(view); int k = draggableChildren.size(); int i = 0; while (i < k) { int l = draggableChildren.keyAt(i); if (l >= j) { view = (DraggableChild)draggableChildren.get(l + 1); if (view == null) { draggableChildren.delete(l); } else { draggableChildren.put(l, view); } } i++; } } } public void setContainerScrollView(ScrollView scrollview) { containerScrollView = scrollview; } public void setOnViewSwapListener(OnViewSwapListener onviewswaplistener) { swapListener = onviewswaplistener; } public void setOrientation(int i) { if (i == 0) { throw new IllegalArgumentException("DragLinearLayout must be VERTICAL."); } else { super.setOrientation(i); return; } } public void setScrollSensitiveHeight(int i) { scrollSensitiveAreaHeight = i; } public void setViewDraggable(View view, View view1) { if (this == view.getParent()) { view1.setOnTouchListener(new DragHandleOnTouchListener(view)); draggableChildren.put(indexOfChild(view), new DraggableChild()); return; } else { Log.e(LOG_TAG, (new StringBuilder()).append(view).append(" is not a child, cannot make draggable.").toString()); return; } } }