1379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette/*
2379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * Copyright (C) 2013 The Android Open Source Project
3379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette *
4379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License");
5379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * you may not use this file except in compliance with the License.
6379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * You may obtain a copy of the License at
7379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette *
8379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette *      http://www.apache.org/licenses/LICENSE-2.0
9379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette *
10379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * Unless required by applicable law or agreed to in writing, software
11379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS,
12379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * See the License for the specific language governing permissions and
14379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * limitations under the License.
15379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette */
16379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
17379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverettepackage android.support.v4.widget;
18379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
19379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viveretteimport android.view.View.OnTouchListener;
20379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
21379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette/**
22379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * Helper for accessing features in PopupMenu introduced after API level 4 in a
23379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette * backwards compatible fashion.
24379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette */
25379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverettepublic class PopupMenuCompat {
26379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    /**
27379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * Interface for the full API.
28379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     */
29379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    interface PopupMenuImpl {
30379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        public OnTouchListener getDragToOpenListener(Object popupMenu);
31379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
32379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
33379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    /**
34379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * Interface implementation that doesn't use anything above v4 APIs.
35379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     */
36379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    static class BasePopupMenuImpl implements PopupMenuImpl {
37379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        @Override
38379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        public OnTouchListener getDragToOpenListener(Object popupMenu) {
39379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette            return null;
40379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        }
41379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
42379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
43379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    /**
44379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * Interface implementation for devices with at least KitKat APIs.
45379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     */
46379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    static class KitKatPopupMenuImpl extends BasePopupMenuImpl {
47379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        @Override
48379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        public OnTouchListener getDragToOpenListener(Object popupMenu) {
49379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette            return PopupMenuCompatKitKat.getDragToOpenListener(popupMenu);
50379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        }
51379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
52379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
53379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    /**
54379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * Select the correct implementation to use for the current platform.
55379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     */
56379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    static final PopupMenuImpl IMPL;
57379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    static {
58379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        final int version = android.os.Build.VERSION.SDK_INT;
59379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        if (version >= 19) {
60379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette            IMPL = new KitKatPopupMenuImpl();
61379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        } else {
62379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette            IMPL = new BasePopupMenuImpl();
63379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        }
64379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
65379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
66379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    private PopupMenuCompat() {
67379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        // This class is not publicly instantiable.
68379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
69379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette
70379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    /**
71379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * On API {@link android.os.Build.VERSION_CODES#KITKAT} and higher, returns
72379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * an {@link OnTouchListener} that can be added to the anchor view to
73379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * implement drag-to-open behavior.
74379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * <p>
75379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * When the listener is set on a view, touching that view and dragging
76379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * outside of its bounds will open the popup window. Lifting will select the
77379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * currently touched list item.
78379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * <p>
79379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * Example usage:
80379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * <pre>
81379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * PopupMenu myPopup = new PopupMenu(context, myAnchor);
82379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());
83379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * </pre>
84379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     *
85379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * @param popupMenu the PopupMenu against which to invoke the method
86379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     * @return a touch listener that controls drag-to-open behavior, or null on
87379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     *         unsupported APIs
88379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette     */
89379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    public static OnTouchListener getDragToOpenListener(Object popupMenu) {
90379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette        return IMPL.getDragToOpenListener(popupMenu);
91379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette    }
92379312ec6d3e517f8bb8fcf2e9876b42f9495df3Alan Viverette}
93