Ich habe eine GridView in einer Anwendung, an der ich gerade arbeite. Ich möchte die Elemente in der GridView per Drag & Drop neu anordnen können. Ich habe viel Hilfe für ListViews gefunden, aber nichts für GridViews. Ich möchte ein Verhalten wie in dieser Launcher-App http://www.youtube.com/watch?v=u5LISE8BU_E&t=5m30s erzielen. Irgendwelche Ideen?
Wenn Sie dieses Problem nicht beheben, gebe ich meinen Code an. Aber es funktioniert auf Android 3.0 und höher, weil ich Android-Drag-N-Drop-Framework
grid = (GridView) findViewById(R.id.grid);
grid.setAdapter(new DragGridAdapter(items, getActivity()));
....
grid.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
GridView parent = (GridView) v;
int x = (int) event.getX();
int y = (int) event.getY();
int position = parent.pointToPosition(x, y);
if (position > AdapterView.INVALID_POSITION) {
int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
View curr = parent.getChildAt(i);
curr.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
boolean result = true;
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_LOCATION:
break;
case DragEvent.ACTION_DRAG_ENTERED:
v.setBackgroundResource(R.drawable.shape_image_view_small_gallery_selected);
break;
case DragEvent.ACTION_DRAG_EXITED:
v.setBackgroundResource(R.drawable.shape_image_view_small_gallery_unselected);
break;
case DragEvent.ACTION_DROP:
if (event.getLocalState() == v) {
result = false;
} else {
View droped = (View) event.getLocalState();
GridItem dropItem = ((DragGridItemHolder) droped.getTag()).item;
GridView parent = (GridView) droped.getParent();
DragGridAdapter adapter = (DragGridAdapter) parent.getAdapter();
List<GridItem> items = adapter.getItems();
View target = v;
GridItem targetItem = ((DragGridItemHolder) target.getTag()).item;
int index = items.indexOf(targetItem);
items.remove(dropItem);
items.add(index, dropItem);
adapter.notifyDataSetChanged();
}
break;
case DragEvent.ACTION_DRAG_ENDED:
v.setBackgroundResource(R.drawable.shape_image_view_small_gallery_unselected);
break;
default:
result = false;
break;
}
return result;
}
});
}
int relativePosition = position - parent.getFirstVisiblePosition();
View target = (View) parent.getChildAt(relativePosition);
DragGridItemHolder holder = (DragGridItemHolder) target.getTag();
GridItem currentItem = holder.item;
String text = currentItem.getFile().getAbsolutePath();
ClipData data = ClipData.newPlainText("DragData", text);
target.startDrag(data, new View.DragShadowBuilder(target), target, 0);
}
}
return false;
und DragGridAdapter
public class DragGridAdapter extends BaseAdapter{
private Context context;
private List<GridItem> items;
public DragGridAdapter(List<GridItem> items, Context context){
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
DragGridItemHolder holder;
if (convertView == null) {
holder = new DragGridItemHolder();
ImageView img = new ImageView(context);
holder.image = img;
convertView = img;
convertView.setTag(holder);
} else {
holder = (DragGridItemHolder) convertView.getTag();
}
holder.item = items.get(position);
holder.image.setImageBitmap(items.get(position).getBitmap());
return convertView;
}
public List<GridItem> getItems() {
return items;
}
Ich hoffe es hilft dir
Meine Version zum Ziehen und Ablegen der Rasteransicht https://github.com/askerov/DynamicGrid .
Er erweitert das ursprüngliche GridView, unterstützt das Ziehen und Ablegen, um die Elemente neu anzuordnen. Es ist voll funktionsfähig auf Version 3.0 und höher, unterstützt jedoch 2.2 und 2.3 mit Einschränkungen (keine Animationen).
Werfen Sie einen Blick auf thquinns DraggableGridView , Dies wurde für Android 2.2 (API Level 8) entwickelt.
Es ist nicht leicht, eine kurze Antwort darauf zu geben, da es Hunderte von Codezeilen gibt: Sie müssen den Start der Ziehaktion abfangen, normalerweise onLongClick, die Ansicht ausblenden, die die Aktion ausgelöst hat, und eine Overlay anzeigen, die verschoben werden kann während sich der Benutzer noch in der Touchdown-Aktion befindet, und nehmen Sie die Änderungen schließlich beim Touch-Up vor. Am besten erweitern Sie den Standard GridView in Android.widget. Das Ergebnis sieht so aus:
Hier ist eine Youtube-Video-Demo, die Sie möglicherweise nützlich finden: http://www.youtube.com/watch?v=m4yktX3SWSs&feature=youtu.be
Ich habe auch eine ausführlichere Antwort in einem Artikel auf meinem Blog zusammengestellt. Vielleicht finden Sie es nützlich, da es ein komplettes Beispiel für den Quellcode enthält. Der Link lautet: http://www.pocketmagic.net/2013/11/complex-Android-gridview-mit-drag-und-drop-funktionalität/
Mit Hilfe des Drag-and-Drop-Frameworks verwende ich anstelle des Umlaufens der untergeordneten Elemente und Festlegen des Draglisteners einen Layout-Container für Rasterelemente, einen DragableLinearLayout, der das LinearLayout erweitert und die onDragEvent (DragEvent) -Methode implementiert.
So können Sie Ihr Raster wie üblich mit dem Adapter füllen, und der größte Teil des Drag & Drop-Codes befindet sich im onDragEvent von DragableLinearLayout
public class DragableLinearLayout extends LinearLayout {
public DragableLinearLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public DragableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DragableLinearLayout(Context context) {
super(context);
}
@Override
public boolean onDragEvent(DragEvent event) {
//in wich grid item am I?
GridView parent = (GridView) getParent();
Object item = parent.getAdapter().getItem(
parent.getPositionForView(this));
//if you need the database id of your item...
Cursor cur = (Cursor) item;
long l_id = cur.getLong(cur.getColumnIndex("youritemid"));
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DRAG_ENTERED:
setBackgroundColor(Color.GREEN);
invalidate();
return true;
case DragEvent.ACTION_DRAG_EXITED:
setBackgroundColor(Color.WHITE);
invalidate();
return false;
case DragEvent.ACTION_DROP:
ClipData cd = event.getClipData();
long l_id_start = Long.valueOf(cd.getItemAt(0).getText()
.toString());
//
Toast.makeText(getContext(), "DROP FROM " + l_id_start
+ " TO " + l_id, Toast.LENGTH_LONG);
//do your stuff
........
//the db requery will be on the onDragEvent.drop of the container
//see the listener
return false;
case DragEvent.ACTION_DRAG_ENDED:
setBackgroundColor(Color.WHITE);
invalidate();
//
return false;
}
return true;
}
}
private View.OnDragListener listenerOnDragEvent = new View.OnDragListener() {
public boolean onDrag(View v, DragEvent event) {
// Defines a variable to store the action type for the incoming
// event
final int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DROP:
// REQUERY
updateDbView();
return false;
// break;
}
return true;
}
};
Ich habe kürzlich eine Lösung gefunden, für die der Autor einige Zeit hier verbracht hat http://blahti.wordpress.com/2012/03/03/improved-drag-drop-for-gridview/ Es gibt 4 Vorhergehende verwandte Blogbeiträge, in denen detailliert beschrieben wird, was dort vor sich geht.
Wahrscheinlich ist das PagedDragDropGrid-Projekt genau das, was Sie brauchen: https://github.com/mrKlar/PagedDragDropGrid
Es bietet benutzerdefinierte ViewGroup
(ähnlich wie GridView) mit Funktionen für die reibungslose Neuordnung (genau wie in Ihrem Video). Wahrscheinlich erfordert es ein paar Anpassungen, aber es lohnt sich.
Ich hoffe es hilft.
Hier ist eine bibliothek von h6ah4i, die die Recycler-Ansichten nutzt, um eine Drag-and-Drop-Rasteransicht mit Nachordnungsfunktionen bereitzustellen.
Google hat vor einigen Monaten einige Code Labs veröffentlicht. https://codelabs.developers.google.com/codelabs/Android-training-adaptive-layouts/index.html?index=..%2F..%2Fandroid-training#
Sie können die Lösung dafür hier überprüfen https://github.com/google-developer-training/Android-fundamentals-apps-v2/tree/master/MaterialMe-Resource
Sie erstellen ein Rasterlayout mit beweglichen Karten, die mit dem itemTouchHandler an eine beliebige Stelle im Layout gezogen und dort abgelegt werden können.
Der detailliertere Code für das Ziehen und Ablegen lautet hier . Sie müssen sich mit Aufgabe 3: Machen Sie Ihre CardView schwenkbar, beweglich, und anklickbar Abschnitt