Android:使用拖放重新排列视图

Android:使用拖放重新排列视图,android,android-layout,drag-and-drop,android-animation,Android,Android Layout,Drag And Drop,Android Animation,我正在尝试使用拖放重新排列视图(特别是卡片) 对于一个简单的实现,我最初的想法是通过将视图从父视图中移除,然后将其添加到左侧或右侧的点来重新定位视图 这似乎在没有动画的情况下效果很好,但一旦我开始使用动画,有时卡就会卡住。我得到一个错误: java.lang.NullPointerException:尝试从字段读取 上的“android.view.iWindows会话android.view.view$AttachInfo.mSession” 位于的空对象引用 android.view.view

我正在尝试使用拖放重新排列视图(特别是卡片)

对于一个简单的实现,我最初的想法是通过将视图从父视图中移除,然后将其添加到左侧或右侧的点来重新定位视图

这似乎在没有动画的情况下效果很好,但一旦我开始使用动画,有时卡就会卡住。我得到一个错误:

java.lang.NullPointerException:尝试从字段读取 上的“android.view.iWindows会话android.view.view$AttachInfo.mSession” 位于的空对象引用 android.view.view.startDrag(view.java:18353)位于 cz.cvut.mazelmir.cards.cards$AFragment$2.onTouch(Anagram.java:158)

我不太确定该怎么做,因为传递给
onTouch
的内容是正在触摸的视图(不应为null)和新创建的参数

关于为什么会发生这种情况,以及我能做些什么来解决它,有什么线索吗? 或者至少提供一些关于如何最好地实现此拖放功能的提示?(可能是一个简单的帧视图,我只是在其中设置了卡的动画?)

下面是包含卡片的片段的代码:(片段布局只是一个线性布局,卡片布局包含一个textview。)

公共静态类affragment扩展片段{
String s=“String”;
ViewGroup emptyContainer;
查看[]张卡片;
浮动[]cardLoc;
公共碎片{
}
@凌驾
创建视图上的公共视图(布局、充气机、最终视图组容器、,
Bundle savedInstanceState){
LinearLayout LinearLayout=(LinearLayout)充气器。充气(R.layout.fragment_anagram,container,false);
emptyContainer=null;
卡片=空;
cardLoc=null;
创建卡片(充气机、线性布局、s);
linearLayout.setOnDragListener(新视图.OnDragListener(){
@凌驾
公共布尔onDrag(视图,DrageEvent事件){
View draggedItem=(View)event.getLocalState();
ViewGroup ViewGroup=(ViewGroup)视图;
开关(event.getAction()){
案例DrageEvent.ACTION\u DRAG\u已启动:
如果(cardLoc==null)
createPositions();
emptyContainer=视图组;
draggedItem.setVisibility(View.INVISIBLE);
打破
case DragEvent.ACTION\u拖动位置:
intemptypos=(int)draggedItem.getTag(R.id.position_标记);
float currentX=event.getX();
//右边?
if(emptyPoscardLoc[emptyPos+1]){
viewGroup.removeView(卡片[emptyPos+1]);
添加视图(卡片[emptyPos+1],emptyPos);
TranslateAnimation TranslateAnimation=新的TranslateAnimation(cardLoc[emptyPos+1]-cardLoc[emptyPos],0,0,0);
translateAnimation.setDuration(200);
卡片[emptyPos+1]。开始初始化(translateAnimation);
View tempView=卡片[emptyPos+1];
卡片[emptyPos+1]=卡片[emptyPos];
卡片[emptyPos]=临时视图;
draggedItem.setTag(R.id.position_标签,emptyPos+1);
tempView.setTag(R.id.position_标签,emptyPos);
}
//左边?
else if(emptyPos>0&¤tXpublic 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();
        }
    }
}
}