我现在正在实施拖放操作。在此操作中,允许从相对布局拖动到另一个布局。如果布局中有一个孩子并且拖动另一个图像,则图像必须交换位置。这是我的问题,当我转换视图组,发生类强制转换异常。我真的不知道怎么解决它,因为我是android的新手。 log cat的错误行指向此((ViewGroup)父级).addView(nextChild)。请给我建议。对不起,如果我的问题打扰你。
这是我的Log cat输出:
01-09 01:57:27.829: E/AndroidRuntime(2021): FATAL EXCEPTION: main
01-09 01:57:27.829: E/AndroidRuntime(2021): Process: com.example.barnyar, PID: 2021
01-09 01:57:27.829: E/AndroidRuntime(2021): java.lang.ClassCastException: android.view.View cannot be cast to android.view.ViewGroup
01-09 01:57:27.829: E/AndroidRuntime(2021): at com.example.barnyar.MainActivity$MyDragListener.onDrag(MainActivity.java:751)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.View.dispatchDragEvent(View.java:17371)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1300)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1286)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1286)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1286)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1286)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1286)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:5026)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewRootImpl.access$800(ViewRootImpl.java:96)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3213)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.os.Handler.dispatchMessage(Handler.java:102)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.os.Looper.loop(Looper.java:136)
01-09 01:57:27.829: E/AndroidRuntime(2021): at android.app.ActivityThread.main(ActivityThread.java:5017)
01-09 01:57:27.829: E/AndroidRuntime(2021): at java.lang.reflect.Method.invokeNative(Native Method)
01-09 01:57:27.829: E/AndroidRuntime(2021): at java.lang.reflect.Method.invoke(Method.java:515)
01-09 01:57:27.829: E/AndroidRuntime(2021): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-09 01:57:27.829: E/AndroidRuntime(2021): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-09 01:57:27.829: E/AndroidRuntime(2021): at dalvik.system.NativeStart.main(Native Method)
这是我的代码:
@Override
public boolean onDrag(View v, DragEvent event) {
View parent = new View(MainActivity.this);
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
Toast.makeText(getApplicationContext(), "Start Drag ", Toast.LENGTH_LONG).show();
parent = v;
Log.i("class",parent+"");
break;
case DragEvent.ACTION_DRAG_ENTERED:
v.setBackground(normalShape); //change the shape of the view
break;
case DragEvent.ACTION_DRAG_EXITED:
v.setBackground(normalShape); //change the shape of the view back to normal
break;
case DragEvent.ACTION_DROP:
if(v.getClass().toString().equals("class android.widget.RelativeLayout")){
Log.i("class","Relative");
if(((ViewGroup)v).getChildCount()!=0){
View nextChild = ((ViewGroup)v).getChildAt(0);
Log.i("child",((ViewGroup)v).getChildCount()+"");
((ViewGroup)parent).addView(nextChild);//the error line
View view = (View) event.getLocalState();
ViewGroup viewgroup = (ViewGroup) view.getParent();
viewgroup.removeView(view);
RelativeLayout containView = (RelativeLayout) v;
containView.addView(view);
view.setVisibility(View.VISIBLE);
}
else {
View view = (View) event.getLocalState();
ViewGroup viewgroup = (ViewGroup) view.getParent();
viewgroup.removeView(view);
RelativeLayout containView = (RelativeLayout) v;
containView.addView(view);
view.setVisibility(View.VISIBLE);
}
}
else {
Log.i("CLass", v.getClass()+"Cant drop");
View view = (View) event.getLocalState();
view.setVisibility(View.VISIBLE);
break;
}
break;
case DragEvent.ACTION_DRAG_ENDED:
v.setBackground(normalShape); //go back to normal shape
default:
break;
}
return true;
}
}
答案 0 :(得分:3)
ViewGroup
也是View
(扩展View
),因此不是强制转换为ViewGroup
,而是将它们保留为View
个对象,并且仅在真正需要时投射(即访问View
中不可用的方法时,仅在ViewGroup
中)。
// childCount is for ViewGroup only, if problem still occurs you can
// check first if v object really is a ViewGroup instance with the
// below instanceof check
if( v instanceof ViewGroup && parent instanceof ViewGroup && ((ViewGroup)v).getChildCount()!=0 ){
// perform the cast only once, also now we know it's safe thanks to the instanceof
ViewGroup vg = (ViewGroup)v
View nextChild = vg.getChildAt(0);
Log.i("child", vg.getChildCount()+"");
// no guarantee here whatever that parent is a more specific ViewGroup
// so if we need this to be a ViewGroup we'll have to cast but check
// with instanceof first
((ViewGroup)parent).addView(nextChild); //this was the error line
View view = (View) event.getLocalState();
ViewGroup viewgroup = (ViewGroup) view.getParent();
viewgroup.removeView(view);
RelativeLayout containView = (RelativeLayout) v;
containView.addView(view);
view.setVisibility(View.VISIBLE);
} else {
// PERFORM SOME LOGGING HERE
// so you know what views got dropped in here that didn't match your requirements in the first place
// TODO
}
同时避免使用Class
检查String.equals(String):boolean
的名称,就像您在下面的代码段中所做的那样。
在你的情况下,这甚至会失败,因为前面的“类”不会成为结果的一部分。
if(v.getClass().toString().equals("class android.widget.RelativeLayout")){
检查Java中Object
类型的正确方法是使用isntanceof
,就像我在下面的代码中所做的那样。
if( v instanceof android.widget.RelativeLayout ){
有关instanceof的更多信息,请访问this StackOverflow question。
答案 1 :(得分:1)
少投射并使用instanceof来检查类型。
if(v instanceof ViewGroup){
ViewGroup vg = (ViewGroup)v;
// TODO your code that needs a ViewGroup.
}
答案 2 :(得分:0)
问题出在if(((ViewGroup)v).getChildCount()!=0)
和View nextChild = ((ViewGroup)v).getChildAt(0);
删除广告并尝试if(v.getChildCount()!=0)
答案 3 :(得分:0)
查看是 ViewGroup 的父级,因此您无法输入转换ViewGroup,即子视图的父级视图。这就是它抛出ClassCastException的原因。