当单击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?
答案 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")