【问题标题】:java.lang.ClassCastException: android.view.View cannot be cast to android.view.ViewGroupjava.lang.ClassCastException: android.view.View 不能转换为 android.view.ViewGroup
【发布时间】:2014-01-09 07:10:54
【问题描述】:

我现在正在执行拖放操作。在此操作中,允许从相对布局拖动到另一个布局。如果布局中有一个孩子并且另一个图像被拖动到​​它,则图像必须交换位置。当我将视图投射到视图组时,这是我的问题,发生类投射异常。我真的不知道如何解决它,因为我是 android 新手。 log cat 中的错误行指向此 ((ViewGroup)parent).addView(nextChild)。请给我建议。对不起,如果我的问题打扰了您。

这是我的日志猫输出:

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;
    }
}

【问题讨论】:

  • 发布 logcat 输出
  • 您是否尝试过将变量 v 更改为 ViewGroup 而不是 View ?
  • @san 。这是覆盖方法。我认为它不能改变。
  • @Hardik >> 已发布

标签: java android drag-and-drop


【解决方案1】:

ViewGroup 与视图投射

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

}

实例

同时避免检查 ClassString.equals(String):boolean 的名称,就像您在下面的 sn-p 中所做的那样。

在你的情况下,这甚至会失败,因为前面的“类”不会成为结果的一部分。

if(v.getClass().toString().equals("class android.widget.RelativeLayout")){

在 Java 中检查 Object 类型的正确方法是使用 isntanceof,就像我在下面的代码中所做的那样。

if( v instanceof android.widget.RelativeLayout ){

有关 instanceof 的更多信息,请访问 this StackOverflow question

【讨论】:

  • 当我添加“parent.addView(nextChild)”时它要求我输入 cast parent
  • 好的,我明白了,addView 确实只适用于 ViewGroup,我会更新代码
  • 感谢您的帮助
  • 那么您认为 v 和 parent 都是 ViewGroup 吗?我会再更新一些代码,所以我们先检查一下
  • 真的很感谢它的工作。它解决了问题。真的非常感谢:D
【解决方案2】:

少做强制转换,使用 instanceof 来检查类型。

if(v instanceof ViewGroup){
    ViewGroup vg = (ViewGroup)v;

    // TODO your code that needs a ViewGroup.
}

【讨论】:

    【解决方案3】:

    问题在这里 if(((ViewGroup)v).getChildCount()!=0)View nextChild = ((ViewGroup)v).getChildAt(0);

    删除强制转换并尝试这种方式if(v.getChildCount()!=0)

    【讨论】:

    • 我看不到 getChildCount() for view 。 :(
    • 那是因为 getChildCount() 是 ViewGroup 的一个方法。
    【解决方案4】:

    ViewViewGroup 的父级,因此您不能键入 cast ViewGroup,它是 View 的父级的子级。这就是它抛出 ClassCastException 的原因。

    【讨论】:

      猜你喜欢
      • 2017-10-02
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多