非活动视图中的AlertDialog框 [英] AlertDialog box in a non-Activity view

查看:62
本文介绍了非活动视图中的AlertDialog框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试修改现有应用程序,以在View类中包含警报对话框.如果我在活动(另一个应用程序)中运行警报对话框,则该对话框运行良好.但是,当我将其添加到现有应用程序中的View类时,它将失败,并显示(无法添加窗口-标记为null)错误.我尝试了"this"(当前视图),getContext()和getApplicationContext().我读到并非所有View都附加到一个活动,因此getContext失败.有其他选择吗?我可以使用某种不依赖活动的通用警报对话框吗?

I am trying to modify an existing application to include an alert dialog in a View class. The alert dialog works fine if I run it in an activity (another application). However, when I add it to a View class in the existing application it fails with a (Unable to add window -- token null) error. I tried "this" (current View), getContext(), and getApplicationContext(). I read that not all Views are attached to an activity, thus getContext fails. Are there any alternatives to this? Can I use some sort of generic alert dialog that does not rely on an Activity?

        Dialog dialog;
        final ArrayList<Integer> itemsSelected = new ArrayList<Integer>();
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("Selection:");
        builder.setMultiChoiceItems(items.toArray(new String[items.size()]), null,
                new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int selectedItemId,
                            boolean isSelected) {
                        if (isSelected) {
                            itemsSelected.add(selectedItemId);
                        } else if (itemsSelected.contains(selectedItemId)) {
                            itemsSelected.remove(Integer.valueOf(selectedItemId));
                        }   
                    }   
                })  
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                // OK
            }   
        })  
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                // Cancel
            }   
        }); 
        dialog = builder.create();
        dialog.show();

推荐答案

否,但是您可以将活动"用作一种代理.这是一个示例类(在Kotlin中):

No, but you can use an Activity as a sort of proxy. Here's an example class (in Kotlin):

/**
 * Activity used solely for showing a dialog outside of an activity context
 */
class DialogActivity : AppCompatActivity() {
    companion object {
        const val EXTRA_TITLE = "title"
        const val EXTRA_MESSAGE = "message"
        const val EXTRA_YES_RES = "yes_res"
        const val EXTRA_NO_RES = "no_res"

        var yesAct: DialogInterface.OnClickListener? = null
        var noAct: DialogInterface.OnClickListener? = null
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            val title = intent.getIntExtra(EXTRA_TITLE, android.R.string.untitled)
            val message = intent.getIntExtra(EXTRA_MESSAGE, android.R.string.untitled)
            val yesRes = intent.getIntExtra(EXTRA_YES_RES, 0)
            val noRes = intent.getIntExtra(EXTRA_NO_RES, 0)

            val builder = AlertDialog.Builder(this)
            builder.setTitle(title)
            builder.setMessage(message)

            if (yesRes != 0) builder.setPositiveButton(yesRes, yesAct)
            if (noRes != 0) builder.setNegativeButton(noRes, noAct)

            builder.setOnCancelListener {
                finish()
            }

            builder.setOnDismissListener {
                finish()
            }

            builder.show()

        } catch (e: Exception) {
            e.printStackTrace()
            finish()
        }
    }

    override fun onDestroy() {
        super.onDestroy()

        yesAct = null
        noAct = null
    }

    /**
     * Builder class
     * Create a DialogActivity instance using this
     */
    class Builder(private val context: Context) {
        var title = android.R.string.untitled
        var message = android.R.string.untitled
        var yesRes = android.R.string.yes
        var noRes = android.R.string.no

        var yesAction: DialogInterface.OnClickListener? = null
        var noAction: DialogInterface.OnClickListener? = null

        fun start() {
            val intent = Intent(context, DialogActivity::class.java)
            intent.putExtra(EXTRA_TITLE, title)
            intent.putExtra(EXTRA_MESSAGE, message)
            intent.putExtra(EXTRA_YES_RES, yesRes)
            intent.putExtra(EXTRA_NO_RES, noRes)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

            yesAct = yesAction
            noAct = noAction

            context.startActivity(intent)
        }
    }
}

要使用它,请使用

DialogActivity.Builder builder = new DialogActivity.Builder(context);
builder.title = whatever;
builder.message = whatever;
//etc
builder.start();

不幸的是,如果您需要为是/否"操作设置侦听器,除了通过静态变量yesActnoAct来完成此操作外,我找不到其他任何方法.

If you need to set listeners for the yes/no actions, unfortunately, I couldn't find any other way but to have this be done through the static variables, yesAct and noAct.

将此用作活动的主题:

<style name="AppTheme.Null" parent="AppTheme">
    <item name="android:windowAnimationStyle">@null</item>
    <item name="android:activityOpenEnterAnimation">@null</item>
    <item name="android:activityOpenExitAnimation">@null</item>
    <item name="android:activityCloseEnterAnimation">@null</item>
    <item name="android:activityCloseExitAnimation">@null</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

这篇关于非活动视图中的AlertDialog框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆