Android GridView reordena elementos mediante Arrastrar y soltar
Tengo un GridView en una aplicación en la que estoy trabajando. Me gustaría poder reordenar los elementos en el GridView mediante arrastrar y soltar. He encontrado mucha ayuda para ListViews pero nada en GridViews. Quiero lograr el comportamiento como en esta aplicación de lanzamiento http://www.youtube.com/watch?v=u5LISE8BU_E&t=5m30s . ¿Algunas ideas?
- Actualización del primer elemento gridview después de que getView lo infla dos veces
- El clic de GridView no funciona dentro de la vista de lista personalizada
- Obtener ID de la vista en GridView
- GridLayoutAnimationControl Utilizar
- No se puede dibujar línea sobre elementos gridview correctamente a través de celdas textview en Android
- Cómo obtener vídeos en GridView desde ** SDCard / carpeta / subcarpeta "
- Adición dinámica de elementos de cuadrícula en vista de cuadrícula
- Volley funciona en WIFI pero no en 3G
- GridView y el exceso de espacio de relleno
- ¿Cómo aplicar diferentes iconos y texto diferente en el tutorial de vista de cuadrícula de Android?
- Mantenga GridView al reanudar desde el modo de suspensión
- Android GridView que hace que los artículos encajen en cada tamaño de pantalla
- ¿Qué stretchMode utilizar en GridView en android
Si no resuelve este problema, le proporcionaré mi código. Pero funciona en Android 3.0 y superior, ya que uso android arrastrar y soltar marco
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;
Y 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; }
Espero que te ayude
Mi versión para arrastrar y soltar la vista de cuadrícula https://github.com/askerov/DynamicGrid .
Se extiende GridView original, soporta arrastrar y soltar para reordenar elementos, auto-desplazamiento si arrastrar fuera de la pantalla. Es completamente funcional en 3.0+ api, pero soporta 2.2 y 2.3 con limitaciones (sin animaciones).
Eche un vistazo a Thquinn's DraggableGridView , Esto fue desarrollado dirigido a Android 2.2 (API nivel 8). Espero que esto ayude a alguien 🙂
Utilizando el marco de arrastrar y soltar, en lugar de que el ciclismo de los niños y la configuración del draglistener, que utilizan como un contenedor de elementos de rejilla, DragableLinearLayout que extiende el LinearLayout e implementa el método onDragEvent (DragEvent).
Así que usted puede llenar su red con el adaptador como de costumbre y la mayor parte del código de arrastrar y soltar está en el onDragEvent de 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; } };
No es fácil proporcionar una respuesta breve sobre esto, ya que hay cientos de líneas de código involucradas: necesitará interceptar el inicio de la acción de arrastrar, normalmente en onLongClick, ocultar la vista que inició la acción, mostrar una superposición que se puede mover alrededor Mientras que el usuario todavía está en la acción del tacto abajo, y finalmente hace los cambios en retocar. La mejor manera de ir es extender el GridView estándar en android.widget. El resultado se ve así:
Aquí tienes una demo de video de youtube que podrías encontrar útil: http://www.youtube.com/watch?v=m4yktX3SWSs&feature=youtu.be
También he reunido una respuesta más detallada en un artículo en mi blog, que podría encontrar útil ya que viene con un ejemplo completo de código fuente. El enlace es: http://www.pocketmagic.net/2013/11/complex-android-gridview-with-drag-and-drop-functionality/
Recientemente he encontrado una solución en la que su autor pasó bastante tiempo aquí http://blahti.wordpress.com/2012/03/03/improved-drag-drop-for-gridview/ Hay 4 posts relacionados anteriores que explican lo que es Pasando en más detalle allí.
Probablemente el proyecto PagedDragDropGrid es lo que necesita: https://github.com/mrKlar/PagedDragDropGrid
Proporciona ViewGroup
personalizado (similar a GridView) con característica de reordenación suave (exactamente como en tu video). Probablemente requerirá un poco de personalizaciones, pero vale la pena.
Espero que ayude.
Aquí hay una biblioteca de h6ah4i que aprovecha las vistas de Recycler para ofrecer un gridview de arrastrar y soltar con capacidades de reordenar.
- Gradle 14.4 falla al generar – No se encontró el método DSL de Gradle 'packageName ()'
- Cómo crear realmente pequeños botones en android de código?