Desplaza la vista de cuadrícula mientras arrastra el elemento (como sombra)
Estoy desarrollando para api> 14 y he implementado la funcionalidad de arrastrar / soltar en un GridView
.
Sin embargo, al arrastrar elementos a la parte superior o inferior de la pantalla, el GridView
no se desplaza.
- Cómo obtener la altura en píxeles de LinearLayout con layout_weight
- Manejador de errores por defecto de RxJava
- Java .equals () devuelve false cuando las cadenas son iguales
- Android stackoverflow utilizando while loop
- Objeto de almacenamiento Robospice que extiende ArrayList en la base de datos a través de Ormlite
Me gustaría tenerlo desplazarse en la dirección en la que arrastra un elemento cada vez más rápido a medida que se mueve hacia el borde y lento como mover el elemento de nuevo hacia el centro vertical de la pantalla.
Seguramente este tipo de funcionalidad debe ser estándar en cualquier drag-n-drop?
De todos modos, ¿alguien sabe la mejor manera de abordar esto?
ACTUALIZACIÓN : En realidad no puedo encontrar un ejemplo en Internet que intente desplazarse con un elemento de cuadrícula arrastrado (¿me estoy perdiendo algo aquí?) Y mucho menos resolver mi problema.
¿Cómo se obtiene el elemento arrastrable (que aparece como una sombra) para desplazarse por la vista de cuadrícula? Estoy asignando el arrastre de la siguiente manera:
int gridChildPosition = position - mGridView.getFirstVisiblePosition(); ViewFlipper gridItem = (ViewFlipper) mGridView.getChildAt(gridChildPosition); ClipData data = ClipData.newPlainText("", ""); DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(gridItem); if (mGridView.startDrag(data, shadowBuilder, gridItem, 0)) { int lastVisiblePosition = mGridView.getLastVisiblePosition() - mGridView.getFirstVisiblePosition(); for (int i=0; i<=lastVisiblePosition; i++) { if (i == gridChildPosition) { continue; } mGridView.getChildAt(i).setOnDragListener(new GridItemDragListener(position)); mGridView.getChildAt(i).setAlpha(0.4f); } }
Por encima del código crea la sombra arrastrable y todos los demás elementos se atenúan. Pero no estoy seguro de cómo puedo obtener la sombra para desplazarse por la vista de cuadrícula.
- ¿Cómo Native Extension toma una captura de pantalla en un dispositivo Android?
- AES obtiene resultados diferentes en iOS (Obj-C) y Android (Java)
- Cómo cambiar la orientación de bloqueo en Android?
- Nueva línea (/ n) no es compatible con android?
- Abrir una imagen en la galería utilizando la ruta del archivo
- Diseño en blanco - eglSurfaceAttrib no implementado
- ¿Cuál es la diferencia entre `opencv.android.JavaCameraView` y` opencv.android.NativeCameraView`
- Intentando agregar un método openFile a React Native, no se puede llamar a getCurrentActivity
Lo bueno de Drag Events es que también puedes escucharlos en el grupo de padres ViewGroup
. Extienda GridView
y onDragEvent
para supervisar DragEvent.ACTION_DRAG_LOCATION
. Allí, obtenga las coordenadas Y ( event.getY()
) de la resistencia. Asegúrese de devolver true de ACTION_DRAG_STARTED
o no recibirá el evento en ACTION_DRAG_LOCATION
.
Determine sus "hit boxes", tal vez usando la técnica que sugiere jaibatrik , o simplemente usando un porcentaje de la altura medida de GridView.
Probablemente tendría más sentido usar smoothScrollByOffset(int offset)
, de esta manera puede implementar scroll escalonado / exponencial. Es decir, cuanto más tiempo el usuario mantiene el elemento arrastrado en el cuadro de resultados, mayor es el desplazamiento.
Suena como una idea genial para una biblioteca / componente de código abierto. D
EDITAR:
He aquí un ejemplo de cómo podría hacer esto:
import android.app.Activity; import android.content.ClipData; import android.content.ClipData.Item; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.DragEvent; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.ArrayAdapter; import android.widget.GridView; public class GridDragActivity extends Activity implements OnItemLongClickListener { private static final String TAG = "GridDragActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyGridView gridView = new MyGridView(this); gridView.setNumColumns(3); gridView.setOnItemLongClickListener(this); gridView.setAdapter(new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, COUNTRIES)); setContentView(gridView); } @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { ClipData data = ClipData.newPlainText((String) view.getTag(), String.valueOf(position)); View.DragShadowBuilder shadow = new View.DragShadowBuilder(view); view.startDrag(data, shadow, null, 0); return true; } class MyGridView extends GridView { private static final int THRESHHOLD = 200; private static final int OFFSET = 10; public MyGridView(Context context) { super(context); } @Override public boolean onDragEvent(DragEvent event) { int height = getMeasuredHeight(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: return true; case DragEvent.ACTION_DRAG_LOCATION: float y = event.getY(); if (height - y < THRESHHOLD) { smoothScrollByOffset(OFFSET); } else if (height - y > height - THRESHHOLD) { smoothScrollByOffset(-OFFSET); } return true; case DragEvent.ACTION_DROP: ClipData data = event.getClipData(); Item item = data.getItemAt(0); int start = Integer.valueOf((String) item.getText()); int end = pointToPosition((int) event.getX(), (int) event.getY()); Log.i(TAG, "DROP started at = " + start + ", ended at = " + end); return true; } return super.onDragEvent(event); } } static final String[] COUNTRIES = new String[] { "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland", "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary" }; }
Creo que necesitas usar los métodos smoothScrollToPosition(int position)
o smoothScrollByOffset(int offset)
de GridView
. Tome dos rectángulos en la parte superior e inferior de la pantalla. Si el evento táctil se recibe en esos rectángulos mientras arrastra, desplácese por GridView
. Puede obtener la última posición visible en cualquier momento utilizando el método getLastVisiblePosition()
.
- Configuración de la aplicación de Android
- ¿Cuál es la diferencia entre una actividad y un servicio de Android