Android Deslizar en la Lista


¿Alguien tiene un ejemplo simple de una ListActivity que muestra Textviews en una columna y cuando desliza de izquierda a derecha ve esa fila en una nueva vista? Esto sería decir editar los datos para esa fila o mostrar información más detallada en esa fila. Por favor, no haga referencia al código shogun u otros sitios, ya que he buscado en Google y no he visto esta respuesta.

Author: JPM, 2010-12-07

4 answers

Tuve el mismo problema y no encontré mi respuesta aquí.

Quería detectar una acción de deslizamiento en el elemento ListView y marcarlo como deslizado, mientras continuaba soportando onItemClick y OnItemLongClick.

Aquí está mi solución:

1a La clase SwipeDetector:

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SwipeDetector implements View.OnTouchListener {

    public static enum Action {
        LR, // Left to Right
        RL, // Right to Left
        TB, // Top to bottom
        BT, // Bottom to Top
        None // when no action was detected
    }

    private static final String logTag = "SwipeDetector";
    private static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;
    private Action mSwipeDetected = Action.None;

    public boolean swipeDetected() {
        return mSwipeDetected != Action.None;
    }

    public Action getAction() {
        return mSwipeDetected;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downX = event.getX();
            downY = event.getY();
            mSwipeDetected = Action.None;
            return false; // allow other events like Click to be processed
        case MotionEvent.ACTION_UP:
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // horizontal swipe detection
            if (Math.abs(deltaX) > MIN_DISTANCE) {
                // left or right
                if (deltaX < 0) {
                    Log.i(logTag, "Swipe Left to Right");
                    mSwipeDetected = Action.LR;
                    return false;
                }
                if (deltaX > 0) {
                    Log.i(logTag, "Swipe Right to Left");
                    mSwipeDetected = Action.RL;
                    return false;
                }
            } else if (Math.abs(deltaY) > MIN_DISTANCE) { // vertical swipe
                                                            // detection
                // top or down
                if (deltaY < 0) {
                    Log.i(logTag, "Swipe Top to Bottom");
                    mSwipeDetected = Action.TB;
                    return false;
                }
                if (deltaY > 0) {
                    Log.i(logTag, "Swipe Bottom to Top");
                    mSwipeDetected = Action.BT;
                    return false;
                }
            }
            return false;
        }
        return false;
    }
}

2do uso la clase swipe detector en la vista de lista:

    final ListView lv = getListView();
    final SwipeDetector swipeDetector = new SwipeDetector();
    lv.setOnTouchListener(swipeDetector);
    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (swipeDetector.swipeDetected()){
                    // do the onSwipe action 
                } else {
                    // do the onItemClick action
                }
            }
    });
    lv.setOnItemLongClickListener(new OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
            if (swipeDetector.swipeDetected()){
                // do the onSwipe action 
            } else {
                // do the onItemLongClick action
            }
        }
    });

De esta manera puedo soportar 3 acciones: deslizar, hacer clic, hacer clic largo y puedo usar la información del elemento ListView.

AÑADIDO MÁS TARDE:

Dado que ListView captura una acción de desplazamiento, a veces es difícil deslizar. Para arreglarlo, hice el siguiente cambio a SwipeDetector.onTouch:

public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            mSwipeDetected = Action.None;
            return false; // allow other events like Click to be processed
        }
        case MotionEvent.ACTION_MOVE: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // horizontal swipe detection
            if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) {
                // left or right
                if (deltaX < 0) {
                    Log.i(logTag, "Swipe Left to Right");
                    mSwipeDetected = Action.LR;
                    return true;
                }
                if (deltaX > 0) {
                    Log.i(logTag, "Swipe Right to Left");
                    mSwipeDetected = Action.RL;
                    return true;
                }
            } else 

            // vertical swipe detection
            if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) {
                // top or down
                if (deltaY < 0) {
                    Log.i(logTag, "Swipe Top to Bottom");
                    mSwipeDetected = Action.TB;
                    return false;
                }
                if (deltaY > 0) {
                    Log.i(logTag, "Swipe Bottom to Top");
                    mSwipeDetected = Action.BT;
                    return false;
                }
            } 
            return true;
        }
    }
    return false;
}
 116
Author: Asaf Pinhassi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-02 00:59:00

Aquí hay un fragmento que uso para detectar golpes. Entonces podría usar un viewflipper para cambiar la vista.

  @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return true;
            } else {
                return false;
            }
        }

        private static final int SWIPE_MIN_DISTANCE = 30;
        private static final int SWIPE_MAX_OFF_PATH = 250;
        private static final int SWIPE_THRESHOLD_VELOCITY = 200;
        class MyGestureDetector extends SimpleOnGestureListener {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {
                try {
                    if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                        return false;
                    // right to left swipe
                    if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        leftFling();
                    } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        rightFling();
                    }
                } catch (Exception e) {
                    // nothing
                }
                return false;
            }

        }
 1
Author: Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-04 11:50:58

Aquí hay una versión muy simplificada que utiliza los dos oyentes (onTouch para la detección de golpe y onClickIem para la detección de clic de elemento) usando la bandera isSwipe para detener el onClickItemListener hasta su confirmado que no era un swipe

Detectando el clic
teniendo en cuenta que no es un golpe primero

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
            {
                if(!isSwipe)
                {
                    adapter.increase(arg2);
                    adapter.notifyDataSetChanged();
                }
            }
        });

Detectando el golpe

        listView.setOnTouchListener(new OnTouchListener() {
        private int action_down_x = 0;
            private int action_up_x = 0;
            private int difference = 0;
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        action_down_x = (int) event.getX();
                        isSwipe=false;  //until now
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if(!isSwipe)
                        {
                            action_up_x = (int) event.getX();
                            difference = action_down_x - action_up_x;
                            if(Math.abs(difference)>50)
                            {
                                Log.d("action","action down x: "+action_down_x);
                                Log.d("action","action up x: "+action_up_x);
                                Log.d("action","difference: "+difference);
                                //swipe left or right
                                if(difference>0){
                                    //swipe left
                                    Log.d("action","swipe left");
                                    adapter.decrease(selectedItem);
                                    adapter.notifyDataSetChanged();
                                }
                                else{
                                    //swipe right
                                    Log.d("action","swipe right");
                                }
                                isSwipe=true;
                            }
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.d("action", "ACTION_UP - ");
                        action_down_x = 0;
                        action_up_x = 0;
                        difference = 0;
                        break;
                }
                return false;   //to allow the clicklistener to work after
            }
        })
 1
Author: SoliQuiD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-17 14:28:01

Si desea mostrar algunos botones con acciones cuando se desliza un elemento de la lista, hay muchas bibliotecas en Internet que tienen este comportamiento. Implementé la biblioteca que encontré en Internet y estoy muy satisfecho. Es muy simple de usar y muy rápido. Mejoré la biblioteca original y agregué un nuevo oyente de clics para hacer clic en el elemento. También he añadido fuente impresionante biblioteca ( http://fortawesome.github.io/Font-Awesome / ) y ahora simplemente puede agregar un nuevo título de elemento y especificar el nombre del icono de la fuente impresionante.

Aquí está el enlace de github

 0
Author: Popa Andrei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-24 14:34:01