В документации Android на AlertDialog приводится следующая инструкция и пример для настройки пользовательского представления в AlertDialog:
Если вы хотите отобразить более сложное представление, найдите FrameLayout под названием «body» и добавьте к нему свое представление:
FrameLayout fl = (FrameLayout) findViewById(R.id.body);
fl.add(myView, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
Во-первых, совершенно очевидно, что add()
это опечатка и должна быть addView()
.
Меня смущает первая строка с использованием R.id.body. Кажется, что это основной элемент AlertDialog ... но я не могу просто ввести это в свой код b / c, это дает ошибку компиляции. Где R.id.body определяется или назначается или что-то еще?
Вот мой код. Я пытался использовать setView(findViewById(R.layout.whatever)
на построителе, но это не сработало. Я предполагаю, потому что я не надувал его вручную?
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setCancelable(false)
.setPositiveButton("Go", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
EditText textBox = (EditText) findViewById(R.id.textbox);
doStuff();
}
});
FrameLayout f1 = (FrameLayout)findViewById(R.id.body /*CURRENTLY an ERROR*/);
f1.addView(findViewById(R.layout.dialog_view));
AlertDialog alert = builder.create();
alert.show();
android
android-alertdialog
шторм986
источник
источник
.setView(getLayoutInflater().inflate(R.layout.dialog_view, null))
в конструктор. Благодарим Серхио Виудеса, ниже.Ответы:
Вы правы, это потому, что вы не накачивали его вручную. Похоже, что вы пытаетесь «извлечь» идентификатор «body» из макета Activity, и это не сработает.
Вероятно, вам нужно что-то вроде этого:
источник
builder.setView(inflater.inflate(R.id.dialog, ROOT_VIEWGROUP[, ATTACH_TO_ROOT]))
, в документах говорится, что корневая группа просмотра является необязательной. Следует ли это использовать в этом случае? Если так ... еще предстоит выяснить, как получить ссылку на AlertDialog ...View
что надуваете. Вызовите егоfindViewById()
,View
когда вам понадобится что-то из его содержимого. См .: github.com/commonsguy/cw-android/tree/master/Database/ConstantsВы можете создать свое представление непосредственно из Layout Inflater, вам нужно только использовать имя вашего XML-файла макета и идентификатор макета в файле.
Ваш XML-файл должен иметь такой идентификатор:
А затем вы можете установить свой макет в конструкторе с помощью следующего кода:
источник
getCurrentFocus()
что возвращает EditText, а EditText не может быть приведен к ViewGroup. Использованиеnull
в качестве второго аргумента исправляет это.android.R.id.custom возвращал для меня значение null. Мне удалось заставить это работать на случай, если кто-то столкнется с той же проблемой,
Для справки, R.layout.simple_password:
источник
FrameLayout
как своего рода фрагмент? Когда я попробовал ответить Andrewx2 выше, у меня возникла ошибка, потому что он подумал, что я раздуваю два макета (это мое предположение).Документы android отредактированы для исправления ошибок.
Представление внутри AlertDialog называется
android.R.id.custom
http://developer.android.com/reference/android/app/AlertDialog.html
источник
Это сработало для меня:
источник
Пользовательский AlertDialog
Этот полный пример включает передачу данных обратно в Activity.
Создать собственный макет
В
EditText
этом простом примере используется макет с символом, но вы можете заменить его на что угодно.custom_layout.xml
Используйте диалог в коде
Ключевые части
setView
чтобы назначить настраиваемый макет дляAlertDialog.Builder
Это полный код из примера проекта, показанного на изображении выше:
MainActivity.java
Ноты
DialogFragment
подкласса, как описано в документации .Смотрите также
источник
EditText editText = customLayout.findViewById(R.id.editText);
должно бытьEditText editText = (EditText) customLayout.findViewById(R.id.editText);
Вот самые простые строки кода, которые мне подходят:
Независимо от типа макета (LinearLayout, FrameLayout, RelativeLayout) будет работать
setView
и будет отличаться только по внешнему виду и поведению.источник
Самый простой способ сделать это - использовать
android.support.v7.app.AlertDialog
вместо того,android.app.AlertDialog
гдеpublic AlertDialog.Builder setView (int layoutResId)
можно использовать ниже API 21.источник
AlertDialog.setView(View view)
добавляет данное представление вR.id.custom FrameLayout
. Ниже приведен фрагмент исходного кода Android, изAlertController.setupView()
которого, наконец, это обрабатывается (mView
это представление, данноеAlertDialog.setView
методу).источник
После изменения идентификатора android.R.id.custom мне нужно было добавить следующее, чтобы отобразить представление:
Однако это привело к отрисовке нового представления в большом родительском представлении без фона, разбив диалоговое окно на две части (текст и кнопки с новым представлением между ними). Наконец-то я получил желаемый эффект, вставив свой View рядом с сообщением:
Я нашел это решение, изучив дерево просмотра с помощью View.getParent () и View.getChildAt (int). Хотя и не очень доволен. Ничего из этого нет в документации Android, и если они когда-либо изменят структуру AlertDialog, это может сломаться.
источник
Было бы наиболее разумно сделать это таким образом, с наименьшим количеством кода.
Чтобы увидеть расширенный список настроек, начните вводить текст
.set
в Android Studio.источник