2015-11-04 3 views
1

Здравствуйте, я огляделся и не смог найти четкого ответа на мою проблему. У меня есть custom adapter, BaseAdapter, что я использую в сочетании с моим ListActivity. Внутри представления для каждого элемента адаптера я хочу добавить checkbox, который, когда clicked, начинает dialog fragment с запросом у пользователя, хочет ли он удалить этот элемент. У меня возникли проблемы с созданием FragmentManager в пределах BaseAdapter. Ниже приведен мой код для участка getView от класса BaseAdapter. Редактировать: Код работает нормально. Я закончил тем, что пропустил Activity от конструктора Adapter и использовал его Activity, чтобы получить FragmentManager.Как добавить диалоговое окно Dialog в BaseAdapter?

private ArrayList<AssignmentRecord> alist = new ArrayList<AssignmentRecord>(); 

private final Context aContext; 

public AssignmentAdapter (Context context, Activity activity){ 
    aContext = context; 
    aActivity = activity; 
} 


public void addItem (AssignmentRecord item) { 
    alist.add(item); 
    notifyDataSetChanged(); 
} 

public void deleteItem (AssignmentRecord item) { 
    alist.remove(item); 
    notifyDataSetChanged(); 
} 
public View getView(int position, View convertView, ViewGroup parent) { 


    final CheckBox statusBox = (CheckBox)convertView.findViewById(R.id.adapter_finish_checkbox); 
    if (assignmentRecord.getCurrentStatus()== AssignmentRecord.Status.NOTFINISHED){ 
     statusBox.setChecked(false); 
    } else { 
     statusBox.setChecked(true); 
    } 

    statusBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

     class removeCheckedFragment extends DialogFragment{ 
      @Override 
      public Dialog onCreateDialog(Bundle savedInstanceState) { 
       // Use the Builder class for convenient dialog construction 
       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
       builder.setMessage("Do you want to remove this item?") 
         .setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           deleteItem(assignmentRecord); 
          } 
         }) 
         .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           // User cancelled the dialog 
          } 
         }); 
       // Create the AlertDialog object and return it 
       return builder.create(); 
      } 
     } 


     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (isChecked){ 
       //prompt to delete record; 

       assignmentRecord.setStatus(AssignmentRecord.Status.FINISHED); 


       FragmentManager fragManager = aActivity.getFragmentManager(); 

       removeCheckedFragment newFragment = new removeCheckedFragment(); 
       newFragment.show(fragManager, "TEST"); 


       // cancel intent for alarm manager 


      } else { 
       // do nothing 
      } 

     } 
    }); 

    return itemlayoutview; 
} 

У меня возникают проблемы при попытке создания FragmentManager. В частности, я получаю это сообщение

111-05 00:03:56.575 3839-3839/com.example.victor.listadapterexample E/AndroidRuntime﹕ FATAL EXCEPTION: main 
java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity 
     at com.example.victor.listadapterexample.AssignmentAdapter$1.onCheckedChanged(AssignmentAdapter.java:153) 
     at android.widget.CompoundButton.setChecked(CompoundButton.java:126) 
     at android.widget.CompoundButton.toggle(CompoundButton.java:87) 
     at android.widget.CompoundButton.performClick(CompoundButton.java:99) 
     at android.view.View$PerformClick.run(View.java:17721) 
     at android.os.Handler.handleCallback(Handler.java:730) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5103) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:525) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
     at dalvik.system.NativeStart.main(Native Method) 

Любая помощь будет оценена

+0

Таким образом, в этом вылетает строке 'FragmentManager fragManager = ((Activity) aContext) .getFragmentManager();'? – Nawako

+0

общий общий результат ошибки logcat –

+0

Не создавайте экземпляр адаптера с контекстом приложения. –

ответ

2

Как Eugen Pechanec гласит:

Dont экземпляр адаптера с контекста приложения.

Я добавлю немного контекста для этого ответа, хотя это имеет смысл.

Вы передаете ApplicationContext на ваш Adapter. Проблема в том, что вы пытаетесь использовать этот Context в качестве замены вашего Activity. В большинстве случаев вы, вероятно, сможете сделать это без каких-либо проблем, так как класс Activity и класс Application наследуются от класса ContextWrapper.

В вашем случае, однако, это не сработает, потому что вы пытаетесь использовать метод getFragmentManager(), который относится к классу Activity, а не классу ContextWrapper.

Есть несколько решений данной проблемы:

  1. Пропустите Activity «s Context к Adapter в конструкторе.
  2. Не создавайте и не показывайте DialogFragment прямо с вашего Adapter. Вместо этого добавьте слушателя в свой Adapter в конструкторе и вызовите его, когда вы хотите показать DialogFragment. Слушатель будет ссылаться на слушателя внутри вашего Activity.

Есть и другие решения, но я считаю, что упомянутые выше являются наиболее распространенными.

На боковой ноте: Это, как правило, считается плохой практикой использовать Application «ы Context в таких местах, как это, поскольку объем этого Context есть все приложение, и поэтому ваши Adapter на самом деле ссылки все в вашем приложении прямо сейчас - например, это может привести к утечкам памяти. Используйте как можно более узкую область.Например, если вам нужен только Context, вы также можете получить это от convertView в своем методе getView(), так как все View s имеет Context, но в гораздо более узком объеме.

Извините за длинный пост, и я надеюсь, что это помогает :-)

+0

Спасибо за подробный пост. Поэтому, если я правильно понимаю это, мне нужно передать «Activity» из моего ListActivity, чтобы вызвать 'getFragmentManager()'. Я уже передал 'Контекст'' ​​Контейна '' в конструкторе, но я не уверен, как это получает экземпляр Activity для вызова 'getFragmentManager()' – victorydub

+0

Да, это правильно - передайте 'Activity' в качестве аргумента в конструкторе «Adapter», а не «Context». Затем сохраните 'Activity' как глобальную переменную в вашем« адаптере »и используйте ее всякий раз, когда вам это нужно в' getView() '. – Darwind

+0

Спасибо! Кажется, это сработало. – victorydub

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