Create simple Android forms
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);
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);
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());
QMBForm is not available at the maven repository yet. But it's a gradly based android-library project.
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
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";
QMBForm is based on the ideas of XLForm - the most flexible and powerful iOS library to create dynamic table-view forms.
Thanks guys!