非活动视图中的AlertDialog框

时间:2018-09-09 22:56:06

标签: java android view dialog alertdialog

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

        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();

1 个答案:

答案 0 :(得分:1)

否,但是您可以将“活动”用作一种代理。这是一个示例类(在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来完成此操作外,我找不到其他任何方法。 / p>

将此用作活动的主题:

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