1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.widget;
18
19import android.view.View.OnTouchListener;
20
21/**
22 * Helper for accessing features in PopupMenu introduced after API level 4 in a
23 * backwards compatible fashion.
24 */
25public class PopupMenuCompat {
26    /**
27     * Interface for the full API.
28     */
29    interface PopupMenuImpl {
30        public OnTouchListener getDragToOpenListener(Object popupMenu);
31    }
32
33    /**
34     * Interface implementation that doesn't use anything above v4 APIs.
35     */
36    static class BasePopupMenuImpl implements PopupMenuImpl {
37        @Override
38        public OnTouchListener getDragToOpenListener(Object popupMenu) {
39            return null;
40        }
41    }
42
43    /**
44     * Interface implementation for devices with at least KitKat APIs.
45     */
46    static class KitKatPopupMenuImpl extends BasePopupMenuImpl {
47        @Override
48        public OnTouchListener getDragToOpenListener(Object popupMenu) {
49            return PopupMenuCompatKitKat.getDragToOpenListener(popupMenu);
50        }
51    }
52
53    /**
54     * Select the correct implementation to use for the current platform.
55     */
56    static final PopupMenuImpl IMPL;
57    static {
58        final int version = android.os.Build.VERSION.SDK_INT;
59        if (version >= 19) {
60            IMPL = new KitKatPopupMenuImpl();
61        } else {
62            IMPL = new BasePopupMenuImpl();
63        }
64    }
65
66    private PopupMenuCompat() {
67        // This class is not publicly instantiable.
68    }
69
70    /**
71     * On API {@link android.os.Build.VERSION_CODES#KITKAT} and higher, returns
72     * an {@link OnTouchListener} that can be added to the anchor view to
73     * implement drag-to-open behavior.
74     * <p>
75     * When the listener is set on a view, touching that view and dragging
76     * outside of its bounds will open the popup window. Lifting will select the
77     * currently touched list item.
78     * <p>
79     * Example usage:
80     * <pre>
81     * PopupMenu myPopup = new PopupMenu(context, myAnchor);
82     * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());
83     * </pre>
84     *
85     * @param popupMenu the PopupMenu against which to invoke the method
86     * @return a touch listener that controls drag-to-open behavior, or null on
87     *         unsupported APIs
88     */
89    public static OnTouchListener getDragToOpenListener(Object popupMenu) {
90        return IMPL.getDragToOpenListener(popupMenu);
91    }
92}
93