如何在 BaseAdapter 中添加 DialogFragment?

How to add a DialogFragment in BaseAdapter?

您好,我环顾四周,没能为我的问题找到明确的答案。我有一个 custom adapterBaseAdapter,我正在与我的 ListActivity 一起使用。在每个适配器项目的视图中,我想添加一个 checkbox,当 clicked 时,启动一个 dialog fragment 询问用户是否要删除该项目。我在从 BaseAdapter 中创建 FragmentManager 时遇到问题。下面是 BaseAdapter class 中 getView 部分的代码。 编辑:代码现在运行良好。我最终从 Adapter 的构造函数中传递了 Activity 并使用 Activity 获得了 FragmentManager.

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.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)

如有任何帮助,我们将不胜感激

正如 Eugen Pechanec 所说:

Dont instantiate the adapter with application context.

我会为这个答案添加一些上下文,这样它更有意义。

您正在将 ApplicationContext 传递给您的 Adapter。问题是您正在尝试使用此 Context 来替代您的 Activity。在大多数情况下,您可能能够毫无问题地执行此操作,因为 Activity class 和 Application class 都继承自 ContextWrapper class.

然而,在您的情况下,这将不起作用,因为您正在尝试使用属于 Activity class 而不是 [=17] 的方法 getFragmentManager() =] class.

这个问题有多种解决方案:

  1. ActivityContext 传递给构造函数中的 Adapter
  2. 不要直接从您的 Adapter 创建和显示 DialogFragment。而是在构造函数中向 Adapter 添加一个侦听器,并在您想要显示 DialogFragment 时调用该侦听器。侦听器将在您的 Activity.
  3. 中引用一个侦听器

还有其他解决方案,但我相信提到的是最常见的。

旁注:在这样的地方使用 ApplicationContext 通常被认为是不好的做法,因为 Context 的范围是整个应用程序,因此您的 Adapter 实际上现在引用了您应用中的所有内容 - 例如,这可能会导致内存泄漏。 使用尽可能窄的范围。例如,如果您只需要一个 Context,您也可以在 getView() 方法中从 convertView 获取它,因为所有 View 都有一个 Context,但是在范围更窄。

抱歉这么久了 post 希望对您有所帮助 :-)