1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.elevationdrag; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import android.content.Context; 20*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.widget.ViewDragHelper; 21*90c8c64dSAndroid Build Coastguard Worker import android.util.AttributeSet; 22*90c8c64dSAndroid Build Coastguard Worker import android.view.MotionEvent; 23*90c8c64dSAndroid Build Coastguard Worker import android.view.View; 24*90c8c64dSAndroid Build Coastguard Worker import android.widget.FrameLayout; 25*90c8c64dSAndroid Build Coastguard Worker 26*90c8c64dSAndroid Build Coastguard Worker import java.util.ArrayList; 27*90c8c64dSAndroid Build Coastguard Worker import java.util.List; 28*90c8c64dSAndroid Build Coastguard Worker 29*90c8c64dSAndroid Build Coastguard Worker /** 30*90c8c64dSAndroid Build Coastguard Worker * A {@link FrameLayout} that allows the user to drag and reposition child views. 31*90c8c64dSAndroid Build Coastguard Worker */ 32*90c8c64dSAndroid Build Coastguard Worker public class DragFrameLayout extends FrameLayout { 33*90c8c64dSAndroid Build Coastguard Worker 34*90c8c64dSAndroid Build Coastguard Worker /** 35*90c8c64dSAndroid Build Coastguard Worker * The list of {@link View}s that will be draggable. 36*90c8c64dSAndroid Build Coastguard Worker */ 37*90c8c64dSAndroid Build Coastguard Worker private List<View> mDragViews; 38*90c8c64dSAndroid Build Coastguard Worker 39*90c8c64dSAndroid Build Coastguard Worker /** 40*90c8c64dSAndroid Build Coastguard Worker * The {@link DragFrameLayoutController} that will be notify on drag. 41*90c8c64dSAndroid Build Coastguard Worker */ 42*90c8c64dSAndroid Build Coastguard Worker private DragFrameLayoutController mDragFrameLayoutController; 43*90c8c64dSAndroid Build Coastguard Worker 44*90c8c64dSAndroid Build Coastguard Worker private ViewDragHelper mDragHelper; 45*90c8c64dSAndroid Build Coastguard Worker DragFrameLayout(Context context)46*90c8c64dSAndroid Build Coastguard Worker public DragFrameLayout(Context context) { 47*90c8c64dSAndroid Build Coastguard Worker this(context, null, 0, 0); 48*90c8c64dSAndroid Build Coastguard Worker } 49*90c8c64dSAndroid Build Coastguard Worker DragFrameLayout(Context context, AttributeSet attrs)50*90c8c64dSAndroid Build Coastguard Worker public DragFrameLayout(Context context, AttributeSet attrs) { 51*90c8c64dSAndroid Build Coastguard Worker this(context, attrs, 0, 0); 52*90c8c64dSAndroid Build Coastguard Worker } 53*90c8c64dSAndroid Build Coastguard Worker DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr)54*90c8c64dSAndroid Build Coastguard Worker public DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 55*90c8c64dSAndroid Build Coastguard Worker this(context, attrs, defStyleAttr, 0); 56*90c8c64dSAndroid Build Coastguard Worker } 57*90c8c64dSAndroid Build Coastguard Worker DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)58*90c8c64dSAndroid Build Coastguard Worker public DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 59*90c8c64dSAndroid Build Coastguard Worker super(context, attrs, defStyleAttr, defStyleRes); 60*90c8c64dSAndroid Build Coastguard Worker mDragViews = new ArrayList<View>(); 61*90c8c64dSAndroid Build Coastguard Worker 62*90c8c64dSAndroid Build Coastguard Worker /** 63*90c8c64dSAndroid Build Coastguard Worker * Create the {@link ViewDragHelper} and set its callback. 64*90c8c64dSAndroid Build Coastguard Worker */ 65*90c8c64dSAndroid Build Coastguard Worker mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() { 66*90c8c64dSAndroid Build Coastguard Worker @Override 67*90c8c64dSAndroid Build Coastguard Worker public boolean tryCaptureView(View child, int pointerId) { 68*90c8c64dSAndroid Build Coastguard Worker return mDragViews.contains(child); 69*90c8c64dSAndroid Build Coastguard Worker } 70*90c8c64dSAndroid Build Coastguard Worker 71*90c8c64dSAndroid Build Coastguard Worker @Override 72*90c8c64dSAndroid Build Coastguard Worker public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 73*90c8c64dSAndroid Build Coastguard Worker super.onViewPositionChanged(changedView, left, top, dx, dy); 74*90c8c64dSAndroid Build Coastguard Worker } 75*90c8c64dSAndroid Build Coastguard Worker 76*90c8c64dSAndroid Build Coastguard Worker @Override 77*90c8c64dSAndroid Build Coastguard Worker public int clampViewPositionHorizontal(View child, int left, int dx) { 78*90c8c64dSAndroid Build Coastguard Worker return left; 79*90c8c64dSAndroid Build Coastguard Worker } 80*90c8c64dSAndroid Build Coastguard Worker 81*90c8c64dSAndroid Build Coastguard Worker @Override 82*90c8c64dSAndroid Build Coastguard Worker public int clampViewPositionVertical(View child, int top, int dy) { 83*90c8c64dSAndroid Build Coastguard Worker return top; 84*90c8c64dSAndroid Build Coastguard Worker } 85*90c8c64dSAndroid Build Coastguard Worker 86*90c8c64dSAndroid Build Coastguard Worker @Override 87*90c8c64dSAndroid Build Coastguard Worker public void onViewCaptured(View capturedChild, int activePointerId) { 88*90c8c64dSAndroid Build Coastguard Worker super.onViewCaptured(capturedChild, activePointerId); 89*90c8c64dSAndroid Build Coastguard Worker if (mDragFrameLayoutController != null) { 90*90c8c64dSAndroid Build Coastguard Worker mDragFrameLayoutController.onDragDrop(true); 91*90c8c64dSAndroid Build Coastguard Worker } 92*90c8c64dSAndroid Build Coastguard Worker } 93*90c8c64dSAndroid Build Coastguard Worker 94*90c8c64dSAndroid Build Coastguard Worker @Override 95*90c8c64dSAndroid Build Coastguard Worker public void onViewReleased(View releasedChild, float xvel, float yvel) { 96*90c8c64dSAndroid Build Coastguard Worker super.onViewReleased(releasedChild, xvel, yvel); 97*90c8c64dSAndroid Build Coastguard Worker if (mDragFrameLayoutController != null) { 98*90c8c64dSAndroid Build Coastguard Worker mDragFrameLayoutController.onDragDrop(false); 99*90c8c64dSAndroid Build Coastguard Worker } 100*90c8c64dSAndroid Build Coastguard Worker } 101*90c8c64dSAndroid Build Coastguard Worker }); 102*90c8c64dSAndroid Build Coastguard Worker } 103*90c8c64dSAndroid Build Coastguard Worker 104*90c8c64dSAndroid Build Coastguard Worker @Override onInterceptTouchEvent(MotionEvent ev)105*90c8c64dSAndroid Build Coastguard Worker public boolean onInterceptTouchEvent(MotionEvent ev) { 106*90c8c64dSAndroid Build Coastguard Worker final int action = ev.getActionMasked(); 107*90c8c64dSAndroid Build Coastguard Worker if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { 108*90c8c64dSAndroid Build Coastguard Worker mDragHelper.cancel(); 109*90c8c64dSAndroid Build Coastguard Worker return false; 110*90c8c64dSAndroid Build Coastguard Worker } 111*90c8c64dSAndroid Build Coastguard Worker return mDragHelper.shouldInterceptTouchEvent(ev); 112*90c8c64dSAndroid Build Coastguard Worker } 113*90c8c64dSAndroid Build Coastguard Worker 114*90c8c64dSAndroid Build Coastguard Worker @Override onTouchEvent(MotionEvent ev)115*90c8c64dSAndroid Build Coastguard Worker public boolean onTouchEvent(MotionEvent ev) { 116*90c8c64dSAndroid Build Coastguard Worker mDragHelper.processTouchEvent(ev); 117*90c8c64dSAndroid Build Coastguard Worker return true; 118*90c8c64dSAndroid Build Coastguard Worker } 119*90c8c64dSAndroid Build Coastguard Worker 120*90c8c64dSAndroid Build Coastguard Worker /** 121*90c8c64dSAndroid Build Coastguard Worker * Adds a new {@link View} to the list of views that are draggable within the container. 122*90c8c64dSAndroid Build Coastguard Worker * @param dragView the {@link View} to make draggable 123*90c8c64dSAndroid Build Coastguard Worker */ addDragView(View dragView)124*90c8c64dSAndroid Build Coastguard Worker public void addDragView(View dragView) { 125*90c8c64dSAndroid Build Coastguard Worker mDragViews.add(dragView); 126*90c8c64dSAndroid Build Coastguard Worker } 127*90c8c64dSAndroid Build Coastguard Worker 128*90c8c64dSAndroid Build Coastguard Worker /** 129*90c8c64dSAndroid Build Coastguard Worker * Sets the {@link DragFrameLayoutController} that will receive the drag events. 130*90c8c64dSAndroid Build Coastguard Worker * @param dragFrameLayoutController a {@link DragFrameLayoutController} 131*90c8c64dSAndroid Build Coastguard Worker */ setDragFrameController(DragFrameLayoutController dragFrameLayoutController)132*90c8c64dSAndroid Build Coastguard Worker public void setDragFrameController(DragFrameLayoutController dragFrameLayoutController) { 133*90c8c64dSAndroid Build Coastguard Worker mDragFrameLayoutController = dragFrameLayoutController; 134*90c8c64dSAndroid Build Coastguard Worker } 135*90c8c64dSAndroid Build Coastguard Worker 136*90c8c64dSAndroid Build Coastguard Worker /** 137*90c8c64dSAndroid Build Coastguard Worker * A controller that will receive the drag events. 138*90c8c64dSAndroid Build Coastguard Worker */ 139*90c8c64dSAndroid Build Coastguard Worker public interface DragFrameLayoutController { 140*90c8c64dSAndroid Build Coastguard Worker onDragDrop(boolean captured)141*90c8c64dSAndroid Build Coastguard Worker public void onDragDrop(boolean captured); 142*90c8c64dSAndroid Build Coastguard Worker } 143*90c8c64dSAndroid Build Coastguard Worker } 144