附加到片段的片段对话框不调用 onYes/No 方法
Posted
技术标签:
【中文标题】附加到片段的片段对话框不调用 onYes/No 方法【英文标题】:Fragment Dialog attached to a Fragment doesn't call onYes/No method 【发布时间】:2014-07-07 16:17:52 【问题描述】:FIRST:我不需要关于如何创建和显示对话框的课程,请阅读我写的所有内容。
我有一个问题,这是我的第一个问题。我有一个带有主活动的应用程序,左侧有一个抽屉,当我单击一个项目时,它会在主要内容中显示一个 Fragment。一个片段让我在 SQLite 数据库中添加一个星球。然后另一个 Fragment 向我显示了一个包含我在数据库中插入的行星的列表。单击其中一个,将出现一个 FragmentDialog 并询问我是否要删除该星球:如果是,请删除它,如果不是,则不执行任何操作。 onYes() 方法似乎没有被调用,我想。有人知道为什么吗? 这是 FragmentDialog 的 Class:
public class FragmentDialog extends DialogFragment
private IFragmentDialog mListener;
public static FragmentDialog getInstance()
return new FragmentDialog();
public interface IFragmentDialog
public void onYes();
public void onNo();
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
AlertDialog.Builder vDialogBuilder = new AlertDialog.Builder(getActivity());
vDialogBuilder.setTitle("Attenzione");
vDialogBuilder.setMessage("Vuoi cancellare questo elemento?");
vDialogBuilder.setPositiveButton("Sì", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
if (mListener != null)
mListener.onYes();
);
vDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
if (mListener != null)
mListener.onNo();
);
return vDialogBuilder.create();
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
if (activity instanceof IFragmentDialog)
mListener = (IFragmentDialog) activity;
这是 Fragment 的 Class,它将打开 FragmentDialog:
public class FragmentPlanetList extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, IFragmentDialog
ListView mListView;
PlanetCursorAdapter mCursorAdapter;
private ILoadFragment mListener;
public static Uri uri = null;
private static final int PLANET_LOADER_ID = 0;
public static FragmentPlanetList getInstance()
return new FragmentPlanetList();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View vView = inflater.inflate(R.layout.fragment_planet_list, container, false);
getActivity().setTitle(R.string.fragment_planet_list);
mListView = (ListView) vView.findViewById(R.id.planet_list);
mCursorAdapter = new PlanetCursorAdapter(getActivity().getApplicationContext(), null, 0);
mListView.setAdapter(mCursorAdapter);
getLoaderManager().initLoader(PLANET_LOADER_ID, null, this);
mListView.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
uri = Uri.parse(PlanetProvider.PLANETS_URI + "/" + id);
// getActivity().getContentResolver().delete(uri, null, null); Toast.makeText(getActivity(), "Cancellato ID" + id, Toast.LENGTH_SHORT).show();
showDialog();
);
return vView;
protected void showDialog()
FragmentDialog vDialog = FragmentDialog.getInstance();
vDialog.show(getFragmentManager(), "SHOW_DIALOG");
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
if (activity instanceof ILoadFragment)
mListener = (ILoadFragment) activity;
@Override
public void onYes()
// not called
Toast.makeText(getActivity(), "A", Toast.LENGTH_LONG).show();
// getActivity().getContentResolver().delete(uri, null, null);
@Override
public void onNo()
编辑:我认为问题在于(如OrhanC1 所说)onAttach() 方法中的 if。我是否也要在我的 Activity 中实现 FragmentDialog 接口?如果是这样,我如何传递列表项的位置和要删除的 uri?
【问题讨论】:
考虑将您的代码缩减为您能想出的能够重现问题的最短示例。会发生两件好事:1)人们将更有可能阅读所有内容,2)创建一个简短示例的练习可能会很好地引导您找到问题。 我认为是if (activity instanceof ILoadFragment)
导致了这个问题。请在 if 语句中添加Log.d("test", "In IF");
并检查 logcat
Logcat中没有Log.d。
如果您只想显示一个带有 yes 和 no 选项的对话框。看到我在这里***.com/questions/11111796/android-show-custom-dialog/…
显示对话框,但未调用接口内的方法。
【参考方案1】:
创建一个对话框处理程序
public class DialogHandler
public Runnable ans_true = null;
public Runnable ans_false = null;
// Dialog. --------------------------------------------------------------
public boolean Confirm(Activity act, String Title, String ConfirmText,
String CancelBtn, String OkBtn, Runnable aProcedure, Runnable bProcedure)
ans_true = aProcedure;
ans_false= bProcedure;
AlertDialog dialog = new AlertDialog.Builder(act).create();
dialog.setTitle(Title);
dialog.setMessage(ConfirmText);
dialog.setCancelable(false);
dialog.setButton(DialogInterface.BUTTON_POSITIVE, OkBtn,
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int buttonId)
ans_true.run();
);
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, CancelBtn,
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int buttonId)
ans_false.run();
);
dialog.setIcon(android.R.drawable.ic_dialog_alert);
dialog.show();
return true;
如何称它为另一个活动
public class YourActivity extends Activity
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button1).setOnClickListener(myclick);
public final Button.OnClickListener myclick = new Button.OnClickListener()
@Override
public void onClick(View v)
doclick();
;
public void doclick()
DialogHandler appdialog = new DialogHandler();
boolean dlg = appdialog.Confirm(this, "Message title", "Message content",
"Cancel", "OK", aproc(), bproc());
public Runnable aproc()
return new Runnable()
public void run()
Log.d("Test", "This from A proc");
;
public Runnable bproc()
return new Runnable()
public void run()
Log.d("Test", "This from B proc");
;
【讨论】:
而不是 appdialog.Confirm(this 。你必须通过 appdialog.Confirm(getActivity while using Fragments 我需要使用 FragmentDialog,而不是其他类型的 Dialog。此外,我在我的应用程序中只使用了一个 Activity 和一些 Fragments。 为什么你只需要使用 FragmentDialog 而这个对话框也可以做你需要的事情 因为如果我旋转设备,FragmentDialog 也会保持活动状态,并且因为我的老师告诉我 FragmentDialogs 更适合编程。【参考方案2】:DialogFragment 实际上只是一个包装对话框的片段。您可以通过在 DialogFragment 的 onCreateDialog() 方法中创建并返回对话框,将任何类型的对话框放入其中。
在 onCreateDialog() 中使用任意数量的按钮创建自定义对话框; 在给定的代码中,ok 是禁用的,您可以通过将代码复制为 setNegativeButton Do 来启用它。
将 null 替换为新的 DialogInterface blah blah 。如果你喜欢
这是一个示例 DialogFragment:
class MyDialogFragment extends DialogFragment
Context mContext;
public MyDialogFragment()
mContext = getActivity();
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
alertDialogBuilder.setTitle("Really?");
alertDialogBuilder.setMessage("Are you sure?");
//null should be your on click listener
alertDialogBuilder.setPositiveButton("OK", null);
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.dismiss();
);
return alertDialogBuilder.create();
创建对话调用:
new MyDialogFragment().show(getFragmentManager(), "MyDialog");
并从某处关闭对话框:
((MyDialogFragment)getFragmentManager().findFragmentByTag("MyDialog")).getDialog().dismiss();
只需更改导入以使用支持库类,所有这些代码都将与支持库完美配合。
【讨论】:
我编辑了问题,请仔细阅读。问题不是显示对话框,而是调用方法。方法没有调用!以上是关于附加到片段的片段对话框不调用 onYes/No 方法的主要内容,如果未能解决你的问题,请参考以下文章