Android AlertDialog - 如何处理极大的邮件?

时间:2014-05-28 19:17:39

标签: android android-layout android-fragments

当单击ListView项并且消息的字符串非常大(近20,000个字符)时,我弹出一个AlertDialog。最后发生的事情是我单击列表项并在显示AlertDialog之前保持大约3-4秒。出于多种原因,这是有问题的,主要是用户可以反复点击按钮并使应用程序崩溃。

我的第一个想法是尝试模仿Google Play应用程序如何处理其开源许可证显示(播放 - >导航抽屉 - >设置 - >开源许可证信息),然后他们弹出AlertDialog然后在显示对话框后,看起来好像已加载了视图/文本。我想它看起来像这样:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
       builder.setTitle(title);
       builder.setMessage(veryLongStringMessage);
       builder.setCancelable(true);
       builder.setNeutralButton(android.R.string.ok, listener);

       final AlertDialog alertDialog = builder.create();
       alertDialog.show();

直到这一点,非常基本的东西。然后我尝试删除构建器中的消息集,例如:

builder.setMessage("")
// create/show dialog as above
alertDialog.setMessage(veryLongStringMessage);

但这似乎只是在显示之前加载整个对话框。所以我想也许可以在活动结束时发布一个runnable,但这不起作用。我尝试在异步任务中执行此操作,但也无法以此方式工作。我把它作为DialogFragment尝试了,我打电话给

activity.getSupportFragmentManager().executePendingTransactions();

然后继续尝试在我知道DialogFragment已经显示之后设置消息,我要么结束一个空对话框(新消息不会显示)或者它立即加载所有内容而我是坐着3-4秒的延迟。

任何人都有任何好的实施方法和使用非常大邮件的AlertDialog?

2 个答案:

答案 0 :(得分:3)

此案例是在我显示Google Play服务的法律声明时:

问题似乎是Dialog.show(),它需要这些秒才能生成布局。 所以我在我的情况下所做的,可能不是最好的,但它有效。我创建了一个时间对话框。

private void showGPSLicense() {
        AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MyActivity.this);
        LicenseDialog.setTitle(getString(R.string.google_maps_legalnotices));
        LicenseDialog.setMessage(getString(R.string.google_maps_loading));
        final Dialog loadingDialog = LicenseDialog.create();  
        loadingDialog.show();       

       //This dialog does not take much time. Meanwhile I get via AsyncTask the heavy message, replacing/dismissing the previous dialog.

        (new AsyncTask<Void, Void,AlertDialog.Builder>() {
            @Override
            protected AlertDialog.Builder doInBackground(Void... arg0) {
                String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(getApplicationContext());
                AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MyActivity.this);
                LicenseDialog.setTitle(getString(R.string.google_maps_legalnotices));
                LicenseDialog.setMessage(LicenseInfo);
                return LicenseDialog;
            }

            protected void onPostExecute(AlertDialog.Builder result) {
                Dialog dialog = result.create();
                dialog.setOnShowListener(new OnShowListener() {

                    public void onShow(DialogInterface dialog) {
                        loadingDialog.dismiss();
                    }
                 });
                dialog.show();
             }
        }).execute();   
}

在Nexus 5(4.4.2)上进行测试

如果您担心多次点击,您还可以通过实施OnClickListener来阻止多次点击:

public abstract class PreventManyClicksListener implements OnClickListener {
    private boolean clickable = true;

    public abstract void preventManyClicks(View view);

    public final void onClick(View view) {
        if (clickable) {
            clickable = false;
            preventManyClicks(view);
        }
    }

    public void setClickable() {
        clickable = true;
    }
}
//...

private PreventManyClicksListener preventDialog = new PreventManyClicksListener() {         
@Override
public void preventManyClicks(View view) {
    showGPSLicense();
    setClickable();
}
};
//.. 
myView.setOnClickListener(preventDialog);

答案 1 :(得分:0)

我认为您需要使用自定义视图才能执行此操作,因为您无法在创建后更新AlertDialog消息。使用ID为textView1的TextView和ID为progressBar1的ProgressBar创建自定义视图,然后创建以下类。

public class MyDialogFragment extends DialogFragment {
    private TextView mTextView;
    private ProgressBar mProgressBar;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_dialog, container, false);
        mTextView = view.findViewById(R.id.textView1);
        mTextView.setVisibility(View.GONE);
        mProgressBar = view.findViewById(R.id.progressBar1);
        mProgressBar.setVisibility(View.VISIBILE);

        return view;    
    }

    @Override
    public View onStart() {
        super.onStart();

        mTextView.setText(getArguments().getString("text");
        mProgressBar.setVisibility(View.GONE);
        mTextView.setVisibility(View.VISIBILE);
    }
}

您还需要在其参数中传递文本字符串。

DialogFragment dialog = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("text", text);
dialog.setArguments(args);
dialog.show(getFragmentManager(), "my_dialog")