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 Reference<View> ref = (Reference<View>) event.getLocalState();
60 final View srcView = ref.reference;
62 switch (event.getAction()) {
63 case DragEvent.ACTION_DRAG_ENTERED:
64 srcView.setVisibility(View.VISIBLE);
65 dstView.setVisibility(View.INVISIBLE);
67 Integer src = mPositions.get(srcView);
68 Integer dst = mPositions.get(dstView);
69 if (src != null && dst != null)
72 ref.reference = dstView;
75 case DragEvent.ACTION_DRAG_ENDED:
76 srcView.post(new Runnable() {
79 srcView.setVisibility(View.VISIBLE);
89 public boolean onLongClick(final View view) {
90 // Force a reset of any states
91 notifyDataSetChanged();
93 // Start the drag on the main loop to allow
94 // the above state reset to settle.
95 view.post(new Runnable() {
98 ClipData data = ClipData.newPlainText("", "");
99 DragShadowBuilder sb = new View.DragShadowBuilder(view);
100 view.startDrag(data, sb, new Reference<View>(view), 0);
108 protected void processView(View view, int type) {
109 view.setOnDragListener(this);
110 view.setOnLongClickListener(this);
113 protected int getPositionFromView(View view) {
115 Integer position = mPositions.get(view);
116 if (position != null)
119 ViewParent vp = view.getParent();
120 if (vp == null || !(vp instanceof View))
129 public abstract void move(int fromPosition, int toPosition);