Как реализовать пользовательское представление AlertDialog
на Android docs на AlertDialog, он дает следующую инструкцию и пример для установки пользовательского представления в AlertDialog:
если вы хотите отобразить более сложный вид, найдите FrameLayout под названием "body" и добавьте к нему свое представление:
FrameLayout fl = (FrameLayout) findViewById(R.id.body);
fl.add(myView, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
во-первых, это довольно очевидно, что add() это опечатка и должна быть addView().
Я в замешательстве по первой линии с использованием ID-Р..тела. Кажется, что это элемент тела AlertDialog ... но я не могу просто ввести, что в моем коде b/c это дает ошибку компиляции. Где ИД Р..тела определяется или назначается, или что?
вот мой код. Я пытался использовать 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();
11 ответов:
вы правы, это потому, что вы не раздували его вручную. Похоже, что вы пытаетесь "извлечь" идентификатор "тела" из макета вашего действия, и это не сработает.
вы, вероятно, хотите что-то вроде этого:
LayoutInflater inflater = getLayoutInflater(); FrameLayout f1 = (FrameLayout)alert.findViewById(android.R.id.body); f1.addView(inflater.inflate(R.layout.dialog_view, f1, false));
вы можете создать свой вид непосредственно из макета Inflater, вам нужно только использовать имя вашего макета XML-файла и идентификатор макета в файле.
ваш XML-файл должен иметь такой идентификатор:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dialog_layout_root" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" />и затем вы можете установить свой макет на Строителе со следующим кодом:
LayoutInflater inflater = getLayoutInflater(); View dialoglayout = inflater.inflate(R.layout.dialog_layout, null); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setView(dialoglayout); builder.show();
android.R.id.custom возвращал null для меня. Мне удалось заставить это работать в случае, если кто-нибудь столкнется с той же проблемой,
AlertDialog.Builder builder = new AlertDialog.Builder(context) .setTitle("My title") .setMessage("Enter password"); final FrameLayout frameView = new FrameLayout(context); builder.setView(frameView); final AlertDialog alertDialog = builder.create(); LayoutInflater inflater = alertDialog.getLayoutInflater(); View dialoglayout = inflater.inflate(R.layout.simple_password, frameView); alertDialog.show();Для справки, расположение Р..simple_password это :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/password_edit_view" android:inputType="textPassword"/> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/show_password" android:id="@+id/show_password_checkbox" android:layout_gravity="left|center_vertical" android:checked="false"/> </LinearLayout>
документы android были отредактированы, чтобы исправить ошибки.
представление внутри AlertDialog называется
android.R.id.customhttp://developer.android.com/reference/android/app/AlertDialog.html
это сработало для меня:
dialog.setView(dialog.getLayoutInflater().inflate(R.layout.custom_dialog_layout, null));
самый простой строки кода, который работает для меня являются следующие:
AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setView(R.layout.layout_resource_id); builder.show();независимо от типа макета (LinearLayout, FrameLayout, RelativeLayout) будет работать по
setViewи будет просто отличаться по внешнему виду и поведению.
AlertDialog.setView(просмотр) добавляет данный вид на р. ИД.таможни заменить. Ниже приведен фрагмент исходного кода Android от AlertController.setupView (), который, наконец, обрабатывает это (mView-это представление, данное AlertDialog.метод setView).
... FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.**custom**); custom.addView(**mView**, new LayoutParams(FILL_PARENT, FILL_PARENT)); ...
самый простой способ сделать это с помощью
android.support.v7.app.AlertDialogвместоandroid.app.AlertDialogздесьpublic AlertDialog.Builder setView (int layoutResId)может использоваться ниже API 21.new AlertDialog.Builder(getActivity()) .setTitle(title) .setView(R.layout.dialog_basic) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //Do something } } ) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //Do something } } ) .create();
после изменения идентификатора это Android.Р.ИД.обычаю, я должен добавить следующее, Чтобы получить представление для отображения:
((View) f1.getParent()).setVisibility(View.VISIBLE);однако это привело к тому, что новое представление отображалось в большом родительском представлении без фона, разбивая диалоговое окно на две части (текст и кнопки, с новым представлением между ними). Я, наконец, получил эффект, который я хотел, вставив мое представление рядом с сообщением:
LinearLayout f1 = (LinearLayout)findViewById(android.R.id.message).getParent().getParent();Я нашел это решение, исследуя дерево представлений с видом.getParent() и Вид.getChildAt (int). Впрочем, я тоже не очень доволен. Ничего из этого нет в документах Android, и если они когда-либо изменят структуру AlertDialog, это может сломаться.
Custom AlertDialog
этот полный пример включает в себя передачу данных обратно в действие.
создать пользовательский макет
макет с
EditTextиспользуется для этого простого примера, но вы можете заменить его чем угодно.custom_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:paddingLeft="20dp" android:paddingRight="20dp" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>используйте диалоговое окно в коде
ключевые части
- используя
setViewчтобы назначить пользовательский макетAlertDialog.Builder- отправка любых данных обратно в действие при нажатии кнопки диалогового окна.
это полный код из примера проекта, показанного на рисунке выше:
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void showAlertDialogButtonClicked(View view) { // create an alert builder AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Name"); // set the custom layout final View customLayout = getLayoutInflater().inflate(R.layout.custom_layout, null); builder.setView(customLayout); // add a button builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // send data from the AlertDialog to the Activity EditText editText = customLayout.findViewById(R.id.editText); sendDialogDataToActivity(editText.getText().toString()); } }); // create and show the alert dialog AlertDialog dialog = builder.create(); dialog.show(); } // do something with the data coming from the AlertDialog private void sendDialogDataToActivity(String data) { Toast.makeText(this, data, Toast.LENGTH_SHORT).show(); } }Примечания
- если вы обнаружите, что используете это в нескольких местах, то подумайте о создании
DialogFragmentподкласс, как описано в документация.см. также
было бы наиболее разумно сделать это таким образом, наименьшее количество кода.
new AlertDialog.Builder(this).builder(this) .setTitle("Title") .setView(R.id.dialog_view) //notice this setView was added .setCancelable(false) .setPositiveButton("Go", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { EditText textBox = (EditText) findViewById(R.id.textbox); doStuff(); } }).show();расширенный перечень вещей, которые вы можете установить, начните вводить
.setв Android Studio

Comments