Compare commits
41 Commits
Author | SHA1 | Date |
---|---|---|
Jenly | 3dfb90809a | 3 years ago |
Jenly | 7f23dfb4ef | 3 years ago |
Jenly | 08e5c8fbb6 | 3 years ago |
Jenly | ac88d07c1b | 3 years ago |
Jenly | 4ee839fe2c | 3 years ago |
Jenly | 1bf77be43a | 3 years ago |
Jenly | 5c848ee830 | 3 years ago |
Jenly | 5183b3b9fe | 3 years ago |
Jenly | 9a426841c9 | 3 years ago |
Jenly | 09972ded00 | 3 years ago |
Jenly | 5139dfbfff | 3 years ago |
Jenly | 41a1f88d33 | 3 years ago |
Jenly | ff6eca1ab2 | 3 years ago |
Jenly | e93a677d1b | 4 years ago |
Jenly | 3ee62c3b32 | 4 years ago |
Jenly | 727cd08b98 | 4 years ago |
Jenly | 898b3912b6 | 4 years ago |
Jenly | 3a685c958f | 4 years ago |
Jenly | 2677d67d70 | 4 years ago |
Jenly | b5832c92da | 4 years ago |
Jenly | 6d04cf4575 | 4 years ago |
Jenly | 372b1ad30f | 4 years ago |
Jenly | d2874564d7 | 4 years ago |
Jenly | dbfbac55de | 4 years ago |
Jenly | d3a759374c | 4 years ago |
Jenly | 5c1c0c1ad6 | 4 years ago |
Jenly | 2d56132692 | 4 years ago |
jenly1314 | 8e657d1ecb | 5 years ago |
jenly1314 | 636e202e2f | 5 years ago |
jenly1314 | e38db4de11 | 5 years ago |
Jenly | 69a93148a2 | 5 years ago |
jenly1314 | 3838ad6685 | 5 years ago |
jenly1314 | d29c1348ad | 5 years ago |
jenly1314 | 82a9b36a7d | 5 years ago |
jenly1314 | a10687ad07 | 5 years ago |
jenly1314 | 0a7e40dfce | 5 years ago |
jenly1314 | ea8f2603a8 | 5 years ago |
jenly1314 | 0a8de018b8 | 5 years ago |
jenly1314 | 4eee3649c9 | 5 years ago |
jenly1314 | ef8b918f1f | 5 years ago |
jenly1314 | 55e92e5f17 | 5 years ago |
@ -0,0 +1,27 @@ |
||||
version: 2 |
||||
jobs: |
||||
build: |
||||
working_directory: ~/code |
||||
docker: |
||||
- image: circleci/android:api-28 |
||||
environment: |
||||
JVM_OPTS: -Xmx3200m |
||||
steps: |
||||
- checkout |
||||
- restore_cache: |
||||
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} |
||||
- run: |
||||
name: Download Dependencies |
||||
command: ./gradlew androidDependencies |
||||
- save_cache: |
||||
paths: |
||||
- ~/.gradle |
||||
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} |
||||
- run: |
||||
name: Run Tests |
||||
command: ./gradlew lint test |
||||
- store_artifacts: |
||||
path: app/build/reports |
||||
destination: reports |
||||
- store_test_results: |
||||
path: app/build/test-results |
@ -0,0 +1,20 @@ |
||||
name: Android CI |
||||
|
||||
on: |
||||
push: |
||||
branches: [ master ] |
||||
pull_request: |
||||
branches: [ master ] |
||||
|
||||
jobs: |
||||
build: |
||||
runs-on: ubuntu-latest |
||||
|
||||
steps: |
||||
- uses: actions/checkout@v2 |
||||
- name: Set up JDK 1.8 |
||||
uses: actions/setup-java@v1 |
||||
with: |
||||
java-version: 1.8 |
||||
- name: Build with Gradle |
||||
run: ./gradlew build |
Binary file not shown.
@ -1,52 +0,0 @@ |
||||
<component name="ProjectCodeStyleConfiguration"> |
||||
<code_scheme name="Project" version="173"> |
||||
<DBN-PSQL> |
||||
<case-options enabled="true"> |
||||
<option name="KEYWORD_CASE" value="lower" /> |
||||
<option name="FUNCTION_CASE" value="lower" /> |
||||
<option name="PARAMETER_CASE" value="lower" /> |
||||
<option name="DATATYPE_CASE" value="lower" /> |
||||
<option name="OBJECT_CASE" value="preserve" /> |
||||
</case-options> |
||||
<formatting-settings enabled="false" /> |
||||
</DBN-PSQL> |
||||
<DBN-SQL> |
||||
<case-options enabled="true"> |
||||
<option name="KEYWORD_CASE" value="lower" /> |
||||
<option name="FUNCTION_CASE" value="lower" /> |
||||
<option name="PARAMETER_CASE" value="lower" /> |
||||
<option name="DATATYPE_CASE" value="lower" /> |
||||
<option name="OBJECT_CASE" value="preserve" /> |
||||
</case-options> |
||||
<formatting-settings enabled="false"> |
||||
<option name="STATEMENT_SPACING" value="one_line" /> |
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" /> |
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" /> |
||||
</formatting-settings> |
||||
</DBN-SQL> |
||||
<DBN-PSQL> |
||||
<case-options enabled="true"> |
||||
<option name="KEYWORD_CASE" value="lower" /> |
||||
<option name="FUNCTION_CASE" value="lower" /> |
||||
<option name="PARAMETER_CASE" value="lower" /> |
||||
<option name="DATATYPE_CASE" value="lower" /> |
||||
<option name="OBJECT_CASE" value="preserve" /> |
||||
</case-options> |
||||
<formatting-settings enabled="false" /> |
||||
</DBN-PSQL> |
||||
<DBN-SQL> |
||||
<case-options enabled="true"> |
||||
<option name="KEYWORD_CASE" value="lower" /> |
||||
<option name="FUNCTION_CASE" value="lower" /> |
||||
<option name="PARAMETER_CASE" value="lower" /> |
||||
<option name="DATATYPE_CASE" value="lower" /> |
||||
<option name="OBJECT_CASE" value="preserve" /> |
||||
</case-options> |
||||
<formatting-settings enabled="false"> |
||||
<option name="STATEMENT_SPACING" value="one_line" /> |
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" /> |
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" /> |
||||
</formatting-settings> |
||||
</DBN-SQL> |
||||
</code_scheme> |
||||
</component> |
@ -1,8 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="CompilerConfiguration"> |
||||
<annotationProcessing> |
||||
<profile default="true" name="Default" enabled="true" /> |
||||
</annotationProcessing> |
||||
</component> |
||||
</project> |
@ -1,456 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="DBNavigator.Project.DataEditorManager"> |
||||
<record-view-column-sorting-type value="BY_INDEX" /> |
||||
<value-preview-text-wrapping value="true" /> |
||||
<value-preview-pinned value="false" /> |
||||
</component> |
||||
<component name="DBNavigator.Project.DataExportManager"> |
||||
<export-instructions> |
||||
<create-header value="true" /> |
||||
<quote-values-containing-separator value="true" /> |
||||
<quote-all-values value="false" /> |
||||
<value-separator value="" /> |
||||
<file-name value="" /> |
||||
<file-location value="" /> |
||||
<scope value="GLOBAL" /> |
||||
<destination value="FILE" /> |
||||
<format value="EXCEL" /> |
||||
<charset value="GBK" /> |
||||
</export-instructions> |
||||
</component> |
||||
<component name="DBNavigator.Project.DatabaseBrowserManager"> |
||||
<autoscroll-to-editor value="false" /> |
||||
<autoscroll-from-editor value="true" /> |
||||
<show-object-properties value="true" /> |
||||
<loaded-nodes /> |
||||
</component> |
||||
<component name="DBNavigator.Project.DatabaseFileManager"> |
||||
<open-files /> |
||||
</component> |
||||
<component name="DBNavigator.Project.EditorStateManager"> |
||||
<last-used-providers /> |
||||
</component> |
||||
<component name="DBNavigator.Project.MethodExecutionManager"> |
||||
<method-browser /> |
||||
<execution-history> |
||||
<group-entries value="true" /> |
||||
<execution-inputs /> |
||||
</execution-history> |
||||
<argument-values-cache /> |
||||
</component> |
||||
<component name="DBNavigator.Project.ObjectDependencyManager"> |
||||
<last-used-dependency-type value="INCOMING" /> |
||||
</component> |
||||
<component name="DBNavigator.Project.ObjectQuickFilterManager"> |
||||
<last-used-operator value="EQUAL" /> |
||||
<filters /> |
||||
</component> |
||||
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true"> |
||||
<recently-used-interfaces /> |
||||
</component> |
||||
<component name="DBNavigator.Project.Settings"> |
||||
<connections /> |
||||
<browser-settings> |
||||
<general> |
||||
<display-mode value="TABBED" /> |
||||
<navigation-history-size value="100" /> |
||||
<show-object-details value="false" /> |
||||
</general> |
||||
<filters> |
||||
<object-type-filter> |
||||
<object-type name="SCHEMA" enabled="true" /> |
||||
<object-type name="USER" enabled="true" /> |
||||
<object-type name="ROLE" enabled="true" /> |
||||
<object-type name="PRIVILEGE" enabled="true" /> |
||||
<object-type name="CHARSET" enabled="true" /> |
||||
<object-type name="TABLE" enabled="true" /> |
||||
<object-type name="VIEW" enabled="true" /> |
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" /> |
||||
<object-type name="NESTED_TABLE" enabled="true" /> |
||||
<object-type name="COLUMN" enabled="true" /> |
||||
<object-type name="INDEX" enabled="true" /> |
||||
<object-type name="CONSTRAINT" enabled="true" /> |
||||
<object-type name="DATASET_TRIGGER" enabled="true" /> |
||||
<object-type name="DATABASE_TRIGGER" enabled="true" /> |
||||
<object-type name="SYNONYM" enabled="true" /> |
||||
<object-type name="SEQUENCE" enabled="true" /> |
||||
<object-type name="PROCEDURE" enabled="true" /> |
||||
<object-type name="FUNCTION" enabled="true" /> |
||||
<object-type name="PACKAGE" enabled="true" /> |
||||
<object-type name="TYPE" enabled="true" /> |
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" /> |
||||
<object-type name="ARGUMENT" enabled="true" /> |
||||
<object-type name="DIMENSION" enabled="true" /> |
||||
<object-type name="CLUSTER" enabled="true" /> |
||||
<object-type name="DBLINK" enabled="true" /> |
||||
</object-type-filter> |
||||
</filters> |
||||
<sorting> |
||||
<object-type name="COLUMN" sorting-type="NAME" /> |
||||
<object-type name="FUNCTION" sorting-type="NAME" /> |
||||
<object-type name="PROCEDURE" sorting-type="NAME" /> |
||||
<object-type name="ARGUMENT" sorting-type="POSITION" /> |
||||
</sorting> |
||||
<default-editors> |
||||
<object-type name="VIEW" editor-type="SELECTION" /> |
||||
<object-type name="PACKAGE" editor-type="SELECTION" /> |
||||
<object-type name="TYPE" editor-type="SELECTION" /> |
||||
</default-editors> |
||||
</browser-settings> |
||||
<navigation-settings> |
||||
<lookup-filters> |
||||
<lookup-objects> |
||||
<object-type name="SCHEMA" enabled="true" /> |
||||
<object-type name="USER" enabled="false" /> |
||||
<object-type name="ROLE" enabled="false" /> |
||||
<object-type name="PRIVILEGE" enabled="false" /> |
||||
<object-type name="CHARSET" enabled="false" /> |
||||
<object-type name="TABLE" enabled="true" /> |
||||
<object-type name="VIEW" enabled="true" /> |
||||
<object-type name="MATERIALIZED VIEW" enabled="true" /> |
||||
<object-type name="NESTED TABLE" enabled="false" /> |
||||
<object-type name="COLUMN" enabled="false" /> |
||||
<object-type name="INDEX" enabled="true" /> |
||||
<object-type name="CONSTRAINT" enabled="true" /> |
||||
<object-type name="DATASET TRIGGER" enabled="true" /> |
||||
<object-type name="DATABASE TRIGGER" enabled="true" /> |
||||
<object-type name="SYNONYM" enabled="false" /> |
||||
<object-type name="SEQUENCE" enabled="true" /> |
||||
<object-type name="PROCEDURE" enabled="true" /> |
||||
<object-type name="FUNCTION" enabled="true" /> |
||||
<object-type name="PACKAGE" enabled="true" /> |
||||
<object-type name="TYPE" enabled="true" /> |
||||
<object-type name="TYPE ATTRIBUTE" enabled="false" /> |
||||
<object-type name="ARGUMENT" enabled="false" /> |
||||
<object-type name="DIMENSION" enabled="false" /> |
||||
<object-type name="CLUSTER" enabled="false" /> |
||||
<object-type name="DBLINK" enabled="true" /> |
||||
</lookup-objects> |
||||
<force-database-load value="false" /> |
||||
<prompt-connection-selection value="true" /> |
||||
<prompt-schema-selection value="true" /> |
||||
</lookup-filters> |
||||
</navigation-settings> |
||||
<dataset-grid-settings> |
||||
<general> |
||||
<enable-zooming value="true" /> |
||||
<enable-column-tooltip value="true" /> |
||||
</general> |
||||
<sorting> |
||||
<nulls-first value="true" /> |
||||
<max-sorting-columns value="4" /> |
||||
</sorting> |
||||
<tracking-columns> |
||||
<columnNames value="" /> |
||||
<visible value="true" /> |
||||
<editable value="false" /> |
||||
</tracking-columns> |
||||
</dataset-grid-settings> |
||||
<dataset-editor-settings> |
||||
<text-editor-popup> |
||||
<active value="false" /> |
||||
<active-if-empty value="false" /> |
||||
<data-length-threshold value="100" /> |
||||
<popup-delay value="1000" /> |
||||
</text-editor-popup> |
||||
<values-actions-popup> |
||||
<show-popup-button value="true" /> |
||||
<element-count-threshold value="1000" /> |
||||
<data-length-threshold value="250" /> |
||||
</values-actions-popup> |
||||
<general> |
||||
<fetch-block-size value="100" /> |
||||
<fetch-timeout value="30" /> |
||||
<trim-whitespaces value="true" /> |
||||
<convert-empty-strings-to-null value="true" /> |
||||
<select-content-on-cell-edit value="true" /> |
||||
<large-value-preview-active value="true" /> |
||||
</general> |
||||
<filters> |
||||
<prompt-filter-dialog value="true" /> |
||||
<default-filter-type value="BASIC" /> |
||||
</filters> |
||||
<qualified-text-editor text-length-threshold="300"> |
||||
<content-types> |
||||
<content-type name="Text" enabled="true" /> |
||||
<content-type name="Properties" enabled="true" /> |
||||
<content-type name="XML" enabled="true" /> |
||||
<content-type name="DTD" enabled="true" /> |
||||
<content-type name="HTML" enabled="true" /> |
||||
<content-type name="XHTML" enabled="true" /> |
||||
<content-type name="Java" enabled="true" /> |
||||
<content-type name="SQL" enabled="true" /> |
||||
<content-type name="PL/SQL" enabled="true" /> |
||||
<content-type name="Groovy" enabled="true" /> |
||||
<content-type name="AIDL" enabled="true" /> |
||||
<content-type name="YAML" enabled="true" /> |
||||
<content-type name="Manifest" enabled="true" /> |
||||
</content-types> |
||||
</qualified-text-editor> |
||||
<record-navigation> |
||||
<navigation-target value="VIEWER" /> |
||||
</record-navigation> |
||||
</dataset-editor-settings> |
||||
<code-editor-settings> |
||||
<general> |
||||
<show-object-navigation-gutter value="false" /> |
||||
<show-spec-declaration-navigation-gutter value="true" /> |
||||
<enable-spellchecking value="true" /> |
||||
<enable-reference-spellchecking value="false" /> |
||||
</general> |
||||
<confirmations> |
||||
<save-changes value="false" /> |
||||
<revert-changes value="true" /> |
||||
</confirmations> |
||||
</code-editor-settings> |
||||
<code-completion-settings> |
||||
<filters> |
||||
<basic-filter> |
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" /> |
||||
<filter-element type="OBJECT" id="schema" selected="true" /> |
||||
<filter-element type="OBJECT" id="role" selected="true" /> |
||||
<filter-element type="OBJECT" id="user" selected="true" /> |
||||
<filter-element type="OBJECT" id="privilege" selected="true" /> |
||||
<user-schema> |
||||
<filter-element type="OBJECT" id="table" selected="true" /> |
||||
<filter-element type="OBJECT" id="view" selected="true" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="true" /> |
||||
<filter-element type="OBJECT" id="index" selected="true" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="true" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="true" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="false" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="true" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="true" /> |
||||
<filter-element type="OBJECT" id="function" selected="true" /> |
||||
<filter-element type="OBJECT" id="package" selected="true" /> |
||||
<filter-element type="OBJECT" id="type" selected="true" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="true" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="true" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="true" /> |
||||
</user-schema> |
||||
<public-schema> |
||||
<filter-element type="OBJECT" id="table" selected="false" /> |
||||
<filter-element type="OBJECT" id="view" selected="false" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="false" /> |
||||
<filter-element type="OBJECT" id="index" selected="false" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="false" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="false" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="false" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="false" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="false" /> |
||||
<filter-element type="OBJECT" id="function" selected="false" /> |
||||
<filter-element type="OBJECT" id="package" selected="false" /> |
||||
<filter-element type="OBJECT" id="type" selected="false" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="false" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="false" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="false" /> |
||||
</public-schema> |
||||
<any-schema> |
||||
<filter-element type="OBJECT" id="table" selected="true" /> |
||||
<filter-element type="OBJECT" id="view" selected="true" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="true" /> |
||||
<filter-element type="OBJECT" id="index" selected="true" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="true" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="true" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="true" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="true" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="true" /> |
||||
<filter-element type="OBJECT" id="function" selected="true" /> |
||||
<filter-element type="OBJECT" id="package" selected="true" /> |
||||
<filter-element type="OBJECT" id="type" selected="true" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="true" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="true" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="true" /> |
||||
</any-schema> |
||||
</basic-filter> |
||||
<extended-filter> |
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" /> |
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" /> |
||||
<filter-element type="OBJECT" id="schema" selected="true" /> |
||||
<filter-element type="OBJECT" id="user" selected="true" /> |
||||
<filter-element type="OBJECT" id="role" selected="true" /> |
||||
<filter-element type="OBJECT" id="privilege" selected="true" /> |
||||
<user-schema> |
||||
<filter-element type="OBJECT" id="table" selected="true" /> |
||||
<filter-element type="OBJECT" id="view" selected="true" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="true" /> |
||||
<filter-element type="OBJECT" id="index" selected="true" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="true" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="true" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="true" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="true" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="true" /> |
||||
<filter-element type="OBJECT" id="function" selected="true" /> |
||||
<filter-element type="OBJECT" id="package" selected="true" /> |
||||
<filter-element type="OBJECT" id="type" selected="true" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="true" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="true" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="true" /> |
||||
</user-schema> |
||||
<public-schema> |
||||
<filter-element type="OBJECT" id="table" selected="true" /> |
||||
<filter-element type="OBJECT" id="view" selected="true" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="true" /> |
||||
<filter-element type="OBJECT" id="index" selected="true" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="true" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="true" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="true" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="true" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="true" /> |
||||
<filter-element type="OBJECT" id="function" selected="true" /> |
||||
<filter-element type="OBJECT" id="package" selected="true" /> |
||||
<filter-element type="OBJECT" id="type" selected="true" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="true" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="true" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="true" /> |
||||
</public-schema> |
||||
<any-schema> |
||||
<filter-element type="OBJECT" id="table" selected="true" /> |
||||
<filter-element type="OBJECT" id="view" selected="true" /> |
||||
<filter-element type="OBJECT" id="materialized view" selected="true" /> |
||||
<filter-element type="OBJECT" id="index" selected="true" /> |
||||
<filter-element type="OBJECT" id="constraint" selected="true" /> |
||||
<filter-element type="OBJECT" id="trigger" selected="true" /> |
||||
<filter-element type="OBJECT" id="synonym" selected="true" /> |
||||
<filter-element type="OBJECT" id="sequence" selected="true" /> |
||||
<filter-element type="OBJECT" id="procedure" selected="true" /> |
||||
<filter-element type="OBJECT" id="function" selected="true" /> |
||||
<filter-element type="OBJECT" id="package" selected="true" /> |
||||
<filter-element type="OBJECT" id="type" selected="true" /> |
||||
<filter-element type="OBJECT" id="dimension" selected="true" /> |
||||
<filter-element type="OBJECT" id="cluster" selected="true" /> |
||||
<filter-element type="OBJECT" id="dblink" selected="true" /> |
||||
</any-schema> |
||||
</extended-filter> |
||||
</filters> |
||||
<sorting enabled="true"> |
||||
<sorting-element type="RESERVED_WORD" id="keyword" /> |
||||
<sorting-element type="RESERVED_WORD" id="datatype" /> |
||||
<sorting-element type="OBJECT" id="column" /> |
||||
<sorting-element type="OBJECT" id="table" /> |
||||
<sorting-element type="OBJECT" id="view" /> |
||||
<sorting-element type="OBJECT" id="materialized view" /> |
||||
<sorting-element type="OBJECT" id="index" /> |
||||
<sorting-element type="OBJECT" id="constraint" /> |
||||
<sorting-element type="OBJECT" id="trigger" /> |
||||
<sorting-element type="OBJECT" id="synonym" /> |
||||
<sorting-element type="OBJECT" id="sequence" /> |
||||
<sorting-element type="OBJECT" id="procedure" /> |
||||
<sorting-element type="OBJECT" id="function" /> |
||||
<sorting-element type="OBJECT" id="package" /> |
||||
<sorting-element type="OBJECT" id="type" /> |
||||
<sorting-element type="OBJECT" id="dimension" /> |
||||
<sorting-element type="OBJECT" id="cluster" /> |
||||
<sorting-element type="OBJECT" id="dblink" /> |
||||
<sorting-element type="OBJECT" id="schema" /> |
||||
<sorting-element type="OBJECT" id="role" /> |
||||
<sorting-element type="OBJECT" id="user" /> |
||||
<sorting-element type="RESERVED_WORD" id="function" /> |
||||
<sorting-element type="RESERVED_WORD" id="parameter" /> |
||||
</sorting> |
||||
<format> |
||||
<enforce-code-style-case value="true" /> |
||||
</format> |
||||
</code-completion-settings> |
||||
<execution-engine-settings> |
||||
<statement-execution> |
||||
<fetch-block-size value="100" /> |
||||
<execution-timeout value="20" /> |
||||
<debug-execution-timeout value="600" /> |
||||
<focus-result value="false" /> |
||||
<prompt-execution value="false" /> |
||||
</statement-execution> |
||||
<script-execution> |
||||
<command-line-interfaces /> |
||||
<execution-timeout value="300" /> |
||||
</script-execution> |
||||
<method-execution> |
||||
<execution-timeout value="30" /> |
||||
<debug-execution-timeout value="600" /> |
||||
<parameter-history-size value="10" /> |
||||
</method-execution> |
||||
</execution-engine-settings> |
||||
<operation-settings> |
||||
<transactions> |
||||
<uncommitted-changes> |
||||
<on-project-close value="ASK" /> |
||||
<on-disconnect value="ASK" /> |
||||
<on-autocommit-toggle value="ASK" /> |
||||
</uncommitted-changes> |
||||
<multiple-uncommitted-changes> |
||||
<on-commit value="ASK" /> |
||||
<on-rollback value="ASK" /> |
||||
</multiple-uncommitted-changes> |
||||
</transactions> |
||||
<session-browser> |
||||
<disconnect-session value="ASK" /> |
||||
<kill-session value="ASK" /> |
||||
<reload-on-filter-change value="false" /> |
||||
</session-browser> |
||||
<compiler> |
||||
<compile-type value="KEEP" /> |
||||
<compile-dependencies value="ASK" /> |
||||
<always-show-controls value="false" /> |
||||
</compiler> |
||||
<debugger> |
||||
<debugger-type value="ASK" /> |
||||
<use-generic-runners value="true" /> |
||||
</debugger> |
||||
</operation-settings> |
||||
<ddl-file-settings> |
||||
<extensions> |
||||
<mapping file-type-id="VIEW" extensions="vw" /> |
||||
<mapping file-type-id="TRIGGER" extensions="trg" /> |
||||
<mapping file-type-id="PROCEDURE" extensions="prc" /> |
||||
<mapping file-type-id="FUNCTION" extensions="fnc" /> |
||||
<mapping file-type-id="PACKAGE" extensions="pkg" /> |
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" /> |
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" /> |
||||
<mapping file-type-id="TYPE" extensions="tpe" /> |
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" /> |
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" /> |
||||
</extensions> |
||||
<general> |
||||
<lookup-ddl-files value="true" /> |
||||
<create-ddl-files value="false" /> |
||||
<synchronize-ddl-files value="true" /> |
||||
<use-qualified-names value="false" /> |
||||
<make-scripts-rerunnable value="true" /> |
||||
</general> |
||||
</ddl-file-settings> |
||||
<general-settings> |
||||
<regional-settings> |
||||
<date-format value="MEDIUM" /> |
||||
<number-format value="UNGROUPED" /> |
||||
<locale value="SYSTEM_DEFAULT" /> |
||||
<use-custom-formats value="false" /> |
||||
</regional-settings> |
||||
<environment> |
||||
<environment-types> |
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" /> |
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" /> |
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" /> |
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" /> |
||||
</environment-types> |
||||
<visibility-settings> |
||||
<connection-tabs value="true" /> |
||||
<dialog-headers value="true" /> |
||||
<object-editor-tabs value="true" /> |
||||
<script-editor-tabs value="false" /> |
||||
<execution-result-tabs value="true" /> |
||||
</visibility-settings> |
||||
</environment> |
||||
</general-settings> |
||||
</component> |
||||
<component name="DBNavigator.Project.StatementExecutionManager"> |
||||
<execution-variables /> |
||||
</component> |
||||
</project> |
@ -1,6 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="Encoding"> |
||||
<file url="PROJECT" charset="UTF-8" /> |
||||
</component> |
||||
</project> |
@ -1,20 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="GradleSettings"> |
||||
<option name="linkedExternalProjectsSettings"> |
||||
<GradleProjectSettings> |
||||
<option name="distributionType" value="DEFAULT_WRAPPED" /> |
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" /> |
||||
<option name="modules"> |
||||
<set> |
||||
<option value="$PROJECT_DIR$" /> |
||||
<option value="$PROJECT_DIR$/app" /> |
||||
<option value="$PROJECT_DIR$/app-dialog" /> |
||||
<option value="$PROJECT_DIR$/app-updater" /> |
||||
</set> |
||||
</option> |
||||
<option name="resolveModulePerSourceSet" value="false" /> |
||||
</GradleProjectSettings> |
||||
</option> |
||||
</component> |
||||
</project> |
@ -1,83 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="MarkdownProjectSettings" wasCopied="true"> |
||||
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="true" showSelectionInPreview="true" openRemoteLinks="true" replaceUnicodeEmoji="false" lastLayoutSetsDefault="false"> |
||||
<PanelProvider> |
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" /> |
||||
</PanelProvider> |
||||
</PreviewSettings> |
||||
<ParserSettings gitHubSyntaxChange="false" emojiShortcuts="0" emojiImages="0"> |
||||
<PegdownExtensions> |
||||
<option name="ABBREVIATIONS" value="false" /> |
||||
<option name="ANCHORLINKS" value="true" /> |
||||
<option name="ASIDE" value="false" /> |
||||
<option name="ATXHEADERSPACE" value="true" /> |
||||
<option name="AUTOLINKS" value="true" /> |
||||
<option name="DEFINITIONS" value="false" /> |
||||
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" /> |
||||
<option name="FENCED_CODE_BLOCKS" value="true" /> |
||||
<option name="FOOTNOTES" value="false" /> |
||||
<option name="HARDWRAPS" value="false" /> |
||||
<option name="HTML_DEEP_PARSER" value="false" /> |
||||
<option name="INSERTED" value="false" /> |
||||
<option name="QUOTES" value="false" /> |
||||
<option name="RELAXEDHRULES" value="true" /> |
||||
<option name="SMARTS" value="false" /> |
||||
<option name="STRIKETHROUGH" value="true" /> |
||||
<option name="SUBSCRIPT" value="false" /> |
||||
<option name="SUPERSCRIPT" value="false" /> |
||||
<option name="SUPPRESS_HTML_BLOCKS" value="false" /> |
||||
<option name="SUPPRESS_INLINE_HTML" value="false" /> |
||||
<option name="TABLES" value="true" /> |
||||
<option name="TASKLISTITEMS" value="true" /> |
||||
<option name="TOC" value="false" /> |
||||
<option name="WIKILINKS" value="true" /> |
||||
</PegdownExtensions> |
||||
<ParserOptions> |
||||
<option name="ADMONITION_EXT" value="false" /> |
||||
<option name="ATTRIBUTES_EXT" value="false" /> |
||||
<option name="COMMONMARK_LISTS" value="false" /> |
||||
<option name="DUMMY" value="false" /> |
||||
<option name="EMOJI_SHORTCUTS" value="true" /> |
||||
<option name="ENUMERATED_REFERENCES_EXT" value="false" /> |
||||
<option name="FLEXMARK_FRONT_MATTER" value="false" /> |
||||
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="true" /> |
||||
<option name="GFM_TABLE_RENDERING" value="true" /> |
||||
<option name="GITBOOK_URL_ENCODING" value="false" /> |
||||
<option name="GITHUB_LISTS" value="true" /> |
||||
<option name="GITHUB_WIKI_LINKS" value="true" /> |
||||
<option name="GITLAB_EXT" value="false" /> |
||||
<option name="GITLAB_MATH_EXT" value="false" /> |
||||
<option name="GITLAB_MERMAID_EXT" value="false" /> |
||||
<option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" /> |
||||
<option name="HEADER_ID_NO_DUPED_DASHES" value="false" /> |
||||
<option name="JEKYLL_FRONT_MATTER" value="false" /> |
||||
<option name="MACROS_EXT" value="false" /> |
||||
<option name="NO_TEXT_ATTRIBUTES" value="false" /> |
||||
<option name="PARSE_HTML_ANCHOR_ID" value="false" /> |
||||
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" /> |
||||
</ParserOptions> |
||||
</ParserSettings> |
||||
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false"> |
||||
<GeneratorProvider> |
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" /> |
||||
</GeneratorProvider> |
||||
<headerTop /> |
||||
<headerBottom /> |
||||
<bodyTop /> |
||||
<bodyBottom /> |
||||
</HtmlSettings> |
||||
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="false" isCssTextEnabled="false" isDynamicPageWidth="true"> |
||||
<StylesheetProvider> |
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" /> |
||||
</StylesheetProvider> |
||||
<ScriptProviders /> |
||||
<cssText /> |
||||
<cssUriHistory /> |
||||
</CssSettings> |
||||
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" /> |
||||
<LinkMapSettings> |
||||
<textMaps /> |
||||
</LinkMapSettings> |
||||
</component> |
||||
</project> |
@ -1,3 +0,0 @@ |
||||
<component name="MarkdownNavigator.ProfileManager"> |
||||
<settings default="" pdf-export="" plain-text-search-scope="Project Files" /> |
||||
</component> |
@ -1,38 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="NullableNotNullManager"> |
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" /> |
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> |
||||
<option name="myNullables"> |
||||
<value> |
||||
<list size="7"> |
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" /> |
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" /> |
||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" /> |
||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" /> |
||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" /> |
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" /> |
||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" /> |
||||
</list> |
||||
</value> |
||||
</option> |
||||
<option name="myNotNulls"> |
||||
<value> |
||||
<list size="6"> |
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" /> |
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" /> |
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" /> |
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" /> |
||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" /> |
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" /> |
||||
</list> |
||||
</value> |
||||
</option> |
||||
</component> |
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> |
||||
<output url="file://$PROJECT_DIR$/build/classes" /> |
||||
</component> |
||||
<component name="ProjectType"> |
||||
<option name="id" value="Android" /> |
||||
</component> |
||||
</project> |
@ -1,12 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="RunConfigurationProducerService"> |
||||
<option name="ignoredProducers"> |
||||
<set> |
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> |
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> |
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> |
||||
</set> |
||||
</option> |
||||
</component> |
||||
</project> |
@ -1,6 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="VcsDirectoryMappings"> |
||||
<mapping directory="" vcs="Git" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,3 @@ |
||||
POM_NAME=App Dialog |
||||
POM_ARTIFACT_ID=app-dialog |
||||
POM_PACKAGING=aar |
@ -1,204 +1,761 @@ |
||||
package com.king.app.dialog; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
import android.support.annotation.IdRes; |
||||
import android.support.annotation.LayoutRes; |
||||
import android.support.annotation.NonNull; |
||||
import android.content.res.ColorStateList; |
||||
import android.graphics.Bitmap; |
||||
import android.graphics.Typeface; |
||||
import android.graphics.drawable.Drawable; |
||||
import android.text.util.Linkify; |
||||
import android.util.SparseArray; |
||||
import android.util.TypedValue; |
||||
import android.view.LayoutInflater; |
||||
import android.view.View; |
||||
import android.widget.Button; |
||||
import android.widget.CompoundButton; |
||||
import android.widget.ImageView; |
||||
import android.widget.ProgressBar; |
||||
import android.widget.RatingBar; |
||||
import android.widget.TextView; |
||||
|
||||
import java.util.regex.Pattern; |
||||
|
||||
import androidx.annotation.ColorInt; |
||||
import androidx.annotation.DrawableRes; |
||||
import androidx.annotation.IdRes; |
||||
import androidx.annotation.LayoutRes; |
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
import androidx.annotation.StringRes; |
||||
|
||||
/** |
||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
* App 对话框配置 |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class AppDialogConfig { |
||||
public class AppDialogConfig extends BaseDialogConfig{ |
||||
|
||||
private Context context; |
||||
|
||||
private SparseArray<View> views; |
||||
|
||||
private View view; |
||||
|
||||
private ViewHolder viewHolder; |
||||
|
||||
/** |
||||
* 布局ID |
||||
* 构造 |
||||
* @param context 上下文 |
||||
*/ |
||||
private @LayoutRes int layoutId = R.layout.app_dialog; |
||||
public AppDialogConfig(@NonNull Context context){ |
||||
this(context, R.layout.app_dialog); |
||||
} |
||||
|
||||
/** |
||||
* 标题视图ID |
||||
* 构造 |
||||
* @param context 上下文 |
||||
* @param layoutId 布局ID |
||||
*/ |
||||
private @IdRes int titleId = R.id.tvDialogTitle; |
||||
public AppDialogConfig(@NonNull Context context, @LayoutRes int layoutId){ |
||||
super(layoutId); |
||||
this.context = context; |
||||
views = new SparseArray<>(); |
||||
} |
||||
|
||||
/** |
||||
* 内容视图ID |
||||
* 获取上下文 |
||||
* @return {@link #context} |
||||
*/ |
||||
private @IdRes int contentId = R.id.tvDialogContent; |
||||
public Context getContext(){ |
||||
return context; |
||||
} |
||||
|
||||
/** |
||||
* 取消视图ID(左边按钮) |
||||
* 获取对话框视图 |
||||
* @param context 上下文 |
||||
* @return 对话框视图 |
||||
* @deprecated 即将废弃,下一个版本可能会移除此方法。 |
||||
*/ |
||||
private @IdRes int cancelId = R.id.btnDialogCancel; |
||||
@Deprecated |
||||
public View getView(@NonNull Context context){ |
||||
return getDialogView(); |
||||
} |
||||
|
||||
/** |
||||
* 确定视图ID(右边按钮) |
||||
* 获取对话框视图 |
||||
* @return 对话框视图 |
||||
*/ |
||||
private @IdRes int okId = R.id.btnDialogOK; |
||||
private View getDialogView(){ |
||||
if(view == null){ |
||||
view = LayoutInflater.from(context).inflate(getLayoutId(),null); |
||||
} |
||||
return view; |
||||
} |
||||
|
||||
/** |
||||
* 按钮中间分割线ID |
||||
* 通过视图ID查找对应的视图 |
||||
* @param id 视图ID |
||||
* @param <T> 对应的视图类 |
||||
* @return 视图ID对应的视图 |
||||
*/ |
||||
private @IdRes int line = R.id.line; |
||||
private <T extends View> T findView(@IdRes int id){ |
||||
return getDialogView().findViewById(id); |
||||
} |
||||
|
||||
/** |
||||
* 标题文本 |
||||
* 根据视图ID获取对应的视图 |
||||
* @param id 视图ID |
||||
* @param <T> 对应的视图类 |
||||
* @return 视图ID对应的视图 |
||||
*/ |
||||
private CharSequence title; |
||||
public <T extends View> T getView(@IdRes int id){ |
||||
View v = views.get(id); |
||||
if(v == null){ |
||||
v = findView(id); |
||||
views.put(id,v); |
||||
} |
||||
|
||||
return (T)v; |
||||
} |
||||
|
||||
/** |
||||
* 内容文本 |
||||
* 通过{@link AppDialogConfig} 创建一个视图 |
||||
* @return {@link View} |
||||
*/ |
||||
private CharSequence content; |
||||
View buildAppDialogView(){ |
||||
TextView tvDialogTitle = getView(titleId); |
||||
if(tvDialogTitle != null){ |
||||
setText(tvDialogTitle,title); |
||||
tvDialogTitle.setVisibility(isHideTitle ? View.GONE : View.VISIBLE); |
||||
} |
||||
|
||||
TextView tvDialogContent = getView(contentId); |
||||
if(tvDialogContent != null){ |
||||
setText(tvDialogContent,content); |
||||
} |
||||
|
||||
Button btnDialogCancel = getView(cancelId); |
||||
if(btnDialogCancel != null){ |
||||
setText(btnDialogCancel,cancel); |
||||
btnDialogCancel.setOnClickListener(onClickCancel != null ? onClickCancel : AppDialog.INSTANCE.mOnClickDismissDialog); |
||||
btnDialogCancel.setVisibility(isHideCancel ? View.GONE : View.VISIBLE); |
||||
} |
||||
|
||||
View line = getView(lineId); |
||||
if(line != null){ |
||||
line.setVisibility(isHideCancel ? View.GONE : View.VISIBLE); |
||||
} |
||||
|
||||
Button btnDialogConfirm = getView(confirmId); |
||||
if(btnDialogConfirm != null){ |
||||
setText(btnDialogConfirm,confirm); |
||||
btnDialogConfirm.setOnClickListener(onClickConfirm != null ? onClickConfirm : AppDialog.INSTANCE.mOnClickDismissDialog); |
||||
|
||||
} |
||||
|
||||
return view; |
||||
} |
||||
|
||||
|
||||
private void setText(TextView tv, CharSequence text){ |
||||
if(text != null){ |
||||
tv.setText(text); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 取消按钮文本 |
||||
* 获取 {@link ViewHolder} |
||||
* @return |
||||
*/ |
||||
private CharSequence cancel; |
||||
public final ViewHolder getViewHolder(){ |
||||
if(viewHolder == null){ |
||||
viewHolder = new ViewHolder(); |
||||
} |
||||
return viewHolder; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 确定按钮文本 |
||||
* ViewHolder主要提供控件的一些常用设置(适用于Dialog,不适用于DialogFragment) |
||||
*/ |
||||
private CharSequence ok; |
||||
public final class ViewHolder { |
||||
|
||||
private ViewHolder(){ |
||||
|
||||
} |
||||
|
||||
//---------------------- 控件常用设置
|
||||
|
||||
/** |
||||
* 是否隐藏取消按钮,如果隐藏取消则底部只显示一个按钮 |
||||
* 设置视图的背景色 |
||||
* {@link View#setBackgroundResource(int)} |
||||
* @param id 视图ID |
||||
* @param resId Drawable资源ID |
||||
* @return {@link View} |
||||
*/ |
||||
private boolean isHideCancel; |
||||
public View setBackgroundResource(@IdRes int id,@DrawableRes int resId){ |
||||
View v = getView(id); |
||||
v.setBackgroundResource(resId); |
||||
return v; |
||||
} |
||||
|
||||
/** |
||||
* 是否隐藏标题 |
||||
* 设置视图的背景色 |
||||
* {@link View#setBackground(Drawable)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link View} |
||||
*/ |
||||
private boolean isHideTitle; |
||||
@TargetApi(16) |
||||
public View setBackground(@IdRes int id, Drawable drawable){ |
||||
View v = getView(id); |
||||
v.setBackground(drawable); |
||||
return v; |
||||
} |
||||
|
||||
private View.OnClickListener onClickCancel; |
||||
/** |
||||
* 设置视图的背景色 |
||||
* {@link View#setBackgroundColor(int)} |
||||
* @param id 视图ID |
||||
* @param color 颜色 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setBackgroundColor(@IdRes int id,@ColorInt int color){ |
||||
View v = getView(id); |
||||
v.setBackgroundColor(color); |
||||
return v; |
||||
} |
||||
|
||||
private View.OnClickListener onClickOk; |
||||
/** |
||||
* 设置视图的标签 |
||||
* {@link View#setTag(Object)} |
||||
* @param id 视图ID |
||||
* @param tag 标签 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setTag(@IdRes int id,Object tag){ |
||||
View v = getView(id); |
||||
v.setTag(tag); |
||||
return v; |
||||
} |
||||
|
||||
private View view; |
||||
/** |
||||
* 设置视图的标签 |
||||
* {@link View#setTag(int, Object)} |
||||
* @param id 视图ID |
||||
* @param key 标签的key |
||||
* @param tag 标签 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setTag(@IdRes int id,int key,Object tag){ |
||||
View v = getView(id); |
||||
v.setTag(key,tag); |
||||
return v; |
||||
} |
||||
|
||||
public @LayoutRes int getLayoutId() { |
||||
return layoutId; |
||||
/** |
||||
* 设置视图的可见性 |
||||
* {@link View#setVisibility(int)} |
||||
* @param id 视图ID |
||||
* @param visibility 可见性 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setVisibility(@IdRes int id, int visibility){ |
||||
View v = getView(id); |
||||
v.setVisibility(visibility); |
||||
return v; |
||||
} |
||||
|
||||
public AppDialogConfig setLayoutId(@LayoutRes int layoutId) { |
||||
this.layoutId = layoutId; |
||||
return this; |
||||
/** |
||||
* 设置视图的可见性 |
||||
* {@link View#setVisibility(int)} |
||||
* @param id 视图ID |
||||
* @param isVisible 是否可见 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setVisibility(@IdRes int id,boolean isVisible){ |
||||
View v = getView(id); |
||||
if(isVisible){ |
||||
v.setVisibility(View.VISIBLE); |
||||
}else{ |
||||
v.setVisibility(View.GONE); |
||||
} |
||||
return v; |
||||
} |
||||
|
||||
public int getTitleId() { |
||||
return titleId; |
||||
/** |
||||
* 设置视图的透明度 |
||||
* {@link View#setAlpha(float)} |
||||
* @param id 视图ID |
||||
* @param alpha 透明度 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setAlpha(@IdRes int id,float alpha){ |
||||
View v = getView(id); |
||||
v.setAlpha(alpha); |
||||
return v; |
||||
} |
||||
|
||||
public AppDialogConfig setTitleId(@IdRes int titleId) { |
||||
this.titleId = titleId; |
||||
return this; |
||||
/** |
||||
* 设置视图左方的复合绘图 {@link Drawable} |
||||
* {@link #setCompoundDrawables(int, Drawable, Drawable, Drawable, Drawable)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawableLeft(@IdRes int id,Drawable drawable){ |
||||
return setCompoundDrawables(id,drawable,null,null,null); |
||||
} |
||||
|
||||
public @IdRes int getContentId() { |
||||
return contentId; |
||||
/** |
||||
* 设置视图上方的复合绘图 {@link Drawable} |
||||
* {@link #setCompoundDrawables(int, Drawable, Drawable, Drawable, Drawable)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawableTop(@IdRes int id,Drawable drawable){ |
||||
return setCompoundDrawables(id,null,drawable,null,null); |
||||
} |
||||
|
||||
public AppDialogConfig setContentId(@IdRes int contentId) { |
||||
this.contentId = contentId; |
||||
return this; |
||||
/** |
||||
* 设置视图右方的复合绘图 {@link Drawable} |
||||
* {@link #setCompoundDrawables(int, Drawable, Drawable, Drawable, Drawable)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawableRight(@IdRes int id,Drawable drawable){ |
||||
return setCompoundDrawables(id,null,null,drawable,null); |
||||
} |
||||
|
||||
public @IdRes int getCancelId() { |
||||
return cancelId; |
||||
/** |
||||
* 设置视图下方的复合绘图 {@link Drawable} |
||||
* {@link #setCompoundDrawables(int, Drawable, Drawable, Drawable, Drawable)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawableBottom(@IdRes int id,Drawable drawable){ |
||||
return setCompoundDrawables(id,null,null,null,drawable); |
||||
} |
||||
|
||||
public AppDialogConfig setCancelId(@IdRes int cancelId) { |
||||
this.cancelId = cancelId; |
||||
return this; |
||||
/** |
||||
* 设置视图的复合绘图 {@link Drawable} |
||||
* {@link TextView#setCompoundDrawables(Drawable, Drawable, Drawable, Drawable)} |
||||
* @param id 视图ID |
||||
* @param left 左方的Drawable |
||||
* @param top 上方的Drawable |
||||
* @param right 右方的Drawable |
||||
* @param bottom 下方的Drawable |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawables(@IdRes int id,Drawable left,Drawable top,Drawable right,Drawable bottom){ |
||||
TextView tv = getView(id); |
||||
tv.setCompoundDrawables(left, top, right, bottom); |
||||
return tv; |
||||
} |
||||
|
||||
public @IdRes int getOkId() { |
||||
return okId; |
||||
/** |
||||
* 设置视图的可填充内距 |
||||
* {@link TextView#setCompoundDrawablePadding(int)} |
||||
* @param id 视图ID |
||||
* @param padding 内填充间距 |
||||
* @return |
||||
*/ |
||||
public TextView setCompoundDrawablePadding(@IdRes int id,int padding){ |
||||
TextView tv = getView(id); |
||||
tv.setCompoundDrawablePadding(padding); |
||||
return tv; |
||||
} |
||||
|
||||
public AppDialogConfig setOkId(@IdRes int okId) { |
||||
this.okId = okId; |
||||
return this; |
||||
/** |
||||
* 设置视图的内在的复合绘图 {@link Drawable} |
||||
* {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)} |
||||
* @param id 视图ID |
||||
* @param left 左方的Drawable |
||||
* @param top 上方的Drawable |
||||
* @param right 右方的Drawable |
||||
* @param bottom 下方的Drawable |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setCompoundDrawablesWithIntrinsicBounds(@IdRes int id, @Nullable Drawable left,@Nullable Drawable top,@Nullable Drawable right,@Nullable Drawable bottom){ |
||||
TextView tv = getView(id); |
||||
tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom); |
||||
return tv; |
||||
} |
||||
|
||||
public @IdRes int getLine() { |
||||
return line; |
||||
/** |
||||
* 设置文本内容 |
||||
* {@link TextView#setText(int)} |
||||
* @param id 视图ID |
||||
* @param resId 字符串资源ID |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setText(@IdRes int id,@StringRes int resId){ |
||||
TextView tv = getView(id); |
||||
tv.setText(resId); |
||||
return tv; |
||||
} |
||||
|
||||
public AppDialogConfig setLine(@IdRes int line) { |
||||
this.line = line; |
||||
return this; |
||||
/** |
||||
* 设置文本内容 |
||||
* {@link TextView#setText(CharSequence)} |
||||
* @param id 视图ID |
||||
* @param text 文本 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setText(@IdRes int id,CharSequence text){ |
||||
TextView tv = getView(id); |
||||
tv.setText(text); |
||||
return tv; |
||||
} |
||||
|
||||
public CharSequence getTitle() { |
||||
return title; |
||||
/** |
||||
* 设置字体颜色 |
||||
* {@link TextView#setTextColor(int)} |
||||
* @param id 视图ID |
||||
* @param color 颜色 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTextColor(@IdRes int id,int color){ |
||||
TextView tv = getView(id); |
||||
tv.setTextColor(color); |
||||
return tv; |
||||
} |
||||
|
||||
public AppDialogConfig setTitle(CharSequence title) { |
||||
this.title = title; |
||||
return this; |
||||
/** |
||||
* 设置字体颜色 |
||||
* {@link TextView#setTextColor(ColorStateList)} |
||||
* @param id 视图ID |
||||
* @param colors 颜色状态列表 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTextColor(@IdRes int id,@NonNull ColorStateList colors){ |
||||
TextView tv = getView(id); |
||||
tv.setTextColor(colors); |
||||
return tv; |
||||
} |
||||
|
||||
public CharSequence getContent() { |
||||
return content; |
||||
/** |
||||
* 设置字体大小 |
||||
* {@link TextView#setTextSize(float)} |
||||
* @param id 视图ID |
||||
* @param size 字体大小(单位:sp) |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTextSize(@IdRes int id,float size){ |
||||
return setTextSize(id, size); |
||||
} |
||||
|
||||
public AppDialogConfig setContent(CharSequence content) { |
||||
this.content = content; |
||||
return this; |
||||
/** |
||||
* 设置字体大小 |
||||
* {@link TextView#setTextSize(int, float)} |
||||
* @param id 视图ID |
||||
* @param unit 单位;推荐使用 {@link TypedValue#COMPLEX_UNIT_SP} |
||||
* @param size 字体大小 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTextSize(@IdRes int id,int unit, float size){ |
||||
TextView tv = getView(id); |
||||
tv.setTextSize(unit,size); |
||||
return tv; |
||||
} |
||||
|
||||
public CharSequence getCancel() { |
||||
return cancel; |
||||
/** |
||||
* 设置字体 |
||||
* {@link TextView#setTypeface(Typeface)} |
||||
* @param id 视图ID |
||||
* @param tf 字体 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTypeface(@IdRes int id,@Nullable Typeface tf){ |
||||
TextView tv = getView(id); |
||||
tv.setTypeface(tf); |
||||
return tv; |
||||
} |
||||
|
||||
public AppDialogConfig setCancel(CharSequence cancel) { |
||||
this.cancel = cancel; |
||||
return this; |
||||
/** |
||||
* 设置字体 |
||||
* {@link TextView#setTypeface(Typeface, int)} |
||||
* @param id 视图ID |
||||
* @param tf 字体 |
||||
* @param style 字体样式 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView setTypeface(@IdRes int id,@Nullable Typeface tf, int style){ |
||||
TextView tv = getView(id); |
||||
tv.setTypeface(tf,style); |
||||
return tv; |
||||
} |
||||
|
||||
public CharSequence getOk() { |
||||
return ok; |
||||
/** |
||||
* 添加链接 |
||||
* {@link #addLinks(int, int)} |
||||
* @param id 视图ID |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView addLinks(@IdRes int id){ |
||||
return addLinks(id,Linkify.ALL); |
||||
} |
||||
|
||||
public AppDialogConfig setOk(CharSequence ok) { |
||||
this.ok = ok; |
||||
return this; |
||||
/** |
||||
* 添加链接 |
||||
* {@link Linkify#addLinks(TextView, int)} |
||||
* @param id 视图ID |
||||
* @param mask 连接掩码;如:{@link Linkify#ALL} |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView addLinks(@IdRes int id,int mask){ |
||||
TextView tv = getView(id); |
||||
Linkify.addLinks(tv,mask); |
||||
return tv; |
||||
} |
||||
|
||||
public boolean isHideCancel() { |
||||
return isHideCancel; |
||||
/** |
||||
* 添加链接 |
||||
* {@link Linkify#addLinks(TextView, Pattern, String)} |
||||
* @param id 视图ID |
||||
* @param pattern 正则表达式模式 |
||||
* @param scheme 方案 |
||||
* @return {@link TextView} |
||||
*/ |
||||
public TextView addLinks(@IdRes int id,@NonNull Pattern pattern,@Nullable String scheme){ |
||||
TextView tv = getView(id); |
||||
Linkify.addLinks(tv,pattern,scheme); |
||||
return tv; |
||||
} |
||||
|
||||
public AppDialogConfig setHideCancel(boolean hideCancel) { |
||||
isHideCancel = hideCancel; |
||||
return this; |
||||
/** |
||||
* 根据Drawable资源ID设置图像 |
||||
* {@link ImageView#setImageResource(int)} |
||||
* @param id 视图ID |
||||
* @param resId Drawable资源ID |
||||
* @return {@link ImageView} |
||||
*/ |
||||
public ImageView setImageResource(@IdRes int id,@DrawableRes int resId){ |
||||
ImageView iv = getView(id); |
||||
iv.setImageResource(resId); |
||||
return iv; |
||||
} |
||||
|
||||
public boolean isHideTitle(){ |
||||
return isHideTitle; |
||||
/** |
||||
* 根据位图设置图像 |
||||
* {@link ImageView#setImageBitmap(Bitmap)} |
||||
* @param id 视图ID |
||||
* @param bitmap 位图 |
||||
* @return {@link ImageView} |
||||
*/ |
||||
public ImageView setImageBitmap(@IdRes int id, Bitmap bitmap){ |
||||
ImageView iv = getView(id); |
||||
iv.setImageBitmap(bitmap); |
||||
return iv; |
||||
} |
||||
|
||||
public AppDialogConfig setHideTitle(boolean hideTitle){ |
||||
isHideTitle = hideTitle; |
||||
return this; |
||||
/** |
||||
* 根据 {@link Drawable} 设置图像 |
||||
* {@link ImageView#setImageResource(int)} |
||||
* @param id 视图ID |
||||
* @param drawable {@link Drawable} |
||||
* @return {@link ImageView} |
||||
*/ |
||||
public ImageView setImageDrawable(@IdRes int id,Drawable drawable){ |
||||
ImageView iv = getView(id); |
||||
iv.setImageDrawable(drawable); |
||||
return iv; |
||||
} |
||||
|
||||
public View.OnClickListener getOnClickCancel() { |
||||
return onClickCancel; |
||||
/** |
||||
* 设置是否选中 |
||||
* {@link CompoundButton#setChecked(boolean)} |
||||
* @param id 视图ID |
||||
* @param isChecked 是否选中 |
||||
* @return {@link CompoundButton} |
||||
*/ |
||||
public CompoundButton setChecked(@IdRes int id, boolean isChecked){ |
||||
CompoundButton cb = getView(id); |
||||
cb.setChecked(isChecked); |
||||
return cb; |
||||
} |
||||
|
||||
public AppDialogConfig setOnClickCancel(View.OnClickListener onClickCancel) { |
||||
this.onClickCancel = onClickCancel; |
||||
return this; |
||||
/** |
||||
* 是否选中 |
||||
* {@link CompoundButton#isChecked()} |
||||
* @param id 视图ID |
||||
* @return {@code true} or {@code false} |
||||
*/ |
||||
public boolean isChecked(@IdRes int id){ |
||||
CompoundButton cb = getView(id); |
||||
return cb.isChecked(); |
||||
} |
||||
|
||||
public View.OnClickListener getOnClickOk() { |
||||
return onClickOk; |
||||
/** |
||||
* 切换 |
||||
* {@link CompoundButton#toggle()} |
||||
* @param id 视图ID |
||||
* @return {@link CompoundButton} |
||||
*/ |
||||
public CompoundButton toggle(@IdRes int id){ |
||||
CompoundButton cb = getView(id); |
||||
cb.toggle(); |
||||
return cb; |
||||
} |
||||
|
||||
public AppDialogConfig setOnClickOk(View.OnClickListener onClickOk) { |
||||
this.onClickOk = onClickOk; |
||||
return this; |
||||
/** |
||||
* 设置进度值 |
||||
* {@link ProgressBar#setProgress(int)} |
||||
* @param id 视图ID |
||||
* @param progress 进度 |
||||
* @return {@link ProgressBar} |
||||
*/ |
||||
public ProgressBar setProgress(@IdRes int id, int progress){ |
||||
ProgressBar progressBar = getView(id); |
||||
progressBar.setProgress(progress); |
||||
return progressBar; |
||||
} |
||||
|
||||
public View getView(@NonNull Context context){ |
||||
if(view == null){ |
||||
view = LayoutInflater.from(context).inflate(layoutId,null); |
||||
/** |
||||
* 设置最大进度值 |
||||
* {@link ProgressBar#setMax(int)} |
||||
* @param id 视图ID |
||||
* @param max 最大进度值 |
||||
* @return {@link ProgressBar} |
||||
*/ |
||||
public ProgressBar setMax(@IdRes int id,int max){ |
||||
ProgressBar progressBar = getView(id); |
||||
progressBar.setMax(max); |
||||
return progressBar; |
||||
} |
||||
|
||||
/** |
||||
* 设置评分 |
||||
* {@link RatingBar#setRating(float)} |
||||
* @param id 视图ID |
||||
* @param rating 评分 |
||||
* @return {@link RatingBar} |
||||
*/ |
||||
public RatingBar setRating(@IdRes int id, float rating){ |
||||
RatingBar ratingBar = getView(id); |
||||
ratingBar.setRating(rating); |
||||
return ratingBar; |
||||
} |
||||
|
||||
/** |
||||
* 设置评分和最大评分值 |
||||
* {@link RatingBar#setRating(float)} and {@link RatingBar#setMax(int)} |
||||
* @param id 视图ID |
||||
* @param rating 评分 |
||||
* @param max 最大评分值 |
||||
* @return {@link RatingBar} |
||||
*/ |
||||
public RatingBar setRating(@IdRes int id,float rating,int max){ |
||||
RatingBar ratingBar = getView(id); |
||||
ratingBar.setRating(rating); |
||||
ratingBar.setMax(max); |
||||
return ratingBar; |
||||
} |
||||
|
||||
/** |
||||
* 设置星星数量 |
||||
* {@link RatingBar#setNumStars(int)} |
||||
* @param id 视图ID |
||||
* @param numStars 星星数量 |
||||
* @return {@link RatingBar} |
||||
*/ |
||||
public RatingBar setNumStars(@IdRes int id,int numStars){ |
||||
RatingBar ratingBar = getView(id); |
||||
ratingBar.setNumStars(numStars); |
||||
return ratingBar; |
||||
} |
||||
|
||||
/** |
||||
* 设置是否选择 |
||||
* {@link View#setSelected(boolean)} |
||||
* @param id 视图ID |
||||
* @param selected 是否选择 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setSelected(@IdRes int id,boolean selected){ |
||||
View view = getView(id); |
||||
view.setSelected(selected); |
||||
return view; |
||||
} |
||||
|
||||
/** |
||||
* 是否选择 |
||||
* {@link View#isSelected()} |
||||
* @param id 视图ID |
||||
* @return {@code true} or {@code false} |
||||
*/ |
||||
public boolean isSelected(@IdRes int id){ |
||||
return getView(id).isSelected(); |
||||
} |
||||
|
||||
/** |
||||
* 设置是否启用 |
||||
* {@link View#setEnabled(boolean)} |
||||
* @param id 视图ID |
||||
* @param enabled 是否启用 |
||||
* @return {@link View} |
||||
*/ |
||||
public View setEnabled(@IdRes int id,boolean enabled){ |
||||
View view = getView(id); |
||||
view.setEnabled(enabled); |
||||
return view; |
||||
} |
||||
|
||||
/** |
||||
* 是否启用 |
||||
* {@link View#isEnabled()} |
||||
* @param id 视图ID |
||||
* @return {@code true} or {@code false} |
||||
*/ |
||||
public boolean isEnabled(@IdRes int id){ |
||||
return getView(id).isEnabled(); |
||||
} |
||||
|
||||
|
||||
//---------------------- 监听事件
|
||||
|
||||
/** |
||||
* 设置点击监听事 |
||||
* {@link View#setOnClickListener(View.OnClickListener)} |
||||
* @param id 视图ID |
||||
* @param onClickListener {@link View.OnClickListener} |
||||
*/ |
||||
public void setOnClickListener(@IdRes int id, View.OnClickListener onClickListener){ |
||||
getView(id).setOnClickListener(onClickListener); |
||||
} |
||||
|
||||
/** |
||||
* 设置触摸监听 |
||||
* {@link View#setOnTouchListener(View.OnTouchListener)} |
||||
* @param id 视图ID |
||||
* @param onTouchListener {@link View.OnTouchListener} |
||||
*/ |
||||
public void setOnTouchListener(@IdRes int id, View.OnTouchListener onTouchListener){ |
||||
getView(id).setOnTouchListener(onTouchListener); |
||||
} |
||||
|
||||
/** |
||||
* 设置长按监听 |
||||
* {@link View#setOnLongClickListener(View.OnLongClickListener)} |
||||
* @param id 视图ID |
||||
* @param onLongClickListener {@link View.OnLongClickListener} |
||||
*/ |
||||
public void setOnLongClickListener(@IdRes int id, View.OnLongClickListener onLongClickListener){ |
||||
getView(id).setOnLongClickListener(onLongClickListener); |
||||
} |
||||
|
||||
/** |
||||
* 设置按键监听 |
||||
* {@link View#setOnKeyListener(View.OnKeyListener)} |
||||
* @param id 视图ID |
||||
* @param onKeyListener {@link View.OnKeyListener} |
||||
*/ |
||||
public void setOnKeyListener(@IdRes int id, View.OnKeyListener onKeyListener){ |
||||
getView(id).setOnKeyListener(onKeyListener); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,669 @@ |
||||
package com.king.app.dialog; |
||||
|
||||
import android.content.Context; |
||||
import android.view.Gravity; |
||||
import android.view.View; |
||||
import android.view.WindowManager; |
||||
|
||||
import androidx.annotation.IdRes; |
||||
import androidx.annotation.LayoutRes; |
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.StringRes; |
||||
import androidx.annotation.StyleRes; |
||||
|
||||
/** |
||||
* 基础对话框配置 |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class BaseDialogConfig { |
||||
|
||||
/** |
||||
* 布局ID |
||||
*/ |
||||
@LayoutRes int layoutId; |
||||
/** |
||||
* 标题视图ID |
||||
*/ |
||||
@IdRes int titleId = R.id.tvDialogTitle; |
||||
/** |
||||
* 内容视图ID |
||||
*/ |
||||
@IdRes int contentId = R.id.tvDialogContent; |
||||
/** |
||||
* 取消视图ID(左边按钮) |
||||
*/ |
||||
@IdRes int cancelId = R.id.btnDialogCancel; |
||||
/** |
||||
* 确定视图ID(右边按钮) |
||||
*/ |
||||
@IdRes int confirmId = R.id.btnDialogConfirm; |
||||
/** |
||||
* 按钮中间分割线ID |
||||
*/ |
||||
@IdRes int lineId = R.id.line; |
||||
|
||||
/** |
||||
* 样式ID |
||||
*/ |
||||
@StyleRes int styleId = R.style.app_dialog; |
||||
|
||||
/** |
||||
* 对话框动画样式ID |
||||
*/ |
||||
@StyleRes int animationStyleId = R.style.app_dialog_scale_animation; |
||||
|
||||
/** |
||||
* 标题文本 |
||||
*/ |
||||
CharSequence title; |
||||
/** |
||||
* 内容文本 |
||||
*/ |
||||
CharSequence content; |
||||
/** |
||||
* 取消按钮文本 |
||||
*/ |
||||
CharSequence cancel; |
||||
/** |
||||
* 确定按钮文本 |
||||
*/ |
||||
CharSequence confirm; |
||||
/** |
||||
* 是否隐藏取消按钮,如果隐藏取消则底部只显示一个按钮 |
||||
*/ |
||||
boolean isHideCancel; |
||||
/** |
||||
* 是否隐藏标题 |
||||
*/ |
||||
boolean isHideTitle; |
||||
|
||||
/** |
||||
* 宽度比例,根据屏幕宽度计算得来 |
||||
*/ |
||||
float widthRatio = AppDialog.INSTANCE.DEFAULT_WIDTH_RATIO; |
||||
|
||||
/** |
||||
* Dialog对齐方式 {@link WindowManager.LayoutParams#gravity} |
||||
* |
||||
*/ |
||||
int gravity = Gravity.NO_GRAVITY; |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#x} |
||||
*/ |
||||
int x; |
||||
/** |
||||
* {@link WindowManager.LayoutParams#y} |
||||
*/ |
||||
int y; |
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalMargin} |
||||
*/ |
||||
float verticalMargin; |
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalMargin} |
||||
*/ |
||||
float horizontalMargin; |
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalWeight} |
||||
*/ |
||||
float horizontalWeight; |
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalWeight} |
||||
*/ |
||||
float verticalWeight; |
||||
|
||||
View.OnClickListener onClickCancel; |
||||
|
||||
View.OnClickListener onClickConfirm; |
||||
|
||||
/** |
||||
* 构造 |
||||
*/ |
||||
public BaseDialogConfig(){ |
||||
this(R.layout.app_dialog); |
||||
} |
||||
|
||||
/** |
||||
* 构造 |
||||
* @param layoutId 布局ID |
||||
*/ |
||||
public BaseDialogConfig(@LayoutRes int layoutId){ |
||||
this.layoutId = layoutId; |
||||
} |
||||
|
||||
/** |
||||
* 布局ID |
||||
* @return 布局ID |
||||
*/ |
||||
public @LayoutRes int getLayoutId() { |
||||
return layoutId; |
||||
} |
||||
|
||||
/** |
||||
* 此方法即将废弃,请通过构造{@link #BaseDialogConfig(int)}来初始化 |
||||
* @param layoutId 布局ID |
||||
* @return {@link BaseDialogConfig} |
||||
* @deprecated 即将废弃,下一个版本可能会移除此方法 |
||||
*/ |
||||
@Deprecated |
||||
public BaseDialogConfig setLayoutId(@LayoutRes int layoutId) { |
||||
this.layoutId = layoutId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 标题视图ID |
||||
* @return 视图ID |
||||
*/ |
||||
public int getTitleId() { |
||||
return titleId; |
||||
} |
||||
|
||||
/** |
||||
* 设置标题视图ID |
||||
* @param titleId 视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setTitleId(@IdRes int titleId) { |
||||
this.titleId = titleId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 样式ID |
||||
* @return 样式ID |
||||
*/ |
||||
public int getStyleId() { |
||||
return styleId; |
||||
} |
||||
|
||||
/** |
||||
* 设置Dialog样式ID(仅对Dialog有效,如果使用的是DialogFragment,请使用{@link #setAnimationStyleId(int)}) |
||||
* @param styleId |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setStyleId(@StyleRes int styleId) { |
||||
this.styleId = styleId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 对话框动画样式ID |
||||
* @return |
||||
*/ |
||||
public int getAnimationStyleId(){ |
||||
return animationStyleId; |
||||
} |
||||
|
||||
/** |
||||
* 对话框动画样式ID (仅对DialogFragment有效,如果使用的是Dialog,请使用{@link #setStyleId(int)}) |
||||
* @param animationStyleId |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setAnimationStyleId(@StyleRes int animationStyleId) { |
||||
this.animationStyleId = animationStyleId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 内容视图ID |
||||
* @return 视图ID |
||||
*/ |
||||
public @IdRes int getContentId() { |
||||
return contentId; |
||||
} |
||||
|
||||
/** |
||||
* 设置内容视图ID |
||||
* @param contentId 内容视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setContentId(@IdRes int contentId) { |
||||
this.contentId = contentId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 取消按钮视图ID |
||||
* @return 视图ID |
||||
*/ |
||||
public @IdRes int getCancelId() { |
||||
return cancelId; |
||||
} |
||||
|
||||
/** |
||||
* 设置取消按钮视图ID |
||||
* @param cancelId 取消按钮视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setCancelId(@IdRes int cancelId) { |
||||
this.cancelId = cancelId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 获取确定按钮视图ID |
||||
* @return 确定按钮视图ID |
||||
* @Deprecated 请使用 {@link #getConfirmId()}来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
@Deprecated |
||||
public @IdRes int getOkId() { |
||||
return getConfirmId(); |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮视图ID |
||||
* @param okId 确定按钮视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
* @Deprecated 请使用 {@link #setConfirmId(int)}来代替,后续版本可能移除此方法 |
||||
*/ |
||||
@Deprecated |
||||
public BaseDialogConfig setOkId(@IdRes int okId) { |
||||
return setConfirmId(okId); |
||||
} |
||||
|
||||
/** |
||||
* 获取确定按钮视图ID |
||||
* @return 视图ID |
||||
*/ |
||||
public @IdRes int getConfirmId() { |
||||
return confirmId; |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮视图ID |
||||
* @param confirmId 确定按钮视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setConfirmId(@IdRes int confirmId) { |
||||
this.confirmId = confirmId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 分割线视图ID |
||||
* @return 视图ID |
||||
*/ |
||||
public @IdRes int getLineId() { |
||||
return lineId; |
||||
} |
||||
|
||||
/** |
||||
* 设置分割线视图ID |
||||
* @param lineId 分割线视图ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setLineId(@IdRes int lineId) { |
||||
this.lineId = lineId; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 标题 |
||||
* @return 标题 |
||||
*/ |
||||
public CharSequence getTitle() { |
||||
return title; |
||||
} |
||||
|
||||
/** |
||||
* 设置标题 |
||||
* @param title 标题 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setTitle(CharSequence title) { |
||||
this.title = title; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置标题 |
||||
* @param context 上下文 |
||||
* @param resId 标题资源ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setTitle(@NonNull Context context, @StringRes int resId) { |
||||
this.title = context.getString(resId); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 文本内容 |
||||
* @return 文本内容 |
||||
*/ |
||||
public CharSequence getContent() { |
||||
return content; |
||||
} |
||||
|
||||
/** |
||||
* 设置文本内容 |
||||
* @param content 文本内容 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setContent(CharSequence content) { |
||||
this.content = content; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 取消按钮文本内容 |
||||
* @return 取消按钮文本内容 |
||||
*/ |
||||
public CharSequence getCancel() { |
||||
return cancel; |
||||
} |
||||
|
||||
/** |
||||
* 设置取消按钮文本内容 |
||||
* @param cancel 取消按钮文本内容 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setCancel(CharSequence cancel) { |
||||
this.cancel = cancel; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置取消按钮文本内容 |
||||
* @param context 上下文 |
||||
* @param resId 取消按钮文本内容资源ID |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setCancel(@NonNull Context context, @StringRes int resId) { |
||||
this.cancel = context.getString(resId); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 获取确定按钮文本内容 |
||||
* @return 确定按钮文本内容 |
||||
* @deprecated 请使用 {@link #getConfirm()} 来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
public CharSequence getOk() { |
||||
return getConfirm(); |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮文本内容 |
||||
* @param ok 确定按钮文本内容 |
||||
* @return {@link BaseDialogConfig} |
||||
* @deprecated 请使用 {@link #setConfirm(CharSequence)} 来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
public BaseDialogConfig setOk(CharSequence ok) { |
||||
return setConfirm(ok); |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮文本内容 |
||||
* @param context 上下文 |
||||
* @param resId 确定按钮文本内容资源ID |
||||
* @return {@link BaseDialogConfig} |
||||
* @deprecated 请使用 {@link #setConfirm(Context, int)}来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
public BaseDialogConfig setOk(@NonNull Context context, @StringRes int resId) { |
||||
return setConfirm(context,resId); |
||||
} |
||||
|
||||
/** |
||||
* 确定按钮文本内容 |
||||
* @return 确定按钮文本内容 |
||||
*/ |
||||
public CharSequence getConfirm() { |
||||
return confirm; |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮文本内容 |
||||
* @param confirm 确定按钮文本内容 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setConfirm(CharSequence confirm) { |
||||
this.confirm = confirm; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置确定按钮文本内容 |
||||
* @param context 上下文 |
||||
* @param resId 确定按钮文本内容资源ID |
||||
* @return {@link BaseDialogConfig} |
||||
* |
||||
*/ |
||||
public BaseDialogConfig setConfirm(@NonNull Context context, @StringRes int resId) { |
||||
this.confirm = context.getString(resId); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 是否隐藏取消按钮 |
||||
* @return {@link #isHideCancel} |
||||
*/ |
||||
public boolean isHideCancel() { |
||||
return isHideCancel; |
||||
} |
||||
|
||||
/** |
||||
* 设置是否隐藏取消按钮 |
||||
* @param hideCancel 是否隐藏取消按钮 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setHideCancel(boolean hideCancel) { |
||||
isHideCancel = hideCancel; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 是否隐藏标题 |
||||
* @return {@link #isHideTitle} |
||||
*/ |
||||
public boolean isHideTitle(){ |
||||
return isHideTitle; |
||||
} |
||||
|
||||
/** |
||||
* 设置是否隐藏标题 |
||||
* @param hideTitle 是否隐藏标题 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setHideTitle(boolean hideTitle){ |
||||
isHideTitle = hideTitle; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Dialog的宽度比例,根据屏幕宽度计算得来 |
||||
* @return {@link #widthRatio} |
||||
*/ |
||||
public float getWidthRatio() { |
||||
return widthRatio; |
||||
} |
||||
|
||||
/** |
||||
* 设置Dialog的宽度比例,根据屏幕宽度计算得来 |
||||
* @param widthRatio Dialog的宽度比例;默认值:{@link AppDialog#DEFAULT_WIDTH_RATIO} |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setWidthRatio(float widthRatio){ |
||||
this.widthRatio = widthRatio; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Dialog的对齐方式 {@link WindowManager.LayoutParams#gravity} |
||||
* @return Dialog的对齐方式 |
||||
*/ |
||||
public int getGravity() { |
||||
return gravity; |
||||
} |
||||
|
||||
/** |
||||
* 设置Dialog的对齐方式 {@link WindowManager.LayoutParams#gravity} |
||||
* @param gravity Dialog的对齐方式 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setGravity(int gravity){ |
||||
this.gravity = gravity; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* “取消”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @return “取消”按钮点击监听 |
||||
*/ |
||||
public View.OnClickListener getOnClickCancel() { |
||||
return onClickCancel; |
||||
} |
||||
|
||||
/** |
||||
* 设置“取消”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @param onClickCancel “取消”按钮点击监听 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setOnClickCancel(View.OnClickListener onClickCancel) { |
||||
this.onClickCancel = onClickCancel; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* “确定”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @return “确定”按钮点击监听 |
||||
*/ |
||||
public View.OnClickListener getOnClickConfirm() { |
||||
return onClickConfirm; |
||||
} |
||||
|
||||
/** |
||||
* 设置“确定”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @param onClickConfirm “确定”按钮点击监听 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setOnClickConfirm(View.OnClickListener onClickConfirm) { |
||||
this.onClickConfirm = onClickConfirm; |
||||
return this; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取“确定”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @return “确定”按钮点击监听 |
||||
* @deprecated 请使用 {@link #getOnClickConfirm()}来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
public View.OnClickListener getOnClickOk() { |
||||
return getOnClickConfirm(); |
||||
} |
||||
|
||||
/** |
||||
* 设置“确定”按钮点击监听,不设置默认点击关闭弹框 |
||||
* @param onClickOk “确定”按钮点击监听 |
||||
* @return {@link BaseDialogConfig} |
||||
* @deprecated 请使用 {@link #setOnClickConfirm(View.OnClickListener)}来代替,后续版本可能会移除此方法 |
||||
*/ |
||||
public BaseDialogConfig setOnClickOk(View.OnClickListener onClickOk) { |
||||
return setOnClickConfirm(onClickOk); |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#x} |
||||
* @return {@link #x} |
||||
*/ |
||||
public int getX() { |
||||
return x; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#x} |
||||
* @param x x轴坐标 |
||||
*/ |
||||
public BaseDialogConfig setX(int x) { |
||||
this.x = x; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#y} |
||||
* @return {@link #y} |
||||
*/ |
||||
public int getY() { |
||||
return y; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#y} |
||||
* @param y y轴坐标 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setY(int y) { |
||||
this.y = y; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalMargin} |
||||
* @return {@link #verticalMargin} |
||||
*/ |
||||
public float getVerticalMargin() { |
||||
return verticalMargin; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalMargin} |
||||
* @param verticalMargin 垂直边距 |
||||
*/ |
||||
public void setVerticalMargin(float verticalMargin) { |
||||
this.verticalMargin = verticalMargin; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalMargin} |
||||
* @return {@link #horizontalMargin} |
||||
*/ |
||||
public float getHorizontalMargin() { |
||||
return horizontalMargin; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalMargin} |
||||
* @param horizontalMargin 水平边距 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setHorizontalMargin(float horizontalMargin) { |
||||
this.horizontalMargin = horizontalMargin; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalWeight} |
||||
* @return {@link #horizontalWeight} |
||||
*/ |
||||
public float getHorizontalWeight() { |
||||
return horizontalWeight; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#horizontalWeight} |
||||
* @param horizontalWeight 水平方向权重 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setHorizontalWeight(float horizontalWeight) { |
||||
this.horizontalWeight = horizontalWeight; |
||||
return this; |
||||
} |
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalWeight} |
||||
* @return {@link #verticalWeight} |
||||
*/ |
||||
public float getVerticalWeight() { |
||||
return verticalWeight; |
||||
} |
||||
|
||||
/** |
||||
* {@link WindowManager.LayoutParams#verticalWeight} |
||||
* @param verticalWeight 垂直方向权重 |
||||
* @return {@link BaseDialogConfig} |
||||
*/ |
||||
public BaseDialogConfig setVerticalWeight(float verticalWeight) { |
||||
this.verticalWeight = verticalWeight; |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="100%" |
||||
android:toYDelta="0%" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="0%" |
||||
android:toYDelta="100%" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="-100%" |
||||
android:toXDelta="0%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0%" |
||||
android:toXDelta="-100%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="100%" |
||||
android:toXDelta="0%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0%" |
||||
android:toXDelta="100%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="0.0" |
||||
android:fromYScale="0.0" |
||||
android:toXScale="1.0" |
||||
android:toYScale="1.0"/> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="100%" |
||||
android:toYDelta="0%" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="1.0" |
||||
android:fromYScale="1.0" |
||||
android:toXScale="0.0" |
||||
android:toYScale="0.0"/> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="0%" |
||||
android:toYDelta="100%" /> |
||||
</set> |
@ -1,6 +1,7 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<scale android:duration="200" |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="0.0" |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="0.0" |
||||
android:fromYScale="0.0" |
||||
android:toXScale="1.0" |
||||
android:toYScale="1.0"/> |
||||
<translate |
||||
android:fromXDelta="-100%" |
||||
android:toXDelta="0%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="1.0" |
||||
android:fromYScale="1.0" |
||||
android:toXScale="0.0" |
||||
android:toYScale="0.0"/> |
||||
<translate |
||||
android:fromXDelta="0%" |
||||
android:toXDelta="-100%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -1,6 +1,7 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<scale android:duration="200" |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="1.0" |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="0.0" |
||||
android:fromYScale="0.0" |
||||
android:toXScale="1.0" |
||||
android:toYScale="1.0"/> |
||||
<translate |
||||
android:fromXDelta="100%" |
||||
android:toXDelta="0%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="1.0" |
||||
android:fromYScale="1.0" |
||||
android:toXScale="0.0" |
||||
android:toYScale="0.0"/> |
||||
<translate |
||||
android:fromXDelta="0%" |
||||
android:toXDelta="100%" |
||||
android:fromYDelta="0" |
||||
android:toYDelta="0" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="0.0" |
||||
android:fromYScale="0.0" |
||||
android:toXScale="1.0" |
||||
android:toYScale="1.0"/> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="-100%" |
||||
android:toYDelta="0%" /> |
||||
</set> |
@ -0,0 +1,16 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<scale |
||||
android:pivotX="50%" |
||||
android:pivotY="50%" |
||||
android:fromXScale="1.0" |
||||
android:fromYScale="1.0" |
||||
android:toXScale="0.0" |
||||
android:toYScale="0.0"/> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="0%" |
||||
android:toYDelta="-100%" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="-100%" |
||||
android:toYDelta="0%" /> |
||||
</set> |
@ -0,0 +1,9 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:duration="200"> |
||||
<translate |
||||
android:fromXDelta="0" |
||||
android:toXDelta="0" |
||||
android:fromYDelta="0%" |
||||
android:toYDelta="-100%" /> |
||||
</set> |
@ -1,13 +1,13 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
|
||||
<color name="colorAccent">#FF4081</color> |
||||
<color name="colorAccent">#5588FF</color> |
||||
|
||||
<color name="app_dialog_title_color">#333333</color> |
||||
<color name="app_dialog_content_color">#333333</color> |
||||
<color name="app_dialog_button_normal_color">#333333</color> |
||||
<color name="app_dialog_button_pressed_color">@color/colorAccent</color> |
||||
|
||||
<color name="app_dialog_line_color">#d2d2d2</color> |
||||
<color name="app_dialog_line_color">#F2F2F2</color> |
||||
|
||||
</resources> |
||||
|
@ -0,0 +1,3 @@ |
||||
POM_NAME=App Updater |
||||
POM_ARTIFACT_ID=app-updater |
||||
POM_PACKAGING=aar |
@ -0,0 +1,235 @@ |
||||
package com.king.app.updater.http; |
||||
|
||||
import android.os.AsyncTask; |
||||
|
||||
import com.king.app.updater.util.LogUtils; |
||||
import com.king.app.updater.util.SSLSocketFactoryUtils; |
||||
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.InputStream; |
||||
import java.net.ConnectException; |
||||
import java.util.Map; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
import okhttp3.Call; |
||||
import okhttp3.OkHttpClient; |
||||
import okhttp3.Request; |
||||
import okhttp3.Response; |
||||
|
||||
/** |
||||
* OkHttpManager使用 {@link OkHttpClient} 实现的 {@link IHttpManager} |
||||
* <p>使用 OkHttpManager 时必须依赖 OkHttp 库 |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class OkHttpManager implements IHttpManager { |
||||
|
||||
private static final int DEFAULT_TIME_OUT = 20000; |
||||
|
||||
private OkHttpClient okHttpClient; |
||||
|
||||
private DownloadTask mDownloadTask; |
||||
|
||||
private static volatile OkHttpManager INSTANCE; |
||||
|
||||
public static OkHttpManager getInstance(){ |
||||
if(INSTANCE == null){ |
||||
synchronized (HttpManager.class){ |
||||
if(INSTANCE == null){ |
||||
INSTANCE = new OkHttpManager(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return INSTANCE; |
||||
} |
||||
|
||||
private OkHttpManager(){ |
||||
this(DEFAULT_TIME_OUT); |
||||
} |
||||
|
||||
/** |
||||
* HttpManager对外暴露。如果没有特殊需求,推荐使用{@link HttpManager#getInstance()} |
||||
* @param timeout 超时时间,单位:毫秒 |
||||
*/ |
||||
public OkHttpManager(int timeout){ |
||||
this(new OkHttpClient.Builder() |
||||
.readTimeout(timeout, TimeUnit.MILLISECONDS) |
||||
.connectTimeout(timeout, TimeUnit.MILLISECONDS) |
||||
.sslSocketFactory(SSLSocketFactoryUtils.createSSLSocketFactory(),SSLSocketFactoryUtils.createTrustAllManager()) |
||||
.hostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) |
||||
.build()); |
||||
} |
||||
|
||||
/** |
||||
* HttpManager对外暴露,推荐使用{@link HttpManager#getInstance()} |
||||
* @param okHttpClient {@link OkHttpClient} |
||||
*/ |
||||
public OkHttpManager(@NonNull OkHttpClient okHttpClient){ |
||||
this.okHttpClient = okHttpClient; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void download(String url,final String path,final String filename, @Nullable Map<String, String> requestProperty,final DownloadCallback callback) { |
||||
mDownloadTask = new DownloadTask(okHttpClient, url, path, filename, requestProperty, callback); |
||||
mDownloadTask.execute(); |
||||
} |
||||
|
||||
@Override |
||||
public void cancel() { |
||||
if(mDownloadTask != null){ |
||||
mDownloadTask.isCancel = true; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 异步下载任务 |
||||
*/ |
||||
private static class DownloadTask extends AsyncTask<Void,Long,File> { |
||||
|
||||
private String url; |
||||
|
||||
private String path; |
||||
|
||||
private String filename; |
||||
|
||||
private Map<String,String> requestProperty; |
||||
|
||||
private DownloadCallback callback; |
||||
|
||||
private Exception exception; |
||||
|
||||
private OkHttpClient okHttpClient; |
||||
|
||||
private volatile boolean isCancel; |
||||
|
||||
public DownloadTask(OkHttpClient okHttpClient,String url, String path, String filename ,@Nullable Map<String,String> requestProperty, DownloadCallback callback){ |
||||
this.okHttpClient = okHttpClient; |
||||
this.url = url; |
||||
this.path = path; |
||||
this.filename = filename; |
||||
this.callback = callback; |
||||
this.requestProperty = requestProperty; |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected File doInBackground(Void... voids) { |
||||
|
||||
try{ |
||||
Request.Builder builder = new Request.Builder() |
||||
.url(url) |
||||
.addHeader("Accept-Encoding", "identity") |
||||
.get(); |
||||
|
||||
if(requestProperty!=null){ |
||||
for(Map.Entry<String,String> entry : requestProperty.entrySet()){ |
||||
builder.addHeader(entry.getKey(),entry.getValue()); |
||||
} |
||||
} |
||||
|
||||
Call call = okHttpClient.newCall(builder.build()); |
||||
Response response = call.execute(); |
||||
|
||||
if(response.isSuccessful()){ |
||||
InputStream is = response.body().byteStream(); |
||||
|
||||
long length = response.body().contentLength(); |
||||
|
||||
LogUtils.d("contentLength:" + length); |
||||
|
||||
long progress = 0; |
||||
|
||||
byte[] buffer = new byte[8192]; |
||||
|
||||
int len; |
||||
File file = new File(path,filename); |
||||
FileOutputStream fos = new FileOutputStream(file); |
||||
while ((len = is.read(buffer)) != -1){ |
||||
if(isCancel){ |
||||
if(call != null){ |
||||
call.cancel(); |
||||
} |
||||
cancel(true); |
||||
break; |
||||
} |
||||
fos.write(buffer,0,len); |
||||
progress += len; |
||||
// 更新进度
|
||||
if(length > 0){ |
||||
publishProgress(progress,length); |
||||
} |
||||
} |
||||
|
||||
fos.flush(); |
||||
fos.close(); |
||||
is.close(); |
||||
|
||||
response.close(); |
||||
|
||||
if(progress <= 0 && length <= 0){ |
||||
throw new IllegalStateException(String.format("contentLength = %d",length)); |
||||
} |
||||
|
||||
return file; |
||||
|
||||
}else {// 连接失败
|
||||
throw new ConnectException(String.format("responseCode = %d",response.code())); |
||||
} |
||||
|
||||
}catch (Exception e){ |
||||
this.exception = e; |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreExecute() { |
||||
super.onPreExecute(); |
||||
if(callback != null){ |
||||
callback.onStart(url); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onPostExecute(File file) { |
||||
super.onPostExecute(file); |
||||
if(callback != null){ |
||||
if(file != null){ |
||||
callback.onFinish(file); |
||||
}else{ |
||||
callback.onError(exception); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onProgressUpdate(Long... values) { |
||||
super.onProgressUpdate(values); |
||||
if(callback != null){ |
||||
if(!isCancelled()){ |
||||
callback.onProgress(values[0],values[1]); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onCancelled() { |
||||
super.onCancelled(); |
||||
if(callback != null){ |
||||
callback.onCancel(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
package com.king.app.updater.notify; |
||||
|
||||
import android.content.Context; |
||||
|
||||
import com.king.app.updater.UpdateConfig; |
||||
|
||||
import java.io.File; |
||||
|
||||
import androidx.annotation.DrawableRes; |
||||
|
||||
/** |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public interface INotification { |
||||
|
||||
void onStart(Context context, int notifyId, String channelId, String channelName, @DrawableRes int icon, CharSequence title, CharSequence content, boolean isVibrate, boolean isSound, boolean isCancelDownload); |
||||
|
||||
void onProgress(Context context, int notifyId, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, int progress, int size, boolean isCancelDownload); |
||||
|
||||
void onFinish(Context context, int notifyId, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, File file, String authority); |
||||
|
||||
void onError(Context context, int notifyId, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, boolean isReDownload, UpdateConfig config); |
||||
|
||||
void onCancel(Context context, int notifyId); |
||||
} |
@ -0,0 +1,38 @@ |
||||
package com.king.app.updater.notify; |
||||
|
||||
import android.content.Context; |
||||
|
||||
import com.king.app.updater.UpdateConfig; |
||||
import com.king.app.updater.util.NotificationUtils; |
||||
|
||||
import java.io.File; |
||||
|
||||
/** |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class NotificationImpl implements INotification { |
||||
@Override |
||||
public void onStart(Context context, int notifyId, String channelId, String channelName, int icon, CharSequence title, CharSequence content, boolean isVibrate, boolean isSound, boolean isCancelDownload) { |
||||
NotificationUtils.showStartNotification(context, notifyId, channelId, channelName, icon, title, content, isVibrate, isSound, isCancelDownload); |
||||
} |
||||
|
||||
@Override |
||||
public void onProgress(Context context, int notifyId, String channelId, int icon, CharSequence title, CharSequence content, int progress, int size, boolean isCancelDownload) { |
||||
NotificationUtils.showProgressNotification(context, notifyId, channelId, icon, title, content, progress, size, isCancelDownload); |
||||
} |
||||
|
||||
@Override |
||||
public void onFinish(Context context, int notifyId, String channelId, int icon, CharSequence title, CharSequence content, File file, String authority) { |
||||
NotificationUtils.showFinishNotification(context, notifyId, channelId, icon, title, content, file, authority); |
||||
} |
||||
|
||||
@Override |
||||
public void onError(Context context, int notifyId, String channelId, int icon, CharSequence title, CharSequence content, boolean isReDownload, UpdateConfig config) { |
||||
NotificationUtils.showErrorNotification(context, notifyId, channelId, icon, title, content, isReDownload, config); |
||||
} |
||||
|
||||
@Override |
||||
public void onCancel(Context context, int notifyId) { |
||||
NotificationUtils.cancelNotification(context, notifyId); |
||||
} |
||||
} |
@ -0,0 +1,316 @@ |
||||
/* |
||||
Copyright © 2015, 2016 Jenly Yu <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
|
||||
*/ |
||||
package com.king.app.updater.util; |
||||
|
||||
|
||||
import android.util.Log; |
||||
|
||||
import java.util.Locale; |
||||
|
||||
/** |
||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class LogUtils { |
||||
|
||||
public static final String TAG = "AppUpdater"; |
||||
|
||||
public static final String VERTICAL = "|"; |
||||
|
||||
/** 是否显示Log日志 */ |
||||
private static boolean isShowLog = true; |
||||
|
||||
/** Log日志优先权 */ |
||||
private static int priority = 1; |
||||
|
||||
/** |
||||
* Priority constant for the println method;use System.out.println |
||||
*/ |
||||
public static final int PRINTLN = 1; |
||||
|
||||
/** |
||||
* Priority constant for the println method; use Log.v. |
||||
*/ |
||||
public static final int VERBOSE = 2; |
||||
|
||||
/** |
||||
* Priority constant for the println method; use Log.d. |
||||
*/ |
||||
public static final int DEBUG = 3; |
||||
|
||||
/** |
||||
* Priority constant for the println method; use Log.i. |
||||
*/ |
||||
public static final int INFO = 4; |
||||
|
||||
/** |
||||
* Priority constant for the println method; use Log.w. |
||||
*/ |
||||
public static final int WARN = 5; |
||||
|
||||
/** |
||||
* Priority constant for the println method; use Log.e. |
||||
*/ |
||||
public static final int ERROR = 6; |
||||
|
||||
/** |
||||
* Priority constant for the println method.use Log.wtf. |
||||
*/ |
||||
public static final int ASSERT = 7; |
||||
|
||||
public static final String TAG_FORMAT = "%s.%s(%s:%d)"; |
||||
|
||||
private LogUtils(){ |
||||
throw new AssertionError(); |
||||
} |
||||
|
||||
public static void setShowLog(boolean isShowLog) { |
||||
|
||||
LogUtils.isShowLog = isShowLog; |
||||
} |
||||
|
||||
public static boolean isShowLog() { |
||||
|
||||
return isShowLog; |
||||
} |
||||
|
||||
public static int getPriority() { |
||||
|
||||
return priority; |
||||
} |
||||
|
||||
public static void setPriority(int priority) { |
||||
|
||||
LogUtils.priority = priority; |
||||
} |
||||
|
||||
/** |
||||
* 根据堆栈生成TAG |
||||
* @return TAG|className.methodName(fileName:lineNumber) |
||||
*/ |
||||
private static String generateTag(StackTraceElement caller) { |
||||
String tag = TAG_FORMAT; |
||||
String callerClazzName = caller.getClassName(); |
||||
callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1); |
||||
tag = String.format(Locale.getDefault(),tag,callerClazzName, caller.getMethodName(),caller.getFileName(),caller.getLineNumber()); |
||||
return new StringBuilder().append(TAG).append(VERTICAL).append(tag).toString(); |
||||
} |
||||
|
||||
/** |
||||
* 获取堆栈 |
||||
* @param n |
||||
* n=0 VMStack |
||||
* n=1 Thread |
||||
* n=3 CurrentStack |
||||
* n=4 CallerStack |
||||
* ... |
||||
* @return |
||||
*/ |
||||
public static StackTraceElement getStackTraceElement(int n) { |
||||
return Thread.currentThread().getStackTrace()[n]; |
||||
} |
||||
|
||||
/** |
||||
* 获取调用方的堆栈TAG |
||||
* @return |
||||
*/ |
||||
private static String getCallerStackLogTag(){ |
||||
return generateTag(getStackTraceElement(5)); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param t |
||||
* @return |
||||
*/ |
||||
private static String getStackTraceString(Throwable t){ |
||||
return Log.getStackTraceString(t); |
||||
} |
||||
|
||||
// -----------------------------------Log.v
|
||||
|
||||
/** |
||||
* Log.v |
||||
* @param msg |
||||
*/ |
||||
public static void v(String msg) { |
||||
if (isShowLog && priority <= VERBOSE) |
||||
Log.v(getCallerStackLogTag(), String.valueOf(msg)); |
||||
|
||||
} |
||||
|
||||
public static void v(Throwable t) { |
||||
if (isShowLog && priority <= VERBOSE) |
||||
Log.v(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void v(String msg,Throwable t) { |
||||
if (isShowLog && priority <= VERBOSE) |
||||
Log.v(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------Log.d
|
||||
|
||||
/** |
||||
* Log.d |
||||
* @param msg |
||||
*/ |
||||
public static void d(String msg) { |
||||
if (isShowLog && priority <= DEBUG) |
||||
Log.d(getCallerStackLogTag(), String.valueOf(msg)); |
||||
} |
||||
|
||||
public static void d(Throwable t) { |
||||
if (isShowLog && priority <= DEBUG) |
||||
Log.d(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void d(String msg,Throwable t) { |
||||
if (isShowLog && priority <= DEBUG) |
||||
Log.d(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------Log.i
|
||||
|
||||
/** |
||||
* Log.i |
||||
* @param msg |
||||
*/ |
||||
public static void i(String msg) { |
||||
if (isShowLog && priority <= INFO) |
||||
Log.i(getCallerStackLogTag(), String.valueOf(msg)); |
||||
} |
||||
|
||||
public static void i(Throwable t) { |
||||
if (isShowLog && priority <= INFO) |
||||
Log.i(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void i(String msg,Throwable t) { |
||||
if (isShowLog && priority <= INFO) |
||||
Log.i(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------Log.w
|
||||
|
||||
/** |
||||
* Log.w |
||||
* @param msg |
||||
*/ |
||||
public static void w(String msg) { |
||||
if (isShowLog && priority <= WARN) |
||||
Log.w(getCallerStackLogTag(), String.valueOf(msg)); |
||||
} |
||||
|
||||
public static void w(Throwable t) { |
||||
if (isShowLog && priority <= WARN) |
||||
Log.w(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void w(String msg,Throwable t) { |
||||
if (isShowLog && priority <= WARN) |
||||
Log.w(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------Log.e
|
||||
|
||||
/** |
||||
* Log.e |
||||
* @param msg |
||||
*/ |
||||
public static void e(String msg) { |
||||
if (isShowLog && priority <= ERROR) |
||||
Log.e(getCallerStackLogTag(), String.valueOf(msg)); |
||||
} |
||||
|
||||
public static void e(Throwable t) { |
||||
if (isShowLog && priority <= ERROR) |
||||
Log.e(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void e(String msg,Throwable t) { |
||||
if (isShowLog && priority <= ERROR) |
||||
Log.e(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------Log.wtf
|
||||
|
||||
/** |
||||
* Log.wtf |
||||
* @param msg |
||||
*/ |
||||
public static void wtf(String msg) { |
||||
if (isShowLog && priority <= ASSERT) |
||||
Log.wtf(getCallerStackLogTag(), String.valueOf(msg)); |
||||
} |
||||
|
||||
public static void wtf(Throwable t) { |
||||
if (isShowLog && priority <= ASSERT) |
||||
Log.wtf(getCallerStackLogTag(), getStackTraceString(t)); |
||||
} |
||||
|
||||
public static void wtf(String msg,Throwable t) { |
||||
if (isShowLog && priority <= ASSERT) |
||||
Log.wtf(getCallerStackLogTag(), String.valueOf(msg), t); |
||||
} |
||||
|
||||
// -----------------------------------System.out.print
|
||||
|
||||
/** |
||||
* System.out.print |
||||
* |
||||
* @param msg |
||||
*/ |
||||
public static void print(String msg) { |
||||
if (isShowLog && priority <= PRINTLN) |
||||
System.out.print(msg); |
||||
} |
||||
|
||||
public static void print(Object obj) { |
||||
if (isShowLog && priority <= PRINTLN) |
||||
System.out.print(obj); |
||||
} |
||||
|
||||
// -----------------------------------System.out.printf
|
||||
|
||||
/** |
||||
* System.out.printf |
||||
* |
||||
* @param msg |
||||
*/ |
||||
public static void printf(String msg) { |
||||
if (isShowLog && priority <= PRINTLN) |
||||
System.out.printf(msg); |
||||
} |
||||
|
||||
// -----------------------------------System.out.println
|
||||
|
||||
/** |
||||
* System.out.println |
||||
* |
||||
* @param msg |
||||
*/ |
||||
public static void println(String msg) { |
||||
if (isShowLog && priority <= PRINTLN) |
||||
System.out.println(msg); |
||||
} |
||||
|
||||
public static void println(Object obj) { |
||||
if (isShowLog && priority <= PRINTLN) |
||||
System.out.println(obj); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,260 @@ |
||||
package com.king.app.updater.util; |
||||
|
||||
import android.app.Notification; |
||||
import android.app.NotificationChannel; |
||||
import android.app.NotificationManager; |
||||
import android.app.PendingIntent; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.os.Build; |
||||
|
||||
import com.king.app.updater.UpdateConfig; |
||||
import com.king.app.updater.constant.Constants; |
||||
import com.king.app.updater.service.DownloadService; |
||||
|
||||
import java.io.File; |
||||
|
||||
import androidx.annotation.DrawableRes; |
||||
import androidx.annotation.RequiresApi; |
||||
import androidx.core.app.NotificationCompat; |
||||
|
||||
/** |
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a> |
||||
*/ |
||||
public class NotificationUtils { |
||||
|
||||
private NotificationUtils(){ |
||||
throw new AssertionError(); |
||||
} |
||||
|
||||
/** |
||||
* 显示开始下载时的通知 |
||||
* @param notifyId |
||||
* @param channelId |
||||
* @param channelName |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
*/ |
||||
public static void showStartNotification(Context context, int notifyId,String channelId, String channelName,@DrawableRes int icon,CharSequence title,CharSequence content,boolean isVibrate,boolean isSound, boolean isCancelDownload){ |
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ |
||||
createNotificationChannel(context,channelId,channelName,isVibrate,isSound); |
||||
} |
||||
NotificationCompat.Builder builder = buildNotification(context,channelId,icon,title,content); |
||||
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT); |
||||
if(isVibrate && isSound){ |
||||
builder.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND); |
||||
}else if(isVibrate){ |
||||
builder.setDefaults(Notification.DEFAULT_VIBRATE); |
||||
}else if(isSound){ |
||||
builder.setDefaults(Notification.DEFAULT_SOUND); |
||||
} |
||||
|
||||
if(isCancelDownload){ |
||||
Intent intent = new Intent(context, DownloadService.class); |
||||
intent.putExtra(Constants.KEY_STOP_DOWNLOAD_SERVICE,true); |
||||
PendingIntent deleteIntent = PendingIntent.getService(context, notifyId,intent, getPendingIntentFlags(PendingIntent.FLAG_CANCEL_CURRENT)); |
||||
builder.setDeleteIntent(deleteIntent); |
||||
} |
||||
|
||||
Notification notification = builder.build(); |
||||
if(isCancelDownload){ |
||||
notification.flags = Notification.FLAG_ONLY_ALERT_ONCE; |
||||
}else{ |
||||
notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONLY_ALERT_ONCE; |
||||
} |
||||
|
||||
notifyNotification(context,notifyId,notification); |
||||
} |
||||
|
||||
/** |
||||
* 显示下载中的通知(更新进度) |
||||
* @param notifyId |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
* @param progress |
||||
* @param size |
||||
*/ |
||||
public static void showProgressNotification(Context context, int notifyId,String channelId,@DrawableRes int icon,CharSequence title,CharSequence content,int progress,int size, boolean isCancelDownload){ |
||||
NotificationCompat.Builder builder = buildNotification(context,channelId,icon,title,content,progress,size); |
||||
|
||||
if(isCancelDownload){ |
||||
Intent intent = new Intent(context, DownloadService.class); |
||||
intent.putExtra(Constants.KEY_STOP_DOWNLOAD_SERVICE,true); |
||||
PendingIntent deleteIntent = PendingIntent.getService(context, notifyId, intent, getPendingIntentFlags(PendingIntent.FLAG_CANCEL_CURRENT)); |
||||
builder.setDeleteIntent(deleteIntent); |
||||
} |
||||
|
||||
Notification notification = builder.build(); |
||||
|
||||
if(isCancelDownload){ |
||||
notification.flags = Notification.FLAG_ONLY_ALERT_ONCE; |
||||
}else{ |
||||
notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONLY_ALERT_ONCE; |
||||
} |
||||
|
||||
notifyNotification(context,notifyId,notification); |
||||
} |
||||
|
||||
/** |
||||
* 显示下载完成时的通知(点击安装) |
||||
* @param notifyId |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
* @param file |
||||
*/ |
||||
public static void showFinishNotification(Context context, int notifyId, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, File file, String authority){ |
||||
cancelNotification(context,notifyId); |
||||
NotificationCompat.Builder builder = buildNotification(context,channelId,icon,title,content); |
||||
builder.setAutoCancel(true); |
||||
Intent intent = AppUtils.getInstallIntent(context,file,authority); |
||||
PendingIntent clickIntent = PendingIntent.getActivity(context, notifyId, intent, getPendingIntentFlags(PendingIntent.FLAG_UPDATE_CURRENT)); |
||||
builder.setContentIntent(clickIntent); |
||||
Notification notification = builder.build(); |
||||
notification.flags = Notification.FLAG_AUTO_CANCEL; |
||||
notifyNotification(context,notifyId,notification); |
||||
} |
||||
|
||||
/** |
||||
* 现在下载失败通知 |
||||
* @param context |
||||
* @param notifyId |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
* @param isReDownload |
||||
* @param config |
||||
*/ |
||||
public static void showErrorNotification(Context context, int notifyId, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, boolean isReDownload, UpdateConfig config){ |
||||
NotificationCompat.Builder builder = buildNotification(context,channelId,icon,title,content); |
||||
builder.setAutoCancel(true); |
||||
int flag = getPendingIntentFlags(PendingIntent.FLAG_UPDATE_CURRENT); |
||||
if(isReDownload){// 重新下载
|
||||
Intent intent = new Intent(context, DownloadService.class); |
||||
intent.putExtra(Constants.KEY_RE_DOWNLOAD,true); |
||||
intent.putExtra(Constants.KEY_UPDATE_CONFIG,config); |
||||
PendingIntent clickIntent = PendingIntent.getService(context, notifyId,intent, flag); |
||||
builder.setContentIntent(clickIntent); |
||||
}else{ |
||||
PendingIntent clickIntent = PendingIntent.getService(context, notifyId, new Intent(), flag); |
||||
builder.setContentIntent(clickIntent); |
||||
} |
||||
|
||||
Notification notification = builder.build(); |
||||
notification.flags = Notification.FLAG_AUTO_CANCEL; |
||||
notifyNotification(context,notifyId,notification); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 显示通知信息(非第一次) |
||||
* @param notifyId |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
*/ |
||||
public static void showNotification(Context context, int notifyId,String channelId,@DrawableRes int icon,CharSequence title,CharSequence content,boolean isAutoCancel){ |
||||
NotificationCompat.Builder builder = buildNotification(context,channelId,icon,title,content); |
||||
builder.setAutoCancel(isAutoCancel); |
||||
Notification notification = builder.build(); |
||||
notification.flags = Notification.FLAG_AUTO_CANCEL; |
||||
notifyNotification(context,notifyId,notification); |
||||
} |
||||
|
||||
/** |
||||
* 取消通知 |
||||
* @param notifyId |
||||
*/ |
||||
public static void cancelNotification(Context context, int notifyId){ |
||||
getNotificationManager(context).cancel(notifyId); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取通知管理器 |
||||
* @return |
||||
*/ |
||||
public static NotificationManager getNotificationManager(Context context){ |
||||
return (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); |
||||
} |
||||
|
||||
/** |
||||
* 创建一个通知渠道(兼容0以上版本) |
||||
* @param channelId |
||||
* @param channelName |
||||
*/ |
||||
@RequiresApi(api = Build.VERSION_CODES.O) |
||||
public static void createNotificationChannel(Context context, String channelId, String channelName,boolean isVibrate,boolean isSound){ |
||||
NotificationChannel channel = new NotificationChannel(channelId,channelName, NotificationManager.IMPORTANCE_HIGH); |
||||
channel.enableVibration(isVibrate); |
||||
if(!isSound){ |
||||
channel.setSound(null,null); |
||||
} |
||||
getNotificationManager(context).createNotificationChannel(channel); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 构建一个通知构建器 |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
* @return |
||||
*/ |
||||
private static NotificationCompat.Builder buildNotification(Context context, String channelId, @DrawableRes int icon,CharSequence title,CharSequence content){ |
||||
return buildNotification(context,channelId,icon,title,content,Constants.NONE,Constants.NONE); |
||||
} |
||||
|
||||
/** |
||||
* 构建一个通知构建器 |
||||
* @param channelId |
||||
* @param icon |
||||
* @param title |
||||
* @param content |
||||
* @param progress |
||||
* @param size |
||||
* @return |
||||
*/ |
||||
private static NotificationCompat.Builder buildNotification(Context context, String channelId, @DrawableRes int icon, CharSequence title, CharSequence content, int progress, int size){ |
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,channelId); |
||||
builder.setSmallIcon(icon); |
||||
|
||||
builder.setContentTitle(title); |
||||
builder.setContentText(content); |
||||
builder.setOngoing(true); |
||||
|
||||
if(progress != Constants.NONE && size != Constants.NONE){ |
||||
builder.setProgress(size,progress,false); |
||||
} |
||||
|
||||
return builder; |
||||
} |
||||
|
||||
/** |
||||
* 更新通知栏 |
||||
* @param id |
||||
* @param notification |
||||
*/ |
||||
private static void notifyNotification(Context context, int id, Notification notification){ |
||||
getNotificationManager(context).notify(id,notification); |
||||
} |
||||
|
||||
/** |
||||
* 获取 PendingIntent 的 flags |
||||
* @param flag |
||||
* @return |
||||
*/ |
||||
private static int getPendingIntentFlags(int flag){ |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||
return flag | PendingIntent.FLAG_IMMUTABLE; |
||||
} |
||||
return flag; |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,18 @@ |
||||
{ |
||||
"version": 2, |
||||
"artifactType": { |
||||
"type": "APK", |
||||
"kind": "Directory" |
||||
}, |
||||
"applicationId": "com.king.appupdater", |
||||
"variantName": "processReleaseResources", |
||||
"elements": [ |
||||
{ |
||||
"type": "SINGLE", |
||||
"filters": [], |
||||
"versionCode": 22, |
||||
"versionName": "1.1.3", |
||||
"outputFile": "app-release.apk" |
||||
} |
||||
] |
||||
} |
@ -1 +0,0 @@ |
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":5,"versionName":"1.0.4","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] |
@ -0,0 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:state_pressed="true" android:color="@color/text_666"/> |
||||
<item android:state_pressed="false" android:color="@color/text_999"/> |
||||
</selector> |
@ -0,0 +1,18 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<item android:state_pressed="false"> |
||||
<shape> |
||||
<solid android:color="@color/colorAccent"/> |
||||
<corners android:radius="20dp"/> |
||||
</shape> |
||||
</item> |
||||
|
||||
<item android:state_pressed="true"> |
||||
<shape> |
||||
<solid android:color="@color/colorPrimaryDark"/> |
||||
<corners android:radius="20dp"/> |
||||
</shape> |
||||
</item> |
||||
|
||||
</selector> |
@ -0,0 +1,25 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:orientation="horizontal" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:padding="16dp" |
||||
android:gravity="center_vertical" |
||||
android:background="@drawable/app_dialog_bg"> |
||||
<ImageView |
||||
android:id="@+id/ivIcon" |
||||
android:layout_width="30dp" |
||||
android:layout_height="30dp" |
||||
android:src="@mipmap/ic_launcher" |
||||
android:layout_marginRight="4dp"/> |
||||
<TextView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerVertical="true" |
||||
android:layout_toRightOf="@+id/ivIcon" |
||||
android:textSize="14sp" |
||||
android:textColor="@color/app_dialog_title_color" |
||||
android:text="@string/app_updater_start_notification_content"/> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,43 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:orientation="horizontal" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:padding="16dp" |
||||
android:gravity="center_vertical" |
||||
android:background="@drawable/app_dialog_bg"> |
||||
<ImageView |
||||
android:id="@+id/ivIcon" |
||||
android:layout_width="20dp" |
||||
android:layout_height="20dp" |
||||
android:src="@mipmap/ic_launcher" |
||||
android:layout_marginRight="4dp"/> |
||||
<TextView |
||||
android:id="@+id/tvDialogTitle" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_toRightOf="@+id/ivIcon" |
||||
android:textSize="14sp" |
||||
android:textColor="@color/app_dialog_title_color" |
||||
android:text="@string/app_updater_progress_notification_title"/> |
||||
<TextView |
||||
android:id="@+id/tvProgress" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_below="@+id/tvDialogTitle" |
||||
android:layout_marginTop="10dp" |
||||
android:text="@string/app_updater_start_notification_content" |
||||
android:textSize="14sp" |
||||
android:textColor="@color/app_dialog_content_color" |
||||
android:lineSpacingMultiplier="1.2" /> |
||||
<ProgressBar |
||||
android:id="@+id/progressBar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="6dp" |
||||
android:layout_marginTop="10dp" |
||||
android:layout_marginBottom="10dp" |
||||
android:max="100" |
||||
android:layout_below="@+id/tvProgress" |
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"/> |
||||
</RelativeLayout> |
@ -1,10 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<color name="colorPrimary">#3F51B5</color> |
||||
<color name="colorPrimaryDark">#303F9F</color> |
||||
<color name="colorAccent">#FF4081</color> |
||||
<color name="colorPrimary">#5588FF</color> |
||||
<color name="colorPrimaryDark">#4B7CFD</color> |
||||
<color name="colorAccent">#5588FF</color> |
||||
|
||||
<color name="ic_launcher_background">#FFFFFF</color> |
||||
|
||||
<color name="white">#FFFFFF</color> |
||||
|
||||
<color name="text_666">#666666</color> |
||||
<color name="text_999">#999999</color> |
||||
|
||||
|
||||
</resources> |
||||
|
@ -1,4 +1,6 @@ |
||||
<resources> |
||||
<string name="app_name">AppUpdater</string> |
||||
|
||||
<string name="ignore">忽略</string> |
||||
|
||||
</resources> |
||||
|
@ -1,49 +1,34 @@ |
||||
//App |
||||
def app_version = [:] |
||||
app_version.versionCode = 5 //androidx 6 |
||||
app_version.versionName = "1.0.4" |
||||
app_version.versionCode = 22 |
||||
app_version.versionName = "1.1.3" |
||||
ext.app_version = app_version |
||||
|
||||
//build version |
||||
def build_versions = [:] |
||||
build_versions.minSdk = 15 |
||||
build_versions.targetSdk = 28 |
||||
build_versions.compileSdk = 28 |
||||
build_versions.buildTools = "28.0.3" |
||||
build_versions.targetSdk = 29 |
||||
build_versions.compileSdk = 29 |
||||
build_versions.buildTools = "29.0.3" |
||||
ext.build_versions = build_versions |
||||
|
||||
// App dependencies |
||||
def versions = [:] |
||||
//support |
||||
versions.supportLibrary = "28.0.0" |
||||
versions.constraintLayout = "1.1.3" |
||||
|
||||
//test |
||||
versions.junit = "4.12" |
||||
versions.runner = "1.0.2" |
||||
versions.espresso = "3.0.2" |
||||
ext.versions = versions |
||||
versions.mavenPublish = '0.13.0' |
||||
versions.gradle = "4.1.1" |
||||
|
||||
ext.deps = [:] |
||||
|
||||
//support |
||||
def support = [:] |
||||
support.appcompat = "com.android.support:appcompat-v7:$versions.supportLibrary" |
||||
support.constraintlayout = "com.android.support.constraint:constraint-layout:$versions.constraintLayout" |
||||
deps.support = support |
||||
//androidx |
||||
versions.appcompat = "1.1.0" |
||||
versions.constraintLayout = "2.0.4" |
||||
|
||||
//test |
||||
def test = [:] |
||||
test.junit = "junit:junit:$versions.junit" |
||||
test.runner = "com.android.support.test:runner:$versions.runner" |
||||
test.espresso = "com.android.support.test.espresso:espresso-core:$versions.espresso" |
||||
deps.test = test |
||||
versions.junit = "1.2.0" |
||||
versions.junit = "4.13.1" |
||||
versions.androidExtJunit = "1.1.2" |
||||
versions.espressoCore = "3.2.0" |
||||
|
||||
versions.okhttp = "4.9.1" |
||||
|
||||
ext.deps = deps |
||||
ext.versions = versions |
||||
|
||||
def addRepos(RepositoryHandler handler) { |
||||
handler.google() |
||||
handler.jcenter() |
||||
} |
||||
ext.addRepos = this.&addRepos |
Loading…
Reference in new issue