/* * Copyright (C) 2009 Android Shuffle Open Source Project * * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 org.dodgybits.shuffle.android.list.view; import android.R; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ListView; public class SwipeListItemWrapper extends FrameLayout { private static final String cTag = "SwipeListItemWrapper"; private int mStartX; private int mStartY; private SwipeListItemListener mListener; private int mPosition; public SwipeListItemWrapper(Context context) { super(context); } public SwipeListItemWrapper(Context context, AttributeSet attrs) { super(context, attrs); } public SwipeListItemWrapper(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final int x = (int)ev.getX(); final int y = (int)ev.getY(); boolean stealEvent = false; switch (action) { case MotionEvent.ACTION_MOVE: Log.d(cTag, "move event"); if (isValidSwipe(x, y)) { stealEvent = true; } break; case MotionEvent.ACTION_DOWN: Log.d(cTag, "down event"); mStartX = x; mStartY = y; break; case MotionEvent.ACTION_CANCEL: Log.d(cTag, "cancel event"); mPosition = AdapterView.INVALID_POSITION; // some parent component has stolen the event // nothing to do break; case MotionEvent.ACTION_UP: Log.d(cTag, "up event"); break; } return stealEvent; } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { // we've got a valid swipe event. Notify the listener (if any) if (mPosition != AdapterView.INVALID_POSITION && mListener != null) { mListener.onListItemSwiped(mPosition); } } return true; } public void setSwipeListItemListener(SwipeListItemListener listener) { mListener = listener; } /** * Check if this appears to be a swipe event. * * Consider it a swipe if it traverses at least a third of the screen, * and is mostly horizontal. */ private boolean isValidSwipe(final int x, final int y) { final int screenWidth = getWidth(); final int xDiff = Math.abs(x - mStartX); final int yDiff = Math.abs(y - mStartY); boolean horizontalValid = xDiff >= (screenWidth / 3); boolean verticalValid = yDiff > 0 && (xDiff / yDiff) > 4; mPosition = AdapterView.INVALID_POSITION; if (horizontalValid && verticalValid) { ListView list = (ListView) findViewById(R.id.list); if (list != null) { // adjust for list not being at top of screen mPosition = list.pointToPosition(mStartX, mStartY - list.getTop()); } } Log.d(cTag, "isValidSwipe hValid=" + horizontalValid + " vValid=" + verticalValid + " position=" + mPosition); return horizontalValid && verticalValid; } }