在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):afollestad/vvalidator开源软件地址(OpenSource Url):https://github.com/afollestad/vvalidator开源编程语言(OpenSource Language):Kotlin 100.0%开源软件介绍(OpenSource Introduction):VValidator (BETA)View Validator, an easy-to-use form validation library for Kotlin & Android. Table of Contents
Gradle DependencyAdd this to your module's dependencies {
implementation 'com.afollestad:vvalidator:0.5.2'
} The BasicsVValidator works automatically within any Activity or AndroidX Fragment. class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.my_layout)
form {
input(R.id.your_edit_text) {
isNotEmpty()
}
submitWith(R.id.submit) { result ->
// this block is only called if form is valid.
// do something with a valid form state.
}
}
}
} The example above asserts that an edit text is not empty when a button a clicked. If that edit text is not empty when the button is clicked, the callback that the comment is in is invoked. Field TypesInputThe most basic type of supported view is an form {
input(R.id.view_id, name = "Optional Name") {
isNotEmpty()
isUri()
isUri().hasScheme("file")
isUri().that { uri -> uri.getQueryParameter("q") != null }
isUrl() // isUri() with defaults to require http/https and a hostname
isEmail()
isNumber()
isNumber().lessThan(5)
isNumber().atMost(5)
isNumber().exactly(5)
isNumber().atLeast(5)
isNumber().greaterThan(5)
isDecimal()
isDecimal().lessThan(5.2)
isDecimal().atMost(5.2)
isDecimal().exactly(5.2)
isDecimal().atLeast(5.2)
isDecimal().greaterThan(5.2)
length().lessThan(5)
length().atMost(5)
length().exactly(5)
length().atLeast(5)
length().greaterThan(5)
contains("Hello, World!")
contains("Hello, World!").ignoreCase()
matches("/^(\+?\d{1,3}|\d{1,4})$/")
// Custom assertions
assert("expected something") { view -> true }
}
} Input LayoutThis is basically identical to input. However, this targets
form {
inputLayout(R.id.view_id, name = "Optional Name") {
isNotEmpty()
isUri()
isUri().hasScheme("file")
isUri().that { uri -> uri.getQueryParameter("q") != null }
isUrl() // isUri() with defaults to require http/https and a hostname
isEmail()
isNumber()
isNumber().lessThan(5)
isNumber().atMost(5)
isNumber().exactly(5)
isNumber().atLeast(5)
isNumber().greaterThan(5)
isDecimal()
isDecimal().lessThan(5.2)
isDecimal().atMost(5.2)
isDecimal().exactly(5.2)
isDecimal().atLeast(5.2)
isDecimal().greaterThan(5.2)
length().lessThan(5)
length().atMost(5)
length().exactly(5)
length().atLeast(5)
length().greaterThan(5)
contains("Hello, World!")
contains("Hello, World!").ignoreCase()
matches("/^(\+?\d{1,3}|\d{1,4})$/")
// Custom assertions
assert("expected something") { view -> true }
}
} CheckableMore specifically, a form {
checkable(R.id.view_id, name = "Optional Name") {
isChecked()
isNotChecked()
// Custom assertions
assert("expected something") { view -> true }
}
} SpinnerA form {
spinner(R.id.view_id, name = "Optional Name") {
selection().exactly(1)
selection().lessThan(1)
selection().atMost(1)
selection().atLeast(1)
selection().greaterThan(1)
// Custom assertions
assert("expected something") { view -> true }
}
} SeekerAn form {
seeker(R.id.view_id, name = "Optional Name") {
progress().exactly(1)
progress().lessThan(1)
progress().atMost(1)
progress().atLeast(1)
progress().greaterThan(1)
// Custom assertions
assert("expected something") { view -> true }
}
} Assertion DescriptionsAll assertions expose a All assertions provide default validation failure messages, however they may not be what you want to display to your app users. form {
input(R.id.some_input) {
isNotEmpty().description("Please enter a value!")
}
spinner(R.id.some_spinner) {
selection()
.greaterThan(0)
.description("Please make a selection!")
}
} Validation ResultsYou get an instance of val myForm = form {
...
}
val result: FormResult = myForm.validate() A call to This result class gives you access to some detailed information. val result: FormResult = // ...
val isSuccess: Boolean = result.success()
val hasErrors: Boolean = result.hasErrors()
val errors: List<FieldError> = result.errors()
val values: List<FieldValue<*>> = result.values()
val singleValue: FieldValue<*> = result["Field Name"]
singleValue.asString()
singleValue.asInt()
singleValue.asLong()
singleValue.asFloat()
singleValue.asDouble()
singleValue.asBoolean() Each instance of val error: FieldError = // ...
// view ID
val id: Int = error.id
// field/view name
val name: String = error.name
// assertion description - what the failure is
val description: String = error.description
// the class of the assertion that failed
val assertionType: KClass<out Assertion<*, *>> = error.assertionType Error HandlingInput and Input Layout fields have default error handling because their underlying views have an error property provided by Android. However, other view types do not. This library provides an error hook for each field that you can use to display errors in the UI. form {
checkable(R.id.view_id, name = "Optional Name") {
isChecked()
onErrors { view, errors ->
// `view` here is a CompoundButton.
// `errors` here is a List<FieldError>, which can be empty to notify that there are no longer
// any validation errors.
val firstError: FieldError? = errors.firstOrNull()
// Show firstError.toString() in the UI.
}
}
} Submit WithYou can have this library automatically handle validating your form with the click of a form {
submitWith(R.id.button_id) { result ->
// Button was clicked and form is completely valid!
}
} Or even a val menu: Menu = // ...
form {
submitWith(menu, R.id.item_id) { result ->
// Item was clicked and form is completely valid!
}
} ConditionalsYou can apply assertions conditionally. Anything outside of a form {
input(R.id.input_site, name = "Site") {
conditional({ spinner.selectedItemPosition > 1 }) {
isUrl()
}
}
} The You can nest conditions as well: form {
input(...) {
conditional(...) {
isNotEmpty()
conditional(...) {
length().greaterThan(0)
}
conditional(...) {
isNumber()
}
}
}
} You may have noticed somewhere above that Supporting Additional ViewsIf you need to support a view type that isn't supported out of the box, you can create custom assertions and form fields. First, you'd need an assertion class that goes with your view. class MyView(context: Context) : EditText(context, null)
class MyAssertion : Assertion<MyView, MyAssertion>() {
override fun isValid(view: MyView): Boolean {
return view.text.isNotEmpty()
}
override fun defaultDescription(): String {
return "edit text should not be empty"
}
} Then you'll need a custom class MyField(
container: ValidationContainer,
view: MyView,
name: String
) : FormField<MyField, MyView, CharSequence>(container, id, name) {
init {
onErrors { myView, errors ->
// Do some sort of default error handling with views
}
}
// Your first custom assertion
fun myAssertion() = assert(MyAssertion())
override fun obtainValue(
id: Int,
name: String
): FieldValue<CharSequence>? {
val currentValue = view.text as? CharSequence ?: return null
return TextFieldValue(
id = id,
name = name,
value = currentValue
)
}
override fun startRealTimeValidation(debounce: Int) {
// See the "Real Time Validation" section below.
// You'd want to begin observing input to the view this field attaches to,
// and call `validate()` on this field when it changes. You should respect the
// `debounce` parameter as well.
}
} Finally, you can add an extension to fun Form.myView(
view: MyView,
name: String? = null,
builder: FieldBuilder<MyField>
) {
val newField = MyField(
container = container.checkAttached(),
view = view,
name = name
)
builder(newField)
appendField(newField)
}
fun Form.myView(
@IdRes id: Int,
name: String? = null,
builder: FieldBuilder<MyField>
) = myView(
view = container.getViewOrThrow(id),
name = name,
builder = builder
) Now, you can use it: form {
myView(R.id.seek_bar, name = "Optional Name") {
myAssertion()
}
} When the form is validated, your assertion's Real Time ValidationThis library provides an option to support real time validation. Rather than performing validation
when you call form {
useRealTimeValidation()
input(R.id.your_edit_text) {
isNotEmpty()
}
} With this example above, the form will automatically perform validation when the input field's text changes. Note that this does work with all field types, not just input fields.
Another optional parameter on form {
useRealTimeValidation(disableSubmit = true)
input(R.id.your_edit_text) {
isNotEmpty()
}
submitWith(R.id.my_button) {
// Do something
}
} |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论