Android: reorder views using drag and drop

I am trying to rearrange views (specifically maps) using drag-and-drop.

My initial thought for a simple implementation is to move the view by removing it from the parent and then adding it to the spot on the left or right.

This seems to work fine without animation, but once I start using animation, sometimes the cards get stuck. I am getting the error:

java.lang.NullPointerException: Attempting to read from field 'android.view.IWindowSession android.view.View $ AttachInfo.mSession' on null object reference in android.view.View.startDrag (View.java:18353) at cz.cvut .mazelmir.cards.Cards $ AFragment $ 2.onTouch (Anagram.java:158)

I'm not really sure what to do with this, as the things passed to onTouch

are touch the view (shouldn't be null) and the newly created parameters.

Are there any clues as to why this is happening and what I can do to fix it? Or at least some hints on how best to implement this drag and drop functionality? (Possibly a simple frame view where I just animated the cards?)

Here's the code for the snippet containing the maps: (The slice layout is just a linear layout, and the map layout contains a text image.)

public static class AFragment extends Fragment {

    String s = "string";
    ViewGroup emptyContainer;
    View[] cards;
    float[] cardLoc;

    public AFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {
        LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.fragment_anagram, container, false);
        emptyContainer = null;
        cards = null;
        cardLoc = null;

        createCards(inflater, linearLayout, s);

        linearLayout.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View view, DragEvent event) {
                View draggedItem = (View) event.getLocalState();
                ViewGroup viewGroup = (ViewGroup) view;
                switch (event.getAction()) {
                    case DragEvent.ACTION_DRAG_STARTED:
                        if (cardLoc == null)
                            createPositions();
                        emptyContainer = viewGroup;
                        draggedItem.setVisibility(View.INVISIBLE);
                        break;
                    case DragEvent.ACTION_DRAG_LOCATION:
                        int emptyPos = (int)draggedItem.getTag(R.id.position_tag);
                        float currentX = event.getX();

                        // To the right?
                        if (emptyPos < cardLoc.length - 1 && currentX > cardLoc[emptyPos + 1]) {
                            viewGroup.removeView(cards[emptyPos + 1]);
                            viewGroup.addView(cards[emptyPos + 1], emptyPos);

                            TranslateAnimation translateAnimation = new TranslateAnimation(cardLoc[emptyPos + 1] - cardLoc[emptyPos], 0, 0, 0);
                            translateAnimation.setDuration(200);
                            cards[emptyPos + 1].startAnimation(translateAnimation);

                            View tempView = cards[emptyPos + 1];
                            cards[emptyPos + 1] = cards[emptyPos];
                            cards[emptyPos] = tempView;

                            draggedItem.setTag(R.id.position_tag, emptyPos + 1);
                            tempView.setTag(R.id.position_tag, emptyPos);
                        }
                        // To the left?
                        else if (emptyPos > 0 && currentX < cardLoc[emptyPos]) {
                            viewGroup.removeView(cards[emptyPos - 1]);
                            viewGroup.addView(cards[emptyPos - 1], emptyPos);

                            TranslateAnimation translateAnimation = new TranslateAnimation(cardLoc[emptyPos - 1] - cardLoc[emptyPos], 0, 0, 0);
                            translateAnimation.setDuration(200);
                            cards[emptyPos - 1].startAnimation(translateAnimation);

                            View tempView = cards[emptyPos - 1];
                            cards[emptyPos - 1] = cards[emptyPos];
                            cards[emptyPos] = tempView;

                            draggedItem.setTag(R.id.position_tag, emptyPos - 1);
                            tempView.setTag(R.id.position_tag, emptyPos);
                        }

                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        draggedItem.setVisibility(View.VISIBLE);
                        break;
                    default:
                        break;
                }
                return true;
            }
        });

        return linearLayout;
    }

    private void createCards(LayoutInflater inflater, LinearLayout container, String s) {
        cards = new View[s.length()];
        int j = 0;
        for (char c : s.toCharArray()) {
            String letter = String.valueOf(c);

            View letterCard = inflater.inflate(R.layout.letter_container, container, false);
            TextView letterTextView = (TextView) letterCard.findViewById(R.id.letter_text);
            letterTextView.setText(letter);
            letterCard.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        ClipData data = ClipData.newPlainText("", "");
                        View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
                        v.startDrag(data, shadowBuilder, v, 0);
                        return true;
                    }
                    return false;
                }
            });
            cards[j] = letterCard;
            container.addView(letterCard);

            letterCard.setTag(R.id.position_tag, j);
            letterCard.setTag(R.id.letter_tag, letter);

            j++;
        }
    }

    public void createPositions() {
        cardLoc = new float[cards.length];
        for (int i = 0; i < cards.length; i++) {
            cardLoc[i] = cards[i].getX();
        }
    }
}
}

      

+3
android android-layout drag-and-drop android-animation


source to share


No one has answered this question yet

Check out similar questions:

3606
Close / hide Android soft keyboard
3295
Why is the Android emulator so slow? How can we speed up the development of an Android emulator?
3288
Correct use cases for Android UserManager.isUserAGoat ()?
2609
Is there a unique identifier for an Android device?
2510
How to persist android activity state by persisting instance state?
2097
Is there a way to run Python on Android?
1844
What is "Context" on Android?
1152
Difference between gravity and layout_gravity on Android
286
Update ViewPager dynamically?
1
throwing null pointer with listview.setadapter () in fragment in oncreateview method



All Articles
Loading...
X
Show
Funny
Dev
Pics