Android:使用拖放重新排列视图
我正在尝试使用拖放重新排列视图(特别是卡片) 对于一个简单的实现,我最初的想法是通过将视图从父视图中移除,然后将其添加到左侧或右侧的点来重新定位视图 这似乎在没有动画的情况下效果很好,但一旦我开始使用动画,有时卡就会卡住。我得到一个错误: 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) 我不太确定该怎么做,因为传递给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
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();
}
}
}
}