4 * Authors: Nathaniel McCallum <npmccallum@redhat.com>
6 * Copyright (C) 2013 Nathaniel McCallum, Red Hat
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 package org.fedorahosted.freeotp.adapters;
23 import java.util.WeakHashMap;
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.View.OnDragListener;
30 import android.view.View.OnLongClickListener;
31 import android.view.ViewParent;
33 public abstract class ReorderableBaseAdapter extends BaseAdapter implements OnLongClickListener, OnDragListener {
34 private final WeakHashMap<View, Integer> mPositions = new WeakHashMap<View, Integer>();
35 private class Reference<T> {
36 public Reference(T t) { reference = t; }
41 public void notifyDataSetChanged() {
43 super.notifyDataSetChanged();
47 public void notifyDataSetInvalidated() {
49 super.notifyDataSetInvalidated();
53 protected void bindView(View view, int position) {
54 mPositions.put(view, position);
58 public boolean onDrag(View dstView, DragEvent event) {
59 @SuppressWarnings("unchecked")
60 Reference<View> ref = (Reference<View>) event.getLocalState();
61 final View srcView = ref.reference;
63 switch (event.getAction()) {
64 case DragEvent.ACTION_DRAG_ENTERED:
65 srcView.setVisibility(View.VISIBLE);
66 dstView.setVisibility(View.INVISIBLE);
68 Integer src = mPositions.get(srcView);
69 Integer dst = mPositions.get(dstView);
70 if (src != null && dst != null)
73 ref.reference = dstView;
76 case DragEvent.ACTION_DRAG_ENDED:
77 srcView.post(new Runnable() {
80 srcView.setVisibility(View.VISIBLE);
90 public boolean onLongClick(final View view) {
91 // Force a reset of any states
92 notifyDataSetChanged();
94 // Start the drag on the main loop to allow
95 // the above state reset to settle.
96 view.post(new Runnable() {
99 ClipData data = ClipData.newPlainText("", "");
100 DragShadowBuilder sb = new View.DragShadowBuilder(view);
101 view.startDrag(data, sb, new Reference<View>(view), 0);
109 protected void processView(View view, int type) {
110 view.setOnDragListener(this);
111 view.setOnLongClickListener(this);
114 protected int getPositionFromView(View view) {
116 Integer position = mPositions.get(view);
117 if (position != null)
120 ViewParent vp = view.getParent();
121 if (vp == null || !(vp instanceof View))
130 public abstract void move(int fromPosition, int toPosition);