]> Pileus Git - ~andy/freeotp/blob - src/org/fedorahosted/freeotp/adapters/ReorderableBaseAdapter.java
Don't set visibility on long press
[~andy/freeotp] / src / org / fedorahosted / freeotp / adapters / ReorderableBaseAdapter.java
1 /*
2  * FreeOTP
3  *
4  * Authors: Nathaniel McCallum <npmccallum@redhat.com>
5  *
6  * Copyright (C) 2013  Nathaniel McCallum, Red Hat
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 package org.fedorahosted.freeotp.adapters;
22
23 import java.util.WeakHashMap;
24
25 import android.content.ClipData;
26 import android.view.DragEvent;
27 import android.view.View;
28 import android.view.View.DragShadowBuilder;
29 import android.view.ViewParent;
30
31 public abstract class ReorderableBaseAdapter extends BaseAdapter {
32         private final WeakHashMap<View, Integer> mPositions = new WeakHashMap<View, Integer>();
33         private class Reference<T> {
34                 public Reference(T t) { reference = t; }
35                 T reference;
36         }
37
38         @Override
39         public void notifyDataSetChanged() {
40                 mPositions.clear();
41                 super.notifyDataSetChanged();
42         }
43
44         @Override
45         public void notifyDataSetInvalidated() {
46                 mPositions.clear();
47                 super.notifyDataSetInvalidated();
48         }
49
50         @Override
51         protected void bindView(View view, int position) {
52                 mPositions.put(view, position);
53         }
54
55         @Override
56         protected void processView(View view, int type) {
57                 view.setOnDragListener(new View.OnDragListener() {
58                         @Override
59                         public boolean onDrag(View dstView, DragEvent event) {
60                                 Reference<View> ref = (Reference<View>) event.getLocalState();
61                                 final View srcView = ref.reference;
62
63                                 switch (event.getAction()) {
64                                 case DragEvent.ACTION_DRAG_ENTERED:
65                                         srcView.setVisibility(View.VISIBLE);
66                                         dstView.setVisibility(View.INVISIBLE);
67
68                                         Integer src = mPositions.get(srcView);
69                                         Integer dst = mPositions.get(dstView);
70                                         if (src != null && dst != null)
71                                                 move(src, dst);
72
73                                         ref.reference = dstView;
74                                         break;
75
76                                 case DragEvent.ACTION_DRAG_ENDED:
77                                     srcView.post(new Runnable() {
78                                                 @Override
79                                                 public void run() {
80                                                         srcView.setVisibility(View.VISIBLE);
81                                                 }
82                                         });
83                                         break;
84                                 }
85
86                                 return true;
87                         }
88                 });
89
90                 view.setOnLongClickListener(new View.OnLongClickListener() {
91                         @Override
92                         public boolean onLongClick(final View view) {
93                                 // Force a reset of any states
94                                 notifyDataSetChanged();
95
96                                 // Start the drag on the main loop to allow
97                                 // the above state reset to settle.
98                                 view.post(new Runnable() {
99                                         @Override
100                                         public void run() {
101                                                 ClipData data = ClipData.newPlainText("", "");
102                                                 DragShadowBuilder sb = new View.DragShadowBuilder(view);
103                                                 view.startDrag(data, sb, new Reference<View>(view), 0);
104                                         }
105                                 });
106
107                                 return true;
108                         }
109                 });
110         }
111
112         protected int getPositionFromView(View view) {
113                 while(true) {
114                         Integer position = mPositions.get(view);
115                         if (position != null)
116                                 return position;
117
118                         ViewParent vp = view.getParent();
119                         if (vp == null || !(vp instanceof View))
120                                 break;
121
122                         view = (View) vp;
123                 }
124
125                 return -1;
126         }
127
128         public abstract void move(int fromPosition, int toPosition);
129 }