Popup discreto que no bloqueará la caída de la fricción n en android

He estado trabajando en la aplicación del lanzador para el androide similar al lanzador de la novedad. He configurado OnItemLongClickListener y OnDragListener. Cuando hago clic en un icono, aparece un menú emergente con un menú como "Eliminar", "Cambiar icono", etc. A continuación se muestra el progreso de la aplicación con una ventana emergente abierta mientras se hace clic.

Introduzca aquí la descripción de la imagen

El problema es cuando el popup se abre las obras de arrastrar pero no funciona. Parece que no puedo registrar la posición x, y una vez que el popup está abierto. También cuando se realiza la caída, se muestra el siguiente mensaje en logcat.

I/ViewRootImpl: Reporting drop result: false 

Mi código es algo como esto en OnDragListener

 public boolean onDrag(View v, DragEvent event) { int dragEvent = event.getAction(); switch (dragEvent) { case DragEvent.ACTION_DRAG_LOCATION: //Open popup here; note: its opened only once. popup.show(); //Log.i("Position x : ", Float.toString(event.getX())); log x or y /*code to detect x any y change amount and close the popup once user drags the icon little further and app knows that user is trying to drag instead of opening the popup and hence close the popup. popup.dismiss(); */ // other case like ACTION_DROP etx goes after this } } 

Pero parece que después de abrir el popup no puedo registrar x o y; También no se puede ejecutar el código que determina si la acción estaba destinada a "arrastrar" o "abrir popup".

Entonces, ¿cómo puedo resolver este problema? Quiero cerrar el popup una vez que la cantidad de arrastre en cualquier es suficiente para saber que el usuario quiere arrastrar. Y si no detener el arrastre y mostrar el popup sólo.

Editar

He resuelto el problema con popup mediante el uso de OnTouchListner y OnDragListner. A continuación se muestra mi código de OnDragListner.

 //bottomAppDrawer is a GridView bottomAppDrawer.setOnDragListener(new View.OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { int dragEvent = event.getAction(); LinearLayout draggedItem = (LinearLayout) event.getLocalState(); //dragged LinearLayout GridView targetItem = (GridView) v; /* How do i get this drop target as LinearLayout so that i can delete or swap data */ switch (dragEvent) { case DragEvent.ACTION_DRAG_LOCATION: if(reset==false) { dragPositionStart = event.getX(); reset= true; } if(Math.abs(dragPositionStart - event.getX())>=20) { Log.i("Position close : ", Float.toString(dragPositionStart)); if(isPopupOpen) { popupMenu.dismiss(); v.startDrag(data, dragShadow, itemView, 0); Toast.makeText(mContext, "popup closed", Toast.LENGTH_SHORT).show(); isPopupOpen = false; } reset = false; } break; case DragEvent.ACTION_DROP: Toast.makeText(mContext, "drop" + Integer.toString(targetItem.getChildCount()), Toast.LENGTH_SHORT).show(); break; } return true; } }); 

Ahora el problema es que estoy recibiendo el objetivo de la caída "Gridview", ya que estoy dejando de LinearLayout en "Gridview". También este "LinearLayout es el hijo de la" GridView ".Y quiero que el objetivo de la caída sea otro" LinearLayout "dentro de la misma" GridView ".Para que pueda intercambiar datos o reordenar.Como en la figura de abajo.

Introduzca aquí la descripción de la imagen

Por lo que entiendo hay dos cosas que quieres hacer. 1) Reordenar las vistas después de arrastrar. Y 2) Cambiar los tipos de vista después del reorden.

Para el problema 1, ya que es una vista de cuadrícula, suena como si realmente queremos reordenar los datos en el adaptador, y posiblemente cambiar los datos para hacer que se muestre de manera diferente. Pero tenemos que averiguar la posición del elemento original y la posición de destino destino.

Podemos extender el GridView para hacer eso:

 public class DragAndDropGridView extends GridView { public void handleMove(int x, int y, int originalPosition) { Rect rect = new Rect(); PushbackAdapter adapter = (PushbackAdapter) getAdapter(); for (int visiblePosition = getFirstVisiblePosition(); visiblePosition <= getLastVisiblePosition(); visiblePosition++) { // TODO verify that there are no edge cases not covered by this View view = getChildAt(visiblePosition); int left = view.getLeft(); int top = view.getTop(); getChildVisibleRect(view, rect, null); rect.offsetTo(left, top); if (rect.contains(x, y)) { // yay the user tried drop the view at this location // determine if they wanted to drop it here or after this side int centerX = rect.centerX(); if (x <= centerX) { // we want to drop it here adapter.move(originalPosition, visiblePosition); adapter.notifyDataSetInvalidated(); break; } else { // we want to drop it behind adapter.move(originalPosition, visiblePosition + 1); adapter.notifyDataSetInvalidated(); break; } } } } } 

Eso nos deja con llamar a handleMoveMethod. Lo hacemos desde el método ACTION_DROP.

  case DragEvent.ACTION_DROP: handleMove((int)event.getX(), (int)event.getY(), getPositionForView(draggedItem)); Toast.makeText(mContext, "drop" + Integer.toString(targetItem.getChildCount()), Toast.LENGTH_SHORT).show(); break; 

Por último (problema 2) suena como usted puede desear cambiar el contenido del objeto en la posición o el tipo de opinión él es contenido pulg. Sugerir utilizar los métodos getItemViewType y getItemViewTypeCount si usted necesita tener diversos tipos de puntos de vista. Por ejemplo, algo en la línea de lo siguiente:

  private static class PushbackAdapter extends ArrayAdapter { ArrayList<Object> mItems; public void move(int originalPosition, int targetPosition){ // TODO verify that this move logic is correct Object item = mItems.remove(originalPosition); item.useLinearLayoutType(true); mItems.add(targetPosition, item); } ... @Override public int getItemViewType(int i) { return mItems.get(i).isLeanearLayoutType()? 1 : 0; } 

Podría haber errores con esto, así que prueba a fondo

Encuentra la posición de LinerLayout (que arrastra) en Gridview usando targetItem.pointToPosition(..) .

Deslizar LinerLayout utilizando el código siguiente:

 int i =targetItem.pointToPosition((int)event.getX(), (int)event.getY()); int j = Integer.parseInt(event.getClipData().getItemAt(0).getText().toString()); Collections.swap(targetItem, i, j);//swap Linerlayout Log.i(TAG, "Swapped " + i+ " with " + j); 

El código no se ha probado. Espero que te ayude. 🙂

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.