Окно AlertDialog в представлении без активности - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь изменить существующее приложение, чтобы включить диалоговое окно с предупреждением в классе View. Диалоговое окно с предупреждением работает нормально, если я запускаю его в действии (другом приложении). Однако, когда я добавляю его в класс View в существующем приложении, происходит сбой с ошибкой (Невозможно добавить окно - токен ноль). Я пытался "это" (текущий вид), getContext () и getApplicationContext (). Я прочитал, что не все представления привязаны к деятельности, поэтому 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 голосов
/ 10 сентября 2018

Нет, но вы можете использовать Activity как своего рода прокси. Вот пример класса (в Котлине):

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

Если вам нужно настроить прослушиватели для действий да / нет, к сожалению, я не смог найти другого способа, кроме как сделать это через статические переменные yesAct и 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>
...