10
votes

Faites défiler de Android en traînant et goutte

Bonjour, j'essaie de faire une traînée et de déposer sur une liste de liste. Cela fonctionne bien. Mais j'ai perdu la capacité de cliquer et de faire défiler. Comment conserver ces deux? Je pensais que la traînée et la chute devaient arriver sur une longue pression de l'article au lieu d'une presse normale. Voici mon ONTOUCH qui est situé dans la vision de MyList qui étend à ListView

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        final int x = (int) ev.getX();
        final int y = (int) ev.getY();  

        if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) {
            this._dragMode = true;
        }

        if (!this._isDragNDrop) 
            return super.onTouchEvent(ev);

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                this._startPosition = pointToPosition(x,y);
                if (this._startPosition != INVALID_POSITION) {
                    int mItemPosition = this._startPosition - getFirstVisiblePosition();
                    this._dragPointOffset = y - getChildAt(mItemPosition).getTop();
                    this._dragPointOffset -= ((int)ev.getRawY()) - y;
                    startDrag(mItemPosition,y);
                    drag(x,y);
                }   
                break;
            case MotionEvent.ACTION_MOVE:
                drag(x,y);
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
            default:
                this._dragMode = false;
                //_isDragNDrop = false;
                this._endPosition = pointToPosition(x,y);
                stopDrag(this._startPosition - getFirstVisiblePosition());
                if (this._dropListener != null && this._startPosition != INVALID_POSITION && this._endPosition != INVALID_POSITION) 
                    this._dropListener.onDrop(this._startPosition, this._endPosition);
                break;
        }
        return true;
    }


0 commentaires

6 Réponses :


5
votes

Je viens de mettre en œuvre la liste de la liste de glisser-déposer dans mon application, le glisser commence par Appuyez longuement sur un élément.

Le code source est sur GitHub: DraggablicatView < / a>, j'ai un Blog post pour la décrire. J'espère que ça vous aide.


4 commentaires

Woah, merci beaucoup! Nous avons décidé de reporter cette fonctionnalité en raison du fait que nous n'avions pas pu le faire fonctionner. Je vais regarder cela et voir si cela résout mon problème. J'ai vu votre blog, c'est vrai que cela prendrait plus d'une semaine comme quand j'ai roulé dans deux jours avec je devais le laisser tomber :)


Grand composant! Fonctionne bien pour moi ... thx


Le lien Publier du blog ci-dessus ne fonctionne pas, mais vous pouvez trouver le reste de ce qui est nécessaire ici: codegarage.no-ip.co.uk/snippets/94


J'ai mis à jour le lien dans la réponse. Merci @mpemburn



2
votes

Découvrez ce Question pour une aide supplémentaire. J'ai également un composant appelé DragSortlistView que j'ai passé beaucoup de temps à affiner. Vous pouvez le trouver ici:


1 commentaires

Bibliothèque cool :)



3
votes

Je suis en train de mettre en œuvre quelque chose de similiaire. J'espère que cela aidera quelqu'un d'autre comme je saute toujours sur les kinks.

...
thumb.setOnDragListener(new Drag());
...

public class Drag implements OnDragListener{
public static int PositionOfDraggedItem = -1;
      public int PositionOfItemDraggedOver = -1;

public Drag() {}

@Override
public boolean onDrag(View v, DragEvent event)
{
    final int action = event.getAction();
    boolean state = true;

    View root = v.getRootView();
    ListView List = (ListView) root.findViewById(android.R.id.list);
    Object holder = v.getTag() instanceof OrderHolder? (OrderHolder)v.getTag() : v.getTag();

    String BookId = holder instanceof OrderHolder? String.valueOf(((OrderHolder)holder).id) : (String)holder;

    switch(action)
    {
        case DragEvent.ACTION_DRAG_STARTED:

            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            if( PositionOfDraggedItem != -1 )
            {
                if( this.PositionOfItemDraggedOver != PositionOfDraggedItem )
                {
                    if( v.getBackground() != null )
                        v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row_ovr));
                }
            }
            break;
        case DragEvent.ACTION_DRAG_LOCATION:
            /**
             * Set the item being
             * here, as it will not
             * provide location data
             * anywhere else
             */
            if( PositionOfDraggedItem == -1 )
                PositionOfDraggedItem = List.getPositionForView(v);

            /**
             * Set the view thats
             * being dragged over
             */
            this.PositionOfItemDraggedOver = List.getPositionForView(v);

            int PositionOfLastVisibleView = List.getLastVisiblePosition();
            int PositionOfFirstVisibleView = List.getFirstVisiblePosition();

            if( this.PositionOfItemDraggedOver != -1 && ( this.PositionOfItemDraggedOver != PositionOfDraggedItem ) ){
                if( this.PositionOfItemDraggedOver == PositionOfLastVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfLastVisibleView || this.PositionOfItemDraggedOver == PositionOfLastVisibleView+1 ){
                    List.smoothScrollToPosition(PositionOfLastVisibleView+1);
                }else if( this.PositionOfItemDraggedOver == PositionOfFirstVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView+1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView ){
                    List.smoothScrollToPosition(PositionOfFirstVisibleView-1);
                }
            }
            break;
        case DragEvent.ACTION_DRAG_EXITED:
            if( v.getBackground() != null )
                v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row));
            break;
        case DragEvent.ACTION_DROP:
            if(event != null)
            {
                ClipData data = event.getClipData();
                if( data != null && data.getItemCount() > 0 )
                {
                    if( !data.getItemAt(0).getText().toString().equalsIgnoreCase(BookId) )
                    {
                        if( v.getBackground() != null )
                            v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row));
                        /**
                         * Ordering info for
                         * book being dragged
                         */
                        String oShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER, 
                                booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString()));
                        String oBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER, 
                                booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString()));

                        /**
                         * Ordering info
                         * for book being dragged
                         * to
                         */
                        String dShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER, 
                                booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId));
                        String dBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER, 
                                booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId));

                        /**
                         * Update book being dragged
                         */
                        ContentValues args = new ContentValues();
                        args.put(dbhelper.BOOKS_SHELFORDER, dShelfOrder);
                        args.put(dbhelper.BOOKS_BOOKSORDER, dBookOrder);
                        BookManager.updateBook(v.getContext().getContentResolver(), data.getItemAt(0).getText().toString(), args);

                        /**
                         * Update book being dragged to
                         */
                        ContentValues values = new ContentValues();
                        values.put(dbhelper.BOOKS_SHELFORDER, oShelfOrder);
                        values.put(dbhelper.BOOKS_BOOKSORDER, oBookOrder);
                        BookManager.updateBook(v.getContext().getContentResolver(), BookId, values);

                        if( v.getContext() instanceof OrderBooks ){
                            ((OrderBooks)v.getContext()).adapter.refresh();
                            ((OrderBooks)v.getContext()).adapter.notifyDataSetChanged();

                            PositionOfDraggedItem = -1;
                        }
                    }
                }
            }
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            if( event != null && event.getResult())
            {
                v.invalidate();
            }
            break;
    }
    return state;
}


2 commentaires

SmoothscrollTopImposition démarrera une animatrice de Scroller à chaque fois, et je pense que le meilleur est de poster un smoothscrolltoposition (montant, linéaire) tous les 1 seconde, mais cette méthode n'est pas publique ou protégée ...


Cette solution fait défiler parfaitement, cependant, les draglisteners de vues de la liste qui n'étaient pas visibles avant le défilement ne réagissent pas tout en faisant glisser. Lorsque je fais glisser un objet à la zone inférieure de la liste de réception, il fait défiler la baisse, mais le draglistener sur les vues visibles par défilement ne reçoivent aucun événement. Ils travaillent comme d'habitude quand je peux les atteindre sans faire défiler. Avez-vous eu une solution pour cela?



1
votes

J'ai mis en œuvre cette solution qui fonctionne pour moi. La méthode suivante est dans mon activité et on l'appelle dans mon drageventListener lorsque la drague provient Action_DRAG_Entered. Certains attributs que j'ai déclarés: xxx

... xxx

espère que cela aidera quelqu'un.


0 commentaires

-1
votes

Il, il m'a fait peu changé dans le code de Rickey et c'est un travail pour moi. XXX


0 commentaires

0
votes

in kotlin: xxx


0 commentaires