Skip to content

Repository files navigation

QMBForm

Travis-CICoverageTechnical Dept

Create simple Android forms

Demo

Basic Usage

  1. Create a "FromDescriptor" - It's the holder for the form

    FormDescriptordescriptor = FormDescriptor.newInstance();
    descriptor.setOnFormRowValueChangedListener(this); //Listen for changes
  2. Create sections with "SectionDescriptor" and add rows - Sections can have titles and rows (Form Elements)

    SectionDescriptorsectionDescriptor = SectionDescriptor.newInstance("tag","Title");
    //Add rows - form elementssectionDescriptor.addRow( RowDescriptor.newInstance("text",RowDescriptor.FormRowDescriptorTypeText, "Text", newValue<String>("test")) );
    sectionDescriptor.addRow( RowDescriptor.newInstance("dateDialog",RowDescriptor.FormRowDescriptorTypeDate, "Date Dialog") );
  3. To render your form, use the "FormManager" helper. You will need a ListView instance.

    FormManagerformManager = newFormManager();
    formManager.setup(descriptor, mListView, getActivity());
    formManager.setOnFormRowClickListener(this); 
  4. Attention! If you use EditText based form elements, make sure you set "windowSoftInputMode" to "adjustPan"

    Do it in your manifest:

    <activityandroid:windowSoftInputMode="adjustPan"/>
    

    Or programmatically in the onCreate method of your activity

    @OverrideprotectedvoidonCreate(BundlesavedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    }
  5. Create elements with custom type identifier and a FormCell class. You can also submit configs to use objects in your cell

    StringcustomType = "customRowIdentifier";
    CellViewFactory.getInstance().setRowTypeMap(customType, CustomFormCell.class);
    RowDescriptorcustomRow = RowDescriptor.newInstance("custom",customType, "title", newValue<String>("value"));
    HashMap<String, Object> cellConfig = newHashMap();
    cellConfig.put("config",configObject);
    customRow.setCellConfig(cellConfig);
    section.addRow(customRow);

Use annotations for models

  1. You can create a form from a POJO by adding annotations to your model properties

    publicclassEntry {
    @FormElement(
    label = R.string.lb_title,
    rowDescriptorType = RowDescriptor.FormRowDescriptorTypeText,
    sortId = 1,
    section = R.string.section_general
    )
    publicStringtitle;
    @FormElement(
    label = R.string.lb_description,
    rowDescriptorType = RowDescriptor.FormRowDescriptorTypeTextView,
    sortId = 2,
    section = R.string.section_general
    )
    publicStringdescription;
    @FormElement(
    label = R.string.lb_date_dialog,
    rowDescriptorType = RowDescriptor.FormRowDescriptorTypeDate,
    sortId = 4,
    section = R.string.section_date
    )
    publicDatedate;
    @FormElement(
    label = R.string.lb_date_inline,
    rowDescriptorType = RowDescriptor.FormRowDescriptorTypeDateInline,
    tag = "customDateInlineTag",
    sortId = 3,
    section = R.string.section_date
    )
    publicDatedateInline;
    }
  2. Use "FormDescriptorAnnotationFactory" to create a FormDescriptor from your model

    FormDescriptorAnnotationFactoryfactory = newFormDescriptorAnnotationFactory(getActivity());
    FormDescriptordescriptor = factory.createFormDescriptorFromAnnotatedClass(entry);

Validation

  1. Define custom validators by implementing FormValidator
    publicclassEmailValidatorimplementsFormValidator {
    privatestaticfinalStringEMAIL_PATTERN =
    "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
    + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    @OverridepublicRowValidationErrorvalidate(RowDescriptordescriptor) {
    Valuevalue = descriptor.getValue();
    if (value.getValue() != null && value.getValue() instanceofString) {
    Stringval = (String) value.getValue();
    return (val.matches(EMAIL_PATTERN)) ? null : newRowValidationError(descriptor, R.string.validation_invalid_email);
    }
    returnnewRowValidationError(descriptor, R.string.validation_invalid_email);
    }

} ```

  1. 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}
    )
    publicStringemail;
  2. Or add validators to rowdescriptors manually

    RowDescriptorrowDescriptor = RowDescriptor.newInstance("valid",
    RowDescriptor.FormRowDescriptorTypeEmail,
    "Email Test",
    newValue<String>("notavalidemail"));
    rowDescriptor.addValidator(newEmailValidator());

Installation

QMBForm is not available at the maven repository yet. But it's a gradly based android-library project.

  1. Include the QMBFrom directory as a library module in your application
  2. 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:
    publicstaticfinalStringFormRowDescriptorTypeName = "name";
    publicstaticfinalStringFormRowDescriptorTypeText = "text";
    publicstaticfinalStringFormRowDescriptorTypeTextInline = "textInline";
    publicstaticfinalStringFormRowDescriptorTypeDetail = "detail";
    publicstaticfinalStringFormRowDescriptorTypeDetailInline = "detailInline";
    publicstaticfinalStringFormRowDescriptorTypeTextView = "textView";
    publicstaticfinalStringFormRowDescriptorTypeTextViewInline = "textViewInline";
    publicstaticfinalStringFormRowDescriptorTypeURL = "url";
    publicstaticfinalStringFormRowDescriptorTypeEmail = "email";
    publicstaticfinalStringFormRowDescriptorTypeEmailInline = "emailInline";
    publicstaticfinalStringFormRowDescriptorTypePassword = "password";
    publicstaticfinalStringFormRowDescriptorTypePasswordInline = "passwordInline";
    publicstaticfinalStringFormRowDescriptorTypeNumber = "number";
    publicstaticfinalStringFormRowDescriptorTypeNumberInline = "numberInline";
    publicstaticfinalStringFormRowDescriptorTypeCurrency = "currency";
    publicstaticfinalStringFormRowDescriptorTypePhone = "phone";
    publicstaticfinalStringFormRowDescriptorTypeInteger = "integer";
    publicstaticfinalStringFormRowDescriptorTypeIntegerInline = "integerInline";
    publicstaticfinalStringFormRowDescriptorTypeSelectorSpinner = "selectorSpinner";
    publicstaticfinalStringFormRowDescriptorTypeSelectorSpinnerInline = "selectorSpinnerInline";
    publicstaticfinalStringFormRowDescriptorTypeSelectorPickerDialog = "selectorPickerDialog";
    publicstaticfinalStringFormRowDescriptorTypeDateInline = "dateInline";
    publicstaticfinalStringFormRowDescriptorTypeTimeInline = "timeInline";
    publicstaticfinalStringFormRowDescriptorTypeDate = "date";
    publicstaticfinalStringFormRowDescriptorTypeTime = "time";
    publicstaticfinalStringFormRowDescriptorTypeBooleanCheck = "booleanCheck";
    publicstaticfinalStringFormRowDescriptorTypeBooleanSwitch = "booleanSwitch";
    publicstaticfinalStringFormRowDescriptorTypeButton = "button";
    publicstaticfinalStringFormRowDescriptorTypeButtonInline = "buttonInline";
    publicstaticfinalStringFormRowDescriptorTypeSelectorSegmentedControl = "selectorSegmentedControl";
    publicstaticfinalStringFormRowDescriptorTypeSelectorSegmentedControlInline = "selectorSegmentedControlInline";
    
  • Coming elements: (Avaiable at XLForm)
    publicstaticfinalStringFormRowDescriptorTypeTwitter = "twitter";
    publicstaticfinalStringFormRowDescriptorTypeAccount = "account";
    publicstaticfinalStringFormRowDescriptorTypeSelectorPush = "selectorPush";
    publicstaticfinalStringFormRowDescriptorTypeSelectorActionSheet = "selectorActionSheet";
    publicstaticfinalStringFormRowDescriptorTypeSelectorAlertView = "selectorAlertView";
    publicstaticfinalStringFormRowDescriptorTypeSelectorPickerView = "selectorPickerView";
    publicstaticfinalStringFormRowDescriptorTypeSelectorPickerViewInline = "selectorPickerViewInline";
    publicstaticfinalStringFormRowDescriptorTypeMultipleSelector = "multipleSelector";
    publicstaticfinalStringFormRowDescriptorTypeSelectorLeftRight = "selectorLeftRight";
    publicstaticfinalStringFormRowDescriptorTypeDateTimeInline = "datetimeInline";
    publicstaticfinalStringFormRowDescriptorTypeDateTime = "datetime";
    publicstaticfinalStringFormRowDescriptorTypePicker = "picker";
    publicstaticfinalStringFormRowDescriptorTypeImage = "image";
    publicstaticfinalStringFormRowDescriptorTypeStepCounter = "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!

Releases

Packages

Contributors

Languages