我该如何做模态对话框片段(代码在我关闭之前不会执行)

Posted

技术标签:

【中文标题】我该如何做模态对话框片段(代码在我关闭之前不会执行)【英文标题】:How can I do Modal DialogFragment (code does not execute til I close it) 【发布时间】:2013-12-28 19:03:06 【问题描述】:

我有一个在应用程序第一次运行时弹出指令的活动(在 DialogFragment 中)。

我想在用户不关闭对话框时停止执行代码。

可以吗???

编辑: 我尝试使用 CountDownLatch,但它冻结了我的 UI,并且对话框没有显示。

活动:

private CountDownLatch startSignal;
@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // open tutorial if need
    startSignal = new CountDownLatch(1);
        TutorialDialog tutoDial = new TutorialDialog();
    tutoDial.show(getSupportFragmentManager(), "tuto");
    try 
        toast("aguardando");
        startSignal.await();
     catch (InterruptedException e) 
        e.printStackTrace();
    

对话框(我只是放了需要的方法):

公共类 TutorialDialog 扩展 DialogFragment private final String TAG = getClass().getSimpleName(); 地图活动父活动; SharedPreferences 首选项;

@Override
public void onAttach(Activity activity) 
    super.onAttach(activity);
    parentActivity = ((MapActivity) activity);


@Override
public Dialog onCreateDialog(Bundle savedInstanceState) 
//      setStyle(DialogFragment.STYLE_NORMAL, 0);
    AlertDialog.Builder principal = new AlertDialog.Builder(getActivity());
    principal.setInverseBackgroundForced(true);
//      principal.setTitle(R.string.report);
    View view = getActivity().getLayoutInflater().inflate(
            R.layout.tutorial, null);
    TextView ok = (TextView)view.findViewById(R.id.ok);


    ok.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            parentActivity.resumeCode();  
            dismiss();
        
    );
    AlertDialog ad = principal.create();
    return ad;


而在Activity中,方法resumeCode():

公共无效恢复代码() startSignal.countDown(); 吐司(“接下来是什么”);

编辑 2:我实施了几次。我的最后一个实现应该是那个,但它仍然不起作用。我会试着解释它是怎么回事。

mainActivity(主线程)启动dialogFragment:

TutorialDialog tutoDial = new TutorialDialog();
        tutoDial.setCancelable(true);
        tutoDial.show(getSupportFragmentManager(), "tuto");

然后,在另一个线程中,我在 onPreExecute() 中运行 await():

公共类 GetPlaces 扩展 AsyncTask>

private ProgressDialog dialog;
    // I put it public so that I can reach it from the DialogFragment
public static CountDownLatch startSignal = new CountDownLatch(1);  

@覆盖 受保护的无效onPreExecute() super.onPreExecute(); 尝试 startSignal.await(); 捕捉(InterruptedException e) // TODO 自动生成的 catch 块 e.printStackTrace(); 对话框 = 新进度对话框(上下文); dialog.setCancelable(false); dialog.setMessage(context.getString(R.string.loading)); 对话框.isIndeterminate(); dialog.setProgressStyle(R.style.dialogInput); 对话框.show();

这样,它不应该在 startSignal 变量达到 0 之前运行

然后,在我的 FragmentDialog 中,当对话框关闭时,我运行:

    noTuto.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            // DISMISS DIALOG
            startSignal.countDown();
            dismiss();
        
    );

所以理论上它应该可以工作,但在丑陋的现实中,我的 FragmentDialog 冻结...

我确定: 1 - 没有 startSignal.await();在应该冻结 UI 的 mainActivity 中 2 - startSignal 变量在另一个线程中定义:

public class GetPlaces extends AsyncTask<Void, Void, ArrayList<Place>>

所以,如果有什么冻结,应该是这个线程,但我不明白为什么我的对话是冻结的。现在,我的对话框不再收到点击...

【问题讨论】:

您的对话框未显示的原因是因为您在 UI 线程中调用 startSignal.await();。您的 UI 线程被阻止执行。这就是您的 UI 冻结的原因,并且您的 Dialog 没有机会出现。 但是即使我把它放在Dialog的onResume()方法上(它至少应该显示第一个活动,并且在onResume中,渲染应该已经完成​​了),总是冻结。 不要在 UI 线程中调用 startSignal.await()。 (onResume 由 UI 线程执行)也许您应该重新编写代码而不使用 CountDownLatch。就您要实现的目标以及阻止您实现目标的原因提出一个明确的例子。 所以,如果我理解得很好,我应该在一个新线程中运行我的 DialogFragment,阻塞主线程,并且由于我的 Dialog 在一个新线程中,我将能够单击一些东西来释放我的用户界面,我说得对吗??? 【参考方案1】:

使用CountDownLatch startSignal = new CountDownLatch(1);

您的代码通常会在用户线程中执行。将您的用户线程代码设为startSignal.await();,以便它可以暂停执行。

您的DialogFragment 将在 UI 线程中执行。将您的 UI 线程代码设为startSignal.countDown(),以恢复您的用户线程代码执行。

【讨论】:

我的实现阻止了我的用户界面!我更新了我的帖子。 我想我在他可以渲染视图之前阻止了 UI。我尝试了不同的方法,总是一样的......

以上是关于我该如何做模态对话框片段(代码在我关闭之前不会执行)的主要内容,如果未能解决你的问题,请参考以下文章

UI5 - XML片段中的格式化程序只执行一次。如何再次运行它们?

模态对话框不会随 stopPropagation 关闭

关闭React语义UI模式与按钮和关闭图标

模态日期选择器

MFC模态与非模态对话框

如何在应用程序关闭之前显示未保存的更改对话框? [关闭]