QMBForm
Create simple Android forms
Basic Usage
-
Create a "FromDescriptor" - It's the holder for the form
FormDescriptor descriptor = FormDescriptor.newInstance(); descriptor.setOnFormRowValueChangedListener(this); //Listen for changes
-
Create sections with "SectionDescriptor" and add rows - Sections can have titles and rows (Form Elements)
SectionDescriptor sectionDescriptor = SectionDescriptor.newInstance("tag","Title"); //Add rows - form elements sectionDescriptor.addRow( RowDescriptor.newInstance("text",RowDescriptor.FormRowDescriptorTypeText, "Text", new Value<String>("test")) ); sectionDescriptor.addRow( RowDescriptor.newInstance("dateDialog",RowDescriptor.FormRowDescriptorTypeDate, "Date Dialog") );
-
To render your form, use the "FormManager" helper. You will need a ListView instance.
FormManager formManager = new FormManager(); formManager.setup(descriptor, mListView, getActivity()); formManager.setOnFormRowClickListener(this);
-
Attention! If you use EditText based form elements, make sure you set "windowSoftInputMode" to "adjustPan"
Do it in your manifest:
<activity android:windowSoftInputMode="adjustPan"/>
Or programmatically in the onCreate method of your activity
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); }
-
Create elements with custom type identifier and a FormCell class. You can also submit configs to use objects in your cell
String customType = "customRowIdentifier"; CellViewFactory.getInstance().setRowTypeMap(customType, CustomFormCell.class); RowDescriptor customRow = RowDescriptor.newInstance("custom",customType, "title", new Value<String>("value")); HashMap<String, Object> cellConfig = new HashMap(); cellConfig.put("config",configObject); customRow.setCellConfig(cellConfig); section.addRow(customRow);
Use annotations for models
-
You can create a form from a POJO by adding annotations to your model properties
public class Entry { @FormElement( label = R.string.lb_title, rowDescriptorType = RowDescriptor.FormRowDescriptorTypeText, sortId = 1, section = R.string.section_general ) public String title; @FormElement( label = R.string.lb_description, rowDescriptorType = RowDescriptor.FormRowDescriptorTypeTextView, sortId = 2, section = R.string.section_general ) public String description; @FormElement( label = R.string.lb_date_dialog, rowDescriptorType = RowDescriptor.FormRowDescriptorTypeDate, sortId = 4, section = R.string.section_date ) public Date date; @FormElement( label = R.string.lb_date_inline, rowDescriptorType = RowDescriptor.FormRowDescriptorTypeDateInline, tag = "customDateInlineTag", sortId = 3, section = R.string.section_date ) public Date dateInline; }
-
Use "FormDescriptorAnnotationFactory" to create a FormDescriptor from your model
FormDescriptorAnnotationFactory factory = new FormDescriptorAnnotationFactory(getActivity()); FormDescriptor descriptor = factory.createFormDescriptorFromAnnotatedClass(entry);
Validation
- Define custom validators by implementing
FormValidator
public class EmailValidator implements FormValidator { private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{ 2, } )$"; @Override public RowValidationError validate(RowDescriptor descriptor) { Value value = descriptor.getValue(); if (value.getValue() != null && value.getValue() instanceof String) { String val = (String) value.getValue(); return (val.matches(EMAIL_PATTERN)) ? null : new RowValidationError(descriptor, R.string.validation_invalid_email); } return new RowValidationError(descriptor, R.string.validation_invalid_email); }
} ```
-
With annotations Specify validator classes as an array of .class items
@FormElement( label = R.string.email, rowDescriptorType = RowDescriptor.FormRowDescriptorTypeEmailInline, sortId = 2, validatorClasses = { EmailValidator.class, BlankStringValidator.class } ) public String email;
-
Or add validators to rowdescriptors manually
RowDescriptor rowDescriptor = RowDescriptor.newInstance("valid", RowDescriptor.FormRowDescriptorTypeEmail, "Email Test", new Value<String>("notavalidemail")); rowDescriptor.addValidator(new EmailValidator());
Installation
QMBForm is not available at the maven repository yet. But it's a gradly based android-library project.
- Include the QMBFrom directory as a library module in your application
- see sample application:
Add this to your build.gradle dependencies section
compile project(":lib:QMBForm")
Add this to your settings.gradle
include ':app', ':lib:QMBForm'
QMBForm has no dependencies to other third party libs (but compile 'com.android.support:appcompat-v7:19.+') is needed
Supported Form Elements
Most elements have an inline version (label on the same line as the displayed value) and a normal version (label on separate line above displayed value).
- Available elements:
public static final String FormRowDescriptorTypeName = "name"; public static final String FormRowDescriptorTypeText = "text"; public static final String FormRowDescriptorTypeTextInline = "textInline"; public static final String FormRowDescriptorTypeDetail = "detail"; public static final String FormRowDescriptorTypeDetailInline = "detailInline"; public static final String FormRowDescriptorTypeTextView = "textView"; public static final String FormRowDescriptorTypeTextViewInline = "textViewInline"; public static final String FormRowDescriptorTypeURL = "url"; public static final String FormRowDescriptorTypeEmail = "email"; public static final String FormRowDescriptorTypeEmailInline = "emailInline"; public static final String FormRowDescriptorTypePassword = "password"; public static final String FormRowDescriptorTypePasswordInline = "passwordInline"; public static final String FormRowDescriptorTypeNumber = "number"; public static final String FormRowDescriptorTypeNumberInline = "numberInline"; public static final String FormRowDescriptorTypeCurrency = "currency"; public static final String FormRowDescriptorTypePhone = "phone"; public static final String FormRowDescriptorTypeInteger = "integer"; public static final String FormRowDescriptorTypeIntegerInline = "integerInline"; public static final String FormRowDescriptorTypeSelectorSpinner = "selectorSpinner"; public static final String FormRowDescriptorTypeSelectorSpinnerInline = "selectorSpinnerInline"; public static final String FormRowDescriptorTypeSelectorPickerDialog = "selectorPickerDialog"; public static final String FormRowDescriptorTypeDateInline = "dateInline"; public static final String FormRowDescriptorTypeTimeInline = "timeInline"; public static final String FormRowDescriptorTypeDate = "date"; public static final String FormRowDescriptorTypeTime = "time"; public static final String FormRowDescriptorTypeBooleanCheck = "booleanCheck"; public static final String FormRowDescriptorTypeBooleanSwitch = "booleanSwitch"; public static final String FormRowDescriptorTypeButton = "button"; public static final String FormRowDescriptorTypeButtonInline = "buttonInline"; public static final String FormRowDescriptorTypeSelectorSegmentedControl = "selectorSegmentedControl"; public static final String FormRowDescriptorTypeSelectorSegmentedControlInline = "selectorSegmentedControlInline";
- Coming elements: (Avaiable at XLForm)
public static final String FormRowDescriptorTypeTwitter = "twitter"; public static final String FormRowDescriptorTypeAccount = "account"; public static final String FormRowDescriptorTypeSelectorPush = "selectorPush"; public static final String FormRowDescriptorTypeSelectorActionSheet = "selectorActionSheet"; public static final String FormRowDescriptorTypeSelectorAlertView = "selectorAlertView"; public static final String FormRowDescriptorTypeSelectorPickerView = "selectorPickerView"; public static final String FormRowDescriptorTypeSelectorPickerViewInline = "selectorPickerViewInline"; public static final String FormRowDescriptorTypeMultipleSelector = "multipleSelector"; public static final String FormRowDescriptorTypeSelectorLeftRight = "selectorLeftRight"; public static final String FormRowDescriptorTypeDateTimeInline = "datetimeInline"; public static final String FormRowDescriptorTypeDateTime = "datetime"; public static final String FormRowDescriptorTypePicker = "picker"; public static final String FormRowDescriptorTypeImage = "image"; public static final String FormRowDescriptorTypeStepCounter = "stepCounter";
To do
- Simpler cell customisation
- More form elements
- Form model
Credits
QMBForm is based on the ideas of XLForm - the most flexible and powerful iOS library to create dynamic table-view forms.
Thanks guys!