【问题标题】:AlertDialog box in a non-Activity view非活动视图中的警报对话框
【发布时间】:2018-09-09 22:56:05
【问题描述】:

我正在尝试修改现有应用程序以在 View 类中包含警报对话框。如果我在活动(另一个应用程序)中运行警报对话框,它可以正常工作。但是,当我将它添加到现有应用程序中的 View 类时,它会失败并出现(无法添加窗口 -- token null)错误。我尝试了“this”(当前视图)、getContext() 和 getApplicationContext()。我读到并非所有视图都附加到活动,因此 getContext 失败。有没有其他选择?我可以使用某种不依赖 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();

【问题讨论】:

    标签: java android view dialog android-alertdialog


    【解决方案1】:

    不,但您可以将 Activity 用作一种代理。这是一个示例类(在 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 来完成。

    将此作为活动的主题:

    <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>
    

    【讨论】:

    • 所以基本上你正在应用程序中启动另一个活动?传递给 DialogActivity.Builder 的上下文是什么?它是当前视图的上下文吗?谢谢
    • 这是您想要的任何上下文,是的。这是一个专门用于显示对话框的活动。另外,等一下,你需要实现一个主题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2022-08-10
    • 2019-02-03
    相关资源
    最近更新 更多