Шаблоны Android: Spinner, в котором каждый элемент запускает свою деятельность - PullRequest
1 голос
/ 14 июня 2011

Я пытаюсь построить сложную форму, где почти все элементы являются необязательными. Он начинается с одного поля и кнопки «Добавить элемент». При нажатии кнопки «Добавить» форма отображает Spinner типов элементов, которые можно добавить в форму (местоположение, фотография, подробное примечание, отметка времени, отличная от «сейчас» и т. Д.). Когда вы выбираете элемент, он запускает Activity, и каждый элемент имеет различную связанную Activity.

Кроме того, каждый выбор будет иметь несколько бит данных, которые было бы неплохо как-то «сохранить» с помощью Activity:

  • Значок и отображаемое имя в Spinner
  • Ключ для хранения данных в БД (а также для передачи в веб-сервис)
  • Схема для отображения результата в исходной форме (то есть миниатюра для фотографии, широта / долгота для местоположения и т. Д.)

Я рассматривал набор классов, которые расширяют абстрактный класс FormElement и будут иметь статические элементы для каждой из указанных выше дополнительных частей данных. (Дополнительным ударом для этого решения является то, сколько боли Resources находятся в статическом контексте.)

Как я могу сделать это настолько чистым и обслуживаемым, насколько это возможно? Мне бы не понравилось редактировать пять разных файлов, чтобы добавить новый тип элемента в эту форму. (Главным образом потому, что я могу гарантировать, что пропущу один и часами отыскиваю чучела).

1 Ответ

1 голос
/ 14 июня 2011

Несколько советов ...

  1. Модульные тесты предотвратят "unbugs":)

  2. Когда каждый Activity получил необходимую информацию от пользователя, вызовите Activity # setResult () с Intent, который содержит данные для каждого типа. Intent поддерживает все методы Bundle, поэтому вы можете устанавливать различные типы данных по мере необходимости.

  3. Для поддержки # 2 убедитесь, что вы используете Activity#startActivityForResult(Intent,int), чтобы запустить его, и прослушайте результат в Activity#onActivityResult(int,Intent)

  4. Я бы, вероятно, сохранил список доступных типов "элементов" для использования с SpinnerAdapter (например, ArrayList<Class<? extends AbstractFormElement>>, и вызывал бы статические методы, такие как .getDisplayName(), .getActivityClass() и т. Д., В адаптере. getView() метод, чтобы определить, что отображать и какую активность запустить.

    Таким образом, ваш список будет содержать такие вещи, как { MyPhotoElement.class, MyTextElement.class, MyDateElement.class, ...}).

  5. Когда каждый элемент добавляется в форму, добавьте его в ArrayList<AbstractFormElement>, который будет использоваться для поддержки другого адаптера для ListView. Этот адаптер будет отправлять инфляцию пользовательского макета представления, а также создавать ViewHolder , в зависимости от типа объекта - для этого потребуется, чтобы каждый отдельный AbstractFormElement имел свой собственный «тип просмотра», в соответствии с адаптером. См. BaseAdapter # getItemViewType (int) и связанные с ним getViewTypeCount().

    Стоит отметить, что для них потребуются отдельные типы представлений только , если один не может быть преобразован в другой ... Например, если у вас есть два "Элемента", которые должны отображать только текстовую строку в списке оба могут иметь общий вид «только для текста». Аналогично, два элемента, которые отображают только фотографию или могут легко преобразовать одно в другое (например, значок с заголовком или миниатюра фотографии без заголовка), могут использовать один тип представления «изображение с заголовком».

Имея в виду вышеизложенное, вам фактически придется в конечном итоге изменить разные файлы, чтобы добавить новый тип (ну, я думаю, технически вы могли бы иметь их все в одном файле, как внутренние классы, но на самом деле нет хорошего аргумента для ), но если вы правильно выполнили интерфейс API, следовали хорошим методам ОО и внедрили хорошие модульные тесты, вы значительно сократите количество усилий, необходимых для поиска ошибок, - просто потому, что большинство добавление нового типа фактически приведет к ошибке компилятора, если вы сделаете это неправильно. Добавьте к этому тот факт, что надлежащий набор модульных тестов сможет программно добавлять все возможные типы и гарантировать, что все отображается правильно, и у вас должен быть довольно обтекаемый процесс для легкой расширяемости:)

Звучит как большая работа, и поначалу это может показаться утомительным и многословным ... Но конечный результат на самом деле гораздо более понятен, особенно если список типов элементов будет довольно обширным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...