如何在 BaseAdapter 中添加 DialogFragment?
How to add a DialogFragment in BaseAdapter?
您好,我环顾四周,没能为我的问题找到明确的答案。我有一个 custom adapter
、BaseAdapter
,我正在与我的 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.
我会为这个答案添加一些上下文,这样它更有意义。
您正在将 Application
的 Context
传递给您的 Adapter
。问题是您正在尝试使用此 Context
来替代您的 Activity
。在大多数情况下,您可能能够毫无问题地执行此操作,因为 Activity
class 和 Application
class 都继承自 ContextWrapper
class.
然而,在您的情况下,这将不起作用,因为您正在尝试使用属于 Activity
class 而不是 [=17] 的方法 getFragmentManager()
=] class.
这个问题有多种解决方案:
- 将
Activity
的 Context
传递给构造函数中的 Adapter
。
- 不要直接从您的
Adapter
创建和显示 DialogFragment
。而是在构造函数中向 Adapter
添加一个侦听器,并在您想要显示 DialogFragment
时调用该侦听器。侦听器将在您的 Activity
. 中引用一个侦听器
还有其他解决方案,但我相信提到的是最常见的。
旁注:在这样的地方使用 Application
的 Context
通常被认为是不好的做法,因为 Context
的范围是整个应用程序,因此您的 Adapter
实际上现在引用了您应用中的所有内容 - 例如,这可能会导致内存泄漏。
使用尽可能窄的范围。例如,如果您只需要一个 Context
,您也可以在 getView()
方法中从 convertView
获取它,因为所有 View
都有一个 Context
,但是在范围更窄。
抱歉这么久了 post 希望对您有所帮助 :-)
您好,我环顾四周,没能为我的问题找到明确的答案。我有一个 custom adapter
、BaseAdapter
,我正在与我的 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.
我会为这个答案添加一些上下文,这样它更有意义。
您正在将 Application
的 Context
传递给您的 Adapter
。问题是您正在尝试使用此 Context
来替代您的 Activity
。在大多数情况下,您可能能够毫无问题地执行此操作,因为 Activity
class 和 Application
class 都继承自 ContextWrapper
class.
然而,在您的情况下,这将不起作用,因为您正在尝试使用属于 Activity
class 而不是 [=17] 的方法 getFragmentManager()
=] class.
这个问题有多种解决方案:
- 将
Activity
的Context
传递给构造函数中的Adapter
。 - 不要直接从您的
Adapter
创建和显示DialogFragment
。而是在构造函数中向Adapter
添加一个侦听器,并在您想要显示DialogFragment
时调用该侦听器。侦听器将在您的Activity
. 中引用一个侦听器
还有其他解决方案,但我相信提到的是最常见的。
旁注:在这样的地方使用 Application
的 Context
通常被认为是不好的做法,因为 Context
的范围是整个应用程序,因此您的 Adapter
实际上现在引用了您应用中的所有内容 - 例如,这可能会导致内存泄漏。
使用尽可能窄的范围。例如,如果您只需要一个 Context
,您也可以在 getView()
方法中从 convertView
获取它,因为所有 View
都有一个 Context
,但是在范围更窄。
抱歉这么久了 post 希望对您有所帮助 :-)