Форма в Android с вводом данных и возвратом результата
Учусь разработке под android. Задача - открыть из активити некую экранную форму, ввести данные (в разных местах приложения они разные - текст, число, дата) и вернуть обратно в вызывающую активити. Сейчас у меня в качестве диалоговой формы выступает несколько активити с разным набором полей для ввода. Мне кажется должны быть более изящные, визуально компактные, решения, чем целая новая активити с всего двумя полями для ввода и кнопкой. Если есть такие возможности, подскажите пож-та.
Ответы (1 шт):
Автор решения: Pavlo Khyzhniak
→ Ссылка
Оформи CustomDialog например так, для редактирования объекта, например Avto:
public class EditAutoDialogFragment extends DialogFragment {
// Фрагменты не могут напрямую взаимодействовать между собой.
// Для этого надо обращаться к контексту, в качестве которого
// выступает класс Activity. Для обращения к activity, как правило,
// создается вложенный интерфейс
public interface OnFragmentEditAutoSendDataListener {
void onSendData(int position,Auto item) throws ParseException;
void onRemoveElement(int position) throws ParseException;
} // OnFragmentSendDataListener
// ссылка на активность, в которой будет запускаться диалог
private OnFragmentEditAutoSendDataListener activityRetranslator;
private Activity activity;
Integer select;
Auto item;
// при подключении к активности, context - ссылка на активнсоть
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
activityRetranslator = (OnFragmentEditAutoSendDataListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context
+ " должен реализовывать интерфейс OnFragmentSendDataListener");
} // try-catch
} // onAttach
public EditAutoDialogFragment() {
// Required empty public constructor
}
@NonNull
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public Dialog onCreateDialog(Bundle savedInstanceState) {
// прочитать данные, переданные из активности (из точки вызова)
// getArguments() - получить параметры из активности
Bundle bundle = getArguments();
// читаем строковый параметр
this.select = bundle.getInt("select");
this.item = bundle.getParcelable("item");
activity = getActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder
.setTitle(getResources().getString(R.string.edit_auto))
.setIcon(R.drawable.edit) // иконка из ресурсов нашего приложения
.setView(R.layout.homework010_fragment_edit_auto_dialog) // добавить разметку - работает только с API21 и старше
// .setPositiveButton("ОК", onClickListener) // для кнопок можно установить текст и обработчик
// нажатия.
// для кнопки "Отмена" обработчик установлен
// .setNegativeButton("Отмена", onClickListener)
;
return builder.create();
} // onCreateDialog
EditText edtBrandName, edtModelName, edtYearOfManufacture, edtEnginePower, edtPrice, edtSymbolicImage;
Button btnSave, btnDelete, btnCancel;
Dialog dialog;
@Override
public void onStart() {
super.onStart();
// возможна работа с элементами разметки диалога
// при помощи getDialog().findBiewById()
setViews();
}
@SuppressLint("SetTextI18n")
private void setViews() {
// получить ссылки на элементы интерфейса
dialog = getDialog();
edtBrandName = (EditText) dialog.findViewById(R.id.edtBrandName);
edtModelName = (EditText) dialog.findViewById(R.id.edtModelName);
edtYearOfManufacture = (EditText) dialog.findViewById(R.id.edtYearOfManufacture);
edtEnginePower = (EditText) dialog.findViewById(R.id.edtEnginePower);
edtPrice = (EditText) dialog.findViewById(R.id.edtPrice);
edtSymbolicImage = (EditText) dialog.findViewById(R.id.edtSymbolicImage);
btnSave = (Button) dialog.findViewById(R.id.btnSave);
btnDelete = (Button) dialog.findViewById(R.id.btnDelete);
btnCancel = (Button) dialog.findViewById(R.id.btnCancel);
edtBrandName.setText(this.item.getBrandName());
edtModelName.setText(this.item.getModelName());
edtYearOfManufacture.setText(String.format(Locale.UK, "%d", item.getYearOfManufacture()));
edtEnginePower.setText(String.format(Locale.UK, "%.2f", item.getEnginePower()));
edtPrice.setText(String.format(Locale.UK, "%d", item.getPrice()));
// edtYearOfManufacture.setText(Integer.toString(this.item.getYearOfManufacture()));
// edtEnginePower.setText(Double.toString(this.item.getEnginePower()));
// edtPrice.setText(Integer.toString(this.item.getPrice()));
edtSymbolicImage.setText(this.item.getSymbolicImage());
btnCancel.setOnClickListener(this::onButtonClickListener);
btnDelete.setOnClickListener(this::onButtonClickListener);
btnSave.setOnClickListener(this::onButtonClickListener);
}
@SuppressLint("NonConstantResourceId")
private void onButtonClickListener(View v) {
switch (v.getId()) {
case R.id.btnSave:
try {
refreshItem();
activityRetranslator.onSendData(this.select,this.item);
} catch (ParseException e) {
e.printStackTrace();
}
if (dialog != null) {
if (dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
}
break;
case R.id.btnDelete:
try {
activityRetranslator.onRemoveElement(this.select);
} catch (ParseException e) {
e.printStackTrace();
}
case R.id.btnCancel:
if (dialog != null) {
if (dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
}
break;
}
}
private void refreshItem() throws ParseException {
this.item.setBrandName(edtBrandName.getText().toString());
this.item.setModelName(edtModelName.getText().toString());
this.item.setYearOfManufacture(Integer.parseInt(edtYearOfManufacture.getText().toString()));
this.item.setEnginePower(Double.parseDouble(edtEnginePower.getText().toString()));
this.item.setPrice(Integer.parseInt(edtPrice.getText().toString()));
this.item.setSymbolicImage(edtSymbolicImage.getText().toString());
}
// String parameter;
// onClick
// Слушатель события клик по кнопке диалога
DialogInterface.OnClickListener onClickListener = (dialogInterface, id) -> {
// определить состояние чек-бокса
// Dialog thisDialog = getDialog(); // ссылка на разметку
//
// // определить набранный в строке ввода текст
// EditText editText = thisDialog.findViewById(R.id.editText);
//
// parameter = editText.getText().toString();
switch (id) {
case Dialog.BUTTON_POSITIVE:
// подготовить и показть Toast
// getBaseContext() - ссылка на активность, в которой создан диалог
Toast toast = Toast.makeText(activity.getBaseContext(), "", Toast.LENGTH_LONG);
toast.setText("Запрос выполнен");
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
break;
case Dialog.BUTTON_NEGATIVE:
} // switch
};
}
И разметка
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".homework010.fragments.EditAutoDialogFragment">
<GridLayout
android:layout_height="match_parent"
android:layout_width="wrap_content">
<TextView
android:id="@+id/txvBrandName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="0"
android:text="@string/Brand" />
<TextView
android:id="@+id/txvModelName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="0"
android:text="@string/Model" />
<TextView
android:id="@+id/txvYearOfManufacture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="0"
android:text="@string/YearOfManufacture" />
<TextView
android:id="@+id/txvEnginePower"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="0"
android:text="@string/EnginePower" />
<TextView
android:id="@+id/txvPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="0"
android:text="@string/Price" />
<TextView
android:id="@+id/txvSymbolicImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="5"
android:layout_column="0"
android:text="@string/SymbolicImage" />
<EditText
android:id="@+id/edtBrandName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="1"
android:autofillHints="@string/hint_lastname"
android:inputType="text"
android:labelFor="@id/txvLastName"
android:maxWidth="400dp"
android:minWidth="100dp" />
<EditText
android:id="@+id/edtModelName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="1"
android:autofillHints="@string/hint_firstname"
android:inputType="text"
android:labelFor="@id/txvFirstName"
android:maxWidth="400dp"
android:minWidth="100dp" />
<EditText
android:id="@+id/edtYearOfManufacture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="1"
android:autofillHints="@string/hint_flightnumber"
android:inputType="numberDecimal"
android:labelFor="@id/txvFlightNumber"
android:maxWidth="400dp"
android:minWidth="100dp" />
<EditText
android:id="@+id/edtEnginePower"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="1"
android:autofillHints="@string/hint_departuredate"
android:inputType="date"
android:labelFor="@id/txvDepartureDate"
android:maxWidth="400dp"
android:minWidth="100dp" />
<EditText
android:id="@+id/edtPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="1"
android:autofillHints="@string/hint_destination"
android:inputType="date"
android:labelFor="@id/txvDestination"
android:maxWidth="400dp"
android:minWidth="100dp" />
<EditText
android:id="@+id/edtSymbolicImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="5"
android:layout_column="1"
android:autofillHints="@string/hint_destination"
android:inputType="date"
android:labelFor="@id/txvDestination"
android:maxWidth="400dp"
android:minWidth="100dp" />
</GridLayout>
<LinearLayout
android:gravity="center"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnSave"
android:text="@string/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btnDelete"
android:text="@string/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btnCancel"
android:text="@string/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
Сам объект:
public class Auto implements Parcelable {
String brandName;//бренд
String modelName;//модель
int yearOfManufacture;//год выпуска
double enginePower;//мощность двигателя
int price;//цена
String symbolicImage;//условное изображение
protected Auto(Parcel in) {
brandName = in.readString();
modelName = in.readString();
yearOfManufacture = in.readInt();
enginePower = in.readDouble();
price = in.readInt();
symbolicImage = in.readString();
}
public static final Creator<Auto> CREATOR = new Creator<Auto>() {
@Override
public Auto createFromParcel(Parcel in) {
return new Auto(in);
}
@Override
public Auto[] newArray(int size) {
return new Auto[size];
}
};
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
if (brandName.length() > 0)
this.brandName = brandName;
}
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
if (modelName.length() > 0)
this.modelName = modelName;
}
public int getYearOfManufacture() {
return yearOfManufacture;
}
public void setYearOfManufacture(int yearOfManufacture) {
if (yearOfManufacture > 0)
this.yearOfManufacture = yearOfManufacture;
}
public double getEnginePower() {
return enginePower;
}
public void setEnginePower(double enginePower) {
if (enginePower > 0)
this.enginePower = enginePower;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
if (price > 0)
this.price = price;
}
public String getSymbolicImage() {
return symbolicImage;
}
public void setSymbolicImage(String symbolicImage) {
if (symbolicImage.length() > 0)
this.symbolicImage = symbolicImage;
}
public Auto(
String _brandName,
String _modelName,
int _yearOfManufacture,
double _enginePower,
int _price,
String _symbolicImage
) {
this.brandName = _brandName;
this.modelName = _modelName;
this.yearOfManufacture = _yearOfManufacture;
this.enginePower = _enginePower;
this.price = _price;
this.symbolicImage = _symbolicImage;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(brandName);
dest.writeString(modelName);
dest.writeInt(yearOfManufacture);
dest.writeDouble(enginePower);
dest.writeInt(price);
dest.writeString(symbolicImage);
}
}
И используй где надо:
private void dialogEdit(int position) {
// ссылка на элемент коллекции
Auto item = itemsList.get(position);
if (item != null) {
// создать диалог, передать ему строку - элемент списка
EditAutoDialogFragment dialog = new EditAutoDialogFragment();
// передача параметров в диалог - через Bundle
Bundle args = new Bundle(); // объект для передачи параметров в диалог
args.putInt("select", position);
args.putParcelable("item", item);
// метод базового класса DialogFragment
dialog.setArguments(args);
// отображение диалогового окна
dialog.show(((AppCompatActivity) context).getSupportFragmentManager(), "dialogEditAuto");
}
}