Home | History | Annotate | Download | only in swipeablelistview
      1 /*
      2  * Copyright (C) 2012 Google Inc.
      3  * Licensed to The Android Open Source Project.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.deskclock.widget.swipeablelistview;
     19 
     20 import android.content.Context;
     21 import android.content.res.Configuration;
     22 import android.graphics.Rect;
     23 import android.util.AttributeSet;
     24 import android.view.MotionEvent;
     25 import android.view.View;
     26 import android.view.ViewConfiguration;
     27 import android.widget.ListView;
     28 
     29 import com.android.deskclock.widget.swipeablelistview.SwipeHelper.Callback;
     30 
     31 /**
     32  * Copy of packages/apps/UnifiedEmail - com.android.mail.ui.Swipeable with changes.
     33  */
     34 public class SwipeableListView extends ListView implements Callback {
     35     private SwipeHelper mSwipeHelper;
     36     private boolean mEnableSwipe = false;
     37 
     38     public static final String LOG_TAG = LogTag.getLogTag();
     39 
     40     private OnItemSwipeListener mOnItemSwipeListener;
     41 
     42     public SwipeableListView(Context context) {
     43         this(context, null);
     44     }
     45 
     46     public SwipeableListView(Context context, AttributeSet attrs) {
     47         this(context, attrs, -1);
     48     }
     49 
     50     public SwipeableListView(Context context, AttributeSet attrs, int defStyle) {
     51         super(context, attrs, defStyle);
     52         float densityScale = getResources().getDisplayMetrics().density;
     53         float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
     54         mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale,
     55                 pagingTouchSlop);
     56         setItemsCanFocus(true);
     57     }
     58 
     59     @Override
     60     protected void onConfigurationChanged(Configuration newConfig) {
     61         super.onConfigurationChanged(newConfig);
     62         float densityScale = getResources().getDisplayMetrics().density;
     63         mSwipeHelper.setDensityScale(densityScale);
     64         float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
     65         mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
     66     }
     67 
     68     @Override
     69     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
     70         LogUtils.d(Utils.VIEW_DEBUGGING_TAG,
     71                 "START CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s",
     72                 isLayoutRequested(), getRootView().isLayoutRequested());
     73         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
     74         LogUtils.d(Utils.VIEW_DEBUGGING_TAG, new Error(),
     75                 "FINISH CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s",
     76                 isLayoutRequested(), getRootView().isLayoutRequested());
     77     }
     78 
     79     @Override
     80     public void requestLayout() {
     81         Utils.checkRequestLayout(this);
     82         super.requestLayout();
     83     }
     84 
     85     /**
     86      * Enable swipe gestures.
     87      */
     88     public void enableSwipe(boolean enable) {
     89         mEnableSwipe = enable;
     90     }
     91 
     92     public boolean isSwipeEnabled() {
     93         return mEnableSwipe;
     94     }
     95 
     96     public void setOnItemSwipeListener(OnItemSwipeListener listener) {
     97         mOnItemSwipeListener = listener;
     98     }
     99 
    100     @Override
    101     public boolean onInterceptTouchEvent(MotionEvent ev) {
    102         if (mEnableSwipe) {
    103             return mSwipeHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
    104         } else {
    105             return super.onInterceptTouchEvent(ev);
    106         }
    107     }
    108 
    109     @Override
    110     public boolean onTouchEvent(MotionEvent ev) {
    111         if (mEnableSwipe) {
    112             return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
    113         } else {
    114             return super.onTouchEvent(ev);
    115         }
    116     }
    117 
    118     @Override
    119     public View getChildAtPosition(MotionEvent ev) {
    120         // find the view under the pointer, accounting for GONE views
    121         final int count = getChildCount();
    122         int touchY = (int) ev.getY();
    123         int childIdx = 0;
    124         View slidingChild;
    125         for (; childIdx < count; childIdx++) {
    126             slidingChild = getChildAt(childIdx);
    127             if (slidingChild.getVisibility() == GONE) {
    128                 continue;
    129             }
    130             if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) {
    131                 return slidingChild;
    132             }
    133         }
    134         return null;
    135     }
    136 
    137     @Override
    138     public View getChildContentView(View view) {
    139         return view;
    140     }
    141 
    142     @Override
    143     public void onScroll() {
    144     }
    145 
    146     @Override
    147     public boolean canChildBeDismissed(View v) {
    148         return true;
    149     }
    150 
    151     @Override
    152     public void onChildDismissed(final View v) {
    153         if (v != null) {
    154             if (mOnItemSwipeListener != null) {
    155                 mOnItemSwipeListener.onSwipe(v);
    156             }
    157         }
    158     }
    159 
    160     @Override
    161     public void onDragCancelled(View v) {
    162     }
    163 
    164     private void redraw(View v) {
    165         int start = getFirstVisiblePosition();
    166         for (int i=start, j = getLastVisiblePosition(); i <= j; i++) {
    167             if (v == getItemAtPosition(i)) {
    168                 View view = getChildAt(i-start);
    169                 getAdapter().getView(i, view, this);
    170             }
    171         }
    172     }
    173 
    174     @Override
    175     public void onBeginDrag(View v) {
    176         // We do this so the underlying ScrollView knows that it won't get
    177         // the chance to intercept events anymore
    178         requestDisallowInterceptTouchEvent(true);
    179     }
    180 
    181     public interface OnItemSwipeListener {
    182         public void onSwipe(View view);
    183     }
    184 }
    185