{"id":13644599,"url":"https://github.com/thyrlian/AwesomeValidation","last_synced_at":"2025-04-21T10:33:40.134Z","repository":{"id":24577230,"uuid":"27984970","full_name":"thyrlian/AwesomeValidation","owner":"thyrlian","description":"Android validation library which helps developer boil down the tedious work to three easy steps.","archived":false,"fork":false,"pushed_at":"2022-05-01T10:05:15.000Z","size":1568,"stargazers_count":1150,"open_issues_count":9,"forks_count":184,"subscribers_count":43,"default_branch":"master","last_synced_at":"2025-04-09T14:07:56.964Z","etag":null,"topics":["android","form","forms","input","ui","validation"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thyrlian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"ko_fi":"thyrlian","patreon":"thyrlian"}},"created_at":"2014-12-14T05:52:41.000Z","updated_at":"2025-03-08T04:48:44.000Z","dependencies_parsed_at":"2022-08-07T11:01:10.424Z","dependency_job_id":null,"html_url":"https://github.com/thyrlian/AwesomeValidation","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAwesomeValidation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAwesomeValidation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAwesomeValidation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAwesomeValidation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thyrlian","download_url":"https://codeload.github.com/thyrlian/AwesomeValidation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250040509,"owners_count":21365120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","form","forms","input","ui","validation"],"created_at":"2024-08-02T01:02:09.018Z","updated_at":"2025-04-21T10:33:35.124Z","avatar_url":"https://github.com/thyrlian.png","language":"Java","funding_links":["https://ko-fi.com/thyrlian","https://patreon.com/thyrlian"],"categories":["表单","Libs","Validation"],"sub_categories":["\u003cA NAME=\"Other1\"\u003e\u003c/A\u003eOther"],"readme":"[![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14)\n[![Maven Central](https://img.shields.io/maven-central/v/com.basgeekball/awesome-validation)](https://search.maven.org/search?q=g:com.basgeekball%20AND%20a:awesome-validation)\n[![JitPack](https://jitpack.io/v/thyrlian/AwesomeValidation.svg)](https://jitpack.io/#thyrlian/AwesomeValidation)\n[![Build \u0026 Test](https://github.com/thyrlian/AwesomeValidation/workflows/Build%20\u0026%20Test/badge.svg)](https://github.com/thyrlian/AwesomeValidation/actions?query=workflow%3A%22Build+%26+Test%22)\n[![Travis CI Status](https://travis-ci.org/thyrlian/AwesomeValidation.svg?branch=master)](https://travis-ci.org/thyrlian/AwesomeValidation)\n[![CircleCI Status](https://circleci.com/gh/thyrlian/AwesomeValidation/tree/master.svg?style=shield\u0026circle-token=78719835860892697c8c54e1f22c872e086a0b09)](https://circleci.com/gh/thyrlian/AwesomeValidation/tree/master)\n[![Codacy Badge](https://api.codacy.com/project/badge/grade/dfea4a7a16c34cab9b810829fc221e19)](https://www.codacy.com/app/thyrlian/AwesomeValidation)\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AwesomeValidation-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/1605)\n[![Android Weekly](https://img.shields.io/badge/Android%20Weekly-%23142-brightgreen.svg)](http://androidweekly.net/issues/issue-142)\n[![Trusted By Many Apps](https://www.appbrain.com/stats/libraries/shield/awesomevalidation.svg)](https://www.appbrain.com/stats/libraries/details/awesomevalidation/awesomevalidation)\n[![AppBrain](https://img.shields.io/badge/AppBrain-stats-brightgreen.svg)](https://www.appbrain.com/stats/libraries/details/awesomevalidation/awesomevalidation)\n\n# AwesomeValidation\n\n## Introduction\n\nImplement validation for Android within only 3 steps.  Developers should focus on their awesome code, and let the library do the boilerplate.  And what's more, this could help keep your layout file clean.\n\n## Steps\n\n1. Declare validation style;\n2. Add validations;\n3. Set a point when to trigger validation.\n\n## Sample code\n\n```java\n// Step 1: designate a style\nAwesomeValidation mAwesomeValidation = new AwesomeValidation(BASIC);\n// or\nAwesomeValidation mAwesomeValidation = new AwesomeValidation(COLORATION);\nmAwesomeValidation.setColor(Color.YELLOW);  // optional, default color is RED if not set\n// or\nAwesomeValidation mAwesomeValidation = new AwesomeValidation(UNDERLABEL);\nmAwesomeValidation.setContext(this);  // mandatory for UNDERLABEL style\n// setUnderlabelColor is optional for UNDERLABEL style, by default it's holo_red_light\nmAwesomeValidation.setUnderlabelColorByResource(android.R.color.holo_orange_light); // optional for UNDERLABEL style\nmAwesomeValidation.setUnderlabelColor(ContextCompat.getColor(this, android.R.color.holo_orange_dark)); // optional for UNDERLABEL style\n// or\nAwesomeValidation mAwesomeValidation = new AwesomeValidation(TEXT_INPUT_LAYOUT);\nmAwesomeValidation.setTextInputLayoutErrorTextAppearance(R.style.TextInputLayoutErrorStyle); // optional, default color is holo_red_light if not set\n// by default, it automatically sets focus to the first failed input field after validation is triggered\n// you can disable this behavior by\nAwesomeValidation.disableAutoFocusOnFirstFailure();\n\n// Step 2: add validations\n// support regex string, java.util.regex.Pattern and Guava#Range\n// you can pass resource or string\nmAwesomeValidation.addValidation(activity, R.id.edt_name, \"[a-zA-Z\\\\s]+\", R.string.err_name);\nmAwesomeValidation.addValidation(activity, R.id.edt_tel, RegexTemplate.TELEPHONE, R.string.err_tel);\nmAwesomeValidation.addValidation(activity, R.id.edt_email, android.util.Patterns.EMAIL_ADDRESS, R.string.err_email);\nmAwesomeValidation.addValidation(activity, R.id.edt_year, Range.closed(1900, Calendar.getInstance().get(Calendar.YEAR)), R.string.err_year);\nmAwesomeValidation.addValidation(activity, R.id.edt_height, Range.closed(0.0f, 2.72f), R.string.err_height);\n// or\nmAwesomeValidation.addValidation(editText, \"regex\", \"Error info\");\n\n// to validate TextInputLayout, pass the TextInputLayout, not the embedded EditText\nAwesomeValidation mAwesomeValidation = new AwesomeValidation(TEXT_INPUT_LAYOUT);\nmAwesomeValidation.addValidation(activity, R.id.til_email, Patterns.EMAIL_ADDRESS, R.string.err_email);\n\n// to validate the confirmation of another field\nString regexPassword = \"(?=.*[a-z])(?=.*[A-Z])(?=.*[\\\\d])(?=.*[~`!@#\\\\$%\\\\^\u0026\\\\*\\\\(\\\\)\\\\-_\\\\+=\\\\{\\\\}\\\\[\\\\]\\\\|\\\\;:\\\"\u003c\u003e,./\\\\?]).{8,}\";\nmAwesomeValidation.addValidation(activity, R.id.edt_password, regexPassword, R.string.err_password);\n// to validate a confirmation field (don't validate any rule other than confirmation on confirmation field)\nmAwesomeValidation.addValidation(activity, R.id.edt_password_confirmation, R.id.edt_password, R.string.err_password_confirmation);\n\n// to validate with a simple custom validator function\nmAwesomeValidation.addValidation(activity, R.id.edt_birthday, new SimpleCustomValidation() {\n    @Override\n    public boolean compare(String input) {\n        // check if the age is \u003e= 18\n        try {\n            Calendar calendarBirthday = Calendar.getInstance();\n            Calendar calendarToday = Calendar.getInstance();\n            calendarBirthday.setTime(new SimpleDateFormat(\"dd/MM/yyyy\", Locale.US).parse(input));\n            int yearOfToday = calendarToday.get(Calendar.YEAR);\n            int yearOfBirthday = calendarBirthday.get(Calendar.YEAR);\n            if (yearOfToday - yearOfBirthday \u003e 18) {\n                return true;\n            } else if (yearOfToday - yearOfBirthday == 18) {\n                int monthOfToday = calendarToday.get(Calendar.MONTH);\n                int monthOfBirthday = calendarBirthday.get(Calendar.MONTH);\n                if (monthOfToday \u003e monthOfBirthday) {\n                    return true;\n                } else if (monthOfToday == monthOfBirthday) {\n                    if (calendarToday.get(Calendar.DAY_OF_MONTH) \u003e= calendarBirthday.get(Calendar.DAY_OF_MONTH)) {\n                        return true;\n                    }\n                }\n            }\n        } catch (ParseException e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n}, R.string.err_birth);\n\n// to validate with your own custom validator function, warn and clear the warning with your way\nmAwesomeValidation.addValidation(activity, R.id.spinner_tech_stacks, new CustomValidation() {\n    @Override\n    public boolean compare(ValidationHolder validationHolder) {\n        if (((Spinner) validationHolder.getView()).getSelectedItem().toString().equals(\"\u003c Please select one \u003e\")) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n}, new CustomValidationCallback() {\n    @Override\n    public void execute(ValidationHolder validationHolder) {\n        TextView textViewError = (TextView) ((Spinner) validationHolder.getView()).getSelectedView();\n        textViewError.setError(validationHolder.getErrMsg());\n        textViewError.setTextColor(Color.RED);\n    }\n}, new CustomErrorReset() {\n    @Override\n    public void reset(ValidationHolder validationHolder) {\n        TextView textViewError = (TextView) ((Spinner) validationHolder.getView()).getSelectedView();\n        textViewError.setError(null);\n        textViewError.setTextColor(Color.BLACK);\n    }\n}, R.string.err_tech_stacks);\n\n// Step 3: set a trigger\nfindViewById(R.id.btn_done).setOnClickListener(new View.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n        mAwesomeValidation.validate();\n    }\n});\n\n// Optional: remove validation failure information\nfindViewById(R.id.btn_clr).setOnClickListener(new View.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n        mAwesomeValidation.clear();\n    }\n});\n```\n\n## Attention\n\n* It works perfectly with **Fragment**, but please pay attention to Fragment's lifecycle.  You should set the `validate()` inside Fragment's `onActivityCreated` instead of `onCreateView` or any other early stage.\n\n* `UNDERLABEL` validation style doesn't support `ConstraintLayout` at the moment, please use other validation styles.  There is an open issue [here](https://github.com/thyrlian/AwesomeValidation/issues/33).\n\n## Import as dependency\n\nFor Gradle it's easy - just add below to your module's `build.gradle` (it's available on [Maven Central](https://search.maven.org/artifact/com.basgeekball/awesome-validation)):\n```gradle\ndependencies {\n    implementation 'com.basgeekball:awesome-validation:4.3'\n}\n```\n\nAlternatively, it's also available on [JitPack](https://jitpack.io/):\n* Add it in your root `build.gradle` at the end of repositories:\n```gradle\nallprojects {\n    repositories {\n        ...\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n* Add the dependency\n```gradle\ndependencies {\n    implementation 'com.github.thyrlian:AwesomeValidation:v4.3'\n    // you can also use the short commit hash to get a specific version\n    // implementation 'com.github.thyrlian:AwesomeValidation:GIT_COMMIT_HASH'\n}\n```\n\n## Screenshots\n\n\u003ca href=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_0.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_0.png\" height=\"600\"\u003e\u003c/a\u003e\n\n\u003ca href=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_1.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_1.png\" height=\"600\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_2.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_2.png\" height=\"600\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_3.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_3.png\" height=\"600\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_4.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AwesomeValidation/blob/master/resource/images/screenshot_4.png\" height=\"600\"\u003e\u003c/a\u003e\n\n## Release guide\n\n* Update version number in ***build.gradle***, ***gradle.properties*** and ***README***\n* Create new git tag: `v*.*`\n* Make sure a `local.properties` file which holds the necessary credentials is present under the [`library` directory](https://github.com/thyrlian/AwesomeValidation/tree/master/library)\n* Run `./gradlew clean build \u0026\u0026 ./gradlew :library:publishReleasePublicationToSonatypeRepository` to generate release file and upload it to [Nexus Repository](https://s01.oss.sonatype.org/#stagingRepositories)\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/thyrlian/AwesomeValidation.svg)](https://starchart.cc/thyrlian/AwesomeValidation)\n\n## License\n\nCopyright (c) 2014-2021 Jing Li. See the [LICENSE](https://github.com/thyrlian/AwesomeValidation/blob/master/LICENSE) file for license rights and limitations (MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthyrlian%2FAwesomeValidation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthyrlian%2FAwesomeValidation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthyrlian%2FAwesomeValidation/lists"}