2014-01-09 4 views
2

Теперь я реализую операцию перетаскивания. В этой операции разрешено перетаскивание из относительного макета в пыльник. Если в макете есть ребенок, а другое изображение перетаскивается, изображения должны обмениваться положением. Вот моя проблема, когда я бросаю представление для просмотра группы, возникает исключение класса. Я действительно не знаю, как это решить, поскольку я новичок в андроиде. Строка ошибки в log cat указывает на это родительское (ViewGroup) .addView (nextChild). Пожалуйста, дайте мне совет. Извините, если мой вопрос вас беспокоит.java.lang.ClassCastException: android.view.View не может быть добавлено в android.view.ViewGroup

Это мой выход журнала кошка:

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

Опубликовать логический вывод – Hardik

+0

Вы пытались сменить переменную v на ViewGroup вместо View? – San

+0

@ san. Это метод переопределения. Я думаю, что это не может быть изменено. –

ответ

3

ViewGroup против Вида литья

ViewGroup также View (расширяет View), поэтому вместо литья в ViewGroup держать их в качестве View объектов и только гипса, когда действительно необходимо (то есть при обращении к методам, которые Арен 't доступно в 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 

} 

InstanceOf

избежать Также проверки имя Class с String.equals(String):boolean, как вы делали в приведенном ниже фрагменте кода.

В вашем случае это может даже потерпеть неудачу, поскольку «класс» впереди не будет частью результата.

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

Правильный способ проверить тип в Object в Java, чтобы использовать isntanceof, как я сделал в коде ниже.

if(v instanceof android.widget.RelativeLayout){ 

Дополнительную информацию о instanceof можно найти на странице this StackOverflow question.

+0

попросил меня набрать родительский элемент при добавлении «parent.addView (nextChild)» –

+0

Хорошо, я вижу, addView для ViewGroup, действительно, я обновлю код – hcpl

+0

Спасибо, что помогли мне –

0

проблема здесь if(((ViewGroup)v).getChildCount()!=0) и View nextChild = ((ViewGroup)v).getChildAt(0);

отливка удалить и попробовать этот путь if(v.getChildCount()!=0)

+0

Я не вижу getChildCount() для просмотра.:( –

+0

Thats cause getChildCount() - метод ViewGroup. – San

1

Сделайте меньше литья и использования чтобы проверить тип.

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

    // TODO your code that needs a ViewGroup. 
} 
0

Посмотреть является родителем ViewGroup и поэтому вы не можете набрать произнесения ViewGroup, ребенок к своему родителю, который является видом. Именно поэтому он бросает ClassCastException.

Смежные вопросы