附加到片段的片段对话框不调用 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() 方法似乎没有被调用,我想。有人知道为什么吗? 这是 FragmentDialogClass

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;
        
    

这是 FragmentClass,它将打开 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 方法的主要内容,如果未能解决你的问题,请参考以下文章

片段未附加到我的活动

片段事务分离和附加后ListView不工作?

多次调用片段 onCreateView

片段未附加到相应的片段

android如何跨片段分离/附加保留视图状态

何时片段不附加到活动而仅附加到上下文?