diff --git a/.gitignore b/.gitignore index 8b39a7d..2fb2288 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,10 @@ build/ *.iml *.ipr *.iws +*.asc +*.gpg .idea/ # Gradle files -.gradle/ \ No newline at end of file +.gradle/ +library/secring.gpg diff --git a/.travis.yml b/.travis.yml index 3c8a6ed..9c12733 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: java -jdk: oraclejdk7 +jdk: oraclejdk8 branches: only: - master env: matrix: - - ANDROID_TARGET=android-21 ANDROID_ABI=armeabi-v7a + - ANDROID_TARGET=android-24 ANDROID_ABI=armeabi-v7a before_install: # Install base Android SDK @@ -18,20 +18,23 @@ before_install: - chmod +x gradlew # Gradle - - wget http://services.gradle.org/distributions/gradle-1.12-bin.zip - - unzip gradle-1.12-bin.zip - - export GRADLE_HOME=$PWD/gradle-1.12 + - wget http://services.gradle.org/distributions/gradle-2.14-bin.zip + - unzip gradle-2.14-bin.zip + - export GRADLE_HOME=$PWD/gradle-2.14 - export PATH=$GRADLE_HOME/bin:$PATH # Install required components # For a full list, run `android list sdk -a --extended` # Note that sysimg-19 downloads only ARM, because only the first license query is accepted. - echo yes | android update sdk --filter platform-tools --no-ui --force > /dev/null - - echo yes | android update sdk --all --filter build-tools-21.1.1 --no-ui --force > /dev/null - - echo yes | android update sdk --filter android-21 --no-ui --force > /dev/null + - echo yes | android update sdk --all --filter build-tools-24.0.0 --no-ui --force > /dev/null + - echo yes | android update sdk --filter android-24 --no-ui --force > /dev/null - echo yes | android update sdk --filter sys-img-x86-android-19 --no-ui --force > /dev/null - echo yes | android update sdk --filter extra-android-support --no-ui --force > /dev/null - echo yes | android update sdk --filter extra-android-m2repository --no-ui --force > /dev/null + - mkdir ${ANDROID_HOME}/licenses || true + - echo yes | echo -e "8933bad161af4178b1185d1a37fbf41ea5269c55" > ${ANDROID_HOME}/licenses/android-sdk-license + - echo yes | echo -e "79120722343a6f314e0719f863036c702b0e6b2a" > ${ANDROID_HOME}/licenses/android-sdk-preview-license install: - ./gradlew assemble \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG index 5e48513..2689df5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,19 @@ Change Log ========== +*** From leonacky/AndroidTagGroup forked from 2dxgujun/AndroidTagGroup + +Version 1.5 *(2016-10-07)* +---------------------------- + +- Add TagGravity +- Change listener for detect tag click event +- Add get/setSelectedTag +- Add get all selected tags + + + + +*** From 2dxgujun/AndroidTagGroup Version 1.4 *(2015-05-23)* ---------------------------- diff --git a/README.md b/README.md index 2a6aa9f..4c8fcd3 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,21 @@ # `AndroidTagGroup` -[![Release 1.4](https://img.shields.io/badge/Release-1.4.1-green.svg)](https://github.com/2dxgujun/AndroidTagGroup/releases) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/me.gujun.android.taggroup/library/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/me.gujun.android.taggroup/library) -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AndroidTagGroup-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1539) -[![Build Status](https://travis-ci.org/2dxgujun/AndroidTagGroup.png?branch=master)](https://travis-ci.org/2dxgujun/AndroidTagGroup) +[![Join the chat at https://gitter.im/leonacky/AndroidTagGroup](https://badges.gitter.im/leonacky/AndroidTagGroup.svg)](https://gitter.im/leonacky/AndroidTagGroup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -The TagGroup is a special layout with a set of tags. You can use it to tag people, books or anything you want. +[![Release 1.6](https://img.shields.io/badge/Release-1.6-green.svg)](https://github.com/leonacky/AndroidTagGroup/releases) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.aotasoft.taggroup/library/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/com.aotasoft.taggroup/library) +[![Build Status](https://travis-ci.org/leonacky/AndroidTagGroup.svg?branch=master)](https://travis-ci.org/leonacky/AndroidTagGroup) -Also you can contribute new idea to me. +The TagGroup is a special layout with a set of tags. I have developed from 2dxgujun/AndroidTagGroup +with new features: + +1. TagGravity + +2. Tag Selected + +3. Get all tags is selected + +4. New implement for detect tag click event # Demo @@ -18,34 +26,37 @@ Also you can contribute new idea to me. ![screenshot2](http://ww4.sinaimg.cn/large/bce2dea9jw1esbsbngv8fj20u005w75v.jpg) ![screenshot3](http://ww4.sinaimg.cn/large/bce2dea9jw1esbsbmoagij20u005sabl.jpg) -[Download Demo](https://github.com/2dxgujun/AndroidTagGroup/releases/download/v1.4/AndroidTagGroup-Demo-v1.4.apk) +### Tag Gravity +![screenshot4](https://dl.dropboxusercontent.com/u/25101600/tag_gravity.png) + +[Download Demo](https://dl.dropboxusercontent.com/u/25101600/TagGroup-demo-release.apk) # Usage ## Step 1 -#### Gradle -```groovy -dependencies { - compile 'me.gujun.android.taggroup:library:1.4@aar' -} -``` - #### Maven ```xml - me.gujun.android.taggroup + com.aotasoft.taggroup library - 1.4 - apklib + 1.6 + aar ``` +#### Gradle +```groovy +dependencies { + compile 'com.aotasoft.taggroup:library:1.6' +} +``` + ## Step 2 Use it in your own code: ```xml - ``` @@ -70,6 +81,17 @@ To delete a tag as user press "Backspace" key or double-tap the tag which you wa Implement a callback interface: `TagGroup.OnTagClickListener`, and set the listener via `setOnTagClickListener()`. +#### How to set a tag is selected? + +To set tag is sellected for TagGroup: use `tagroup.setSelectedTag(...)` + +#### How to get all tags is selected? + +To get all tags is sellected for TagGroup: use `tagroup.getSelectedTags(...)` will return all position of tag is selected + +#### Gravity for TagGroup + +To set gravity for TagGroup: use `setGravity(...)` supported `TagGroup.Gravity.LEFT`, `TagGroup.Gravity.MIDDLE` and `TagGroup.Gravity.RIGHT` # Build @@ -88,7 +110,7 @@ There are several attributes you can set: | attr | default | mean | |:------------------------- |:---------------- |:------------------------------------------------------- | | atg_isAppendMode | false | Determine the TagGroup mode, APPEND or single DISPLAY. | -| atg_inputHint | Add Tag/添加标签 | The hint of the INPUT tag. | +| atg_inputHint | Add Tag | The hint of the INPUT tag. | | atg_borderColor | #49C120 | The tag outline border color. | | atg_textColor | #49C120 | The tag text color. | | atg_backgroundColor | #FFFFFF | The tag background color. | @@ -108,19 +130,11 @@ There are several attributes you can set: | atg_verticalPadding | 3dp | The vertical tag padding.(Mark4) | # Developed By - -Jun Gu - <2dxgujun@gmail.com> - - - Follow me on Weibo - - - Follow me on Google Plus - +Tuan Dinh - from origin project 2dxgujun/AndroidTagGroup # License - Copyright 2015 Jun Gu + Copyright 2015 Tuan Dinh Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/build.gradle b/build.gradle index cd74ded..62ca2b9 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,9 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath('com.android.tools.build:gradle:2.2.0') { + force = true + } } } diff --git a/demo/build.gradle b/demo/build.gradle index 8b3ed8d..f76226d 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 21 - buildToolsVersion '21.1.1' + compileSdkVersion 24 + buildToolsVersion '24.0.0' defaultConfig { - applicationId 'me.gujun.android.taggroup.demo' - minSdkVersion 8 - targetSdkVersion 21 + applicationId 'com.aotasoft.taggroup.demo' + minSdkVersion 9 + targetSdkVersion 24 versionName project.VERSION_NAME versionCode Integer.parseInt(project.VERSION_CODE) } @@ -18,9 +18,12 @@ android { } productFlavors { } + lintOptions { + abortOnError false + } } dependencies { compile project(':library') - compile 'com.android.support:appcompat-v7:21.0.3' + compile 'com.android.support:appcompat-v7:24.2.1' } \ No newline at end of file diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml index 732aefd..c51ab28 100644 --- a/demo/src/main/AndroidManifest.xml +++ b/demo/src/main/AndroidManifest.xml @@ -1,13 +1,13 @@ + package="com.aotasoft.taggroup.demo" > - + @@ -15,12 +15,12 @@ + android:parentActivityName="com.aotasoft.taggroup.demo.MainActivity" > + android:value="com.aotasoft.taggroup.demo.MainActivity" /> diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/demo/src/main/java/com/aotasoft/taggroup/demo/MainActivity.java similarity index 79% rename from demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java rename to demo/src/main/java/com/aotasoft/taggroup/demo/MainActivity.java index 872bf9f..019abfd 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java +++ b/demo/src/main/java/com/aotasoft/taggroup/demo/MainActivity.java @@ -1,4 +1,4 @@ -package me.gujun.android.taggroup.demo; +package com.aotasoft.taggroup.demo; import android.content.Intent; import android.os.Bundle; @@ -9,8 +9,8 @@ import android.widget.TextView; import android.widget.Toast; -import me.gujun.android.taggroup.TagGroup; -import me.gujun.android.taggroup.demo.db.TagsManager; +import com.aotasoft.taggroup.TagGroup; +import com.aotasoft.taggroup.demo.db.TagsManager; public class MainActivity extends ActionBarActivity { @@ -19,6 +19,8 @@ public class MainActivity extends ActionBarActivity { private TagGroup mDefaultTagGroup; private TagGroup mSmallTagGroup; private TagGroup mLargeTagGroup; + private TagGroup mLargeMiddleTagGroup; + private TagGroup mLargeRightTagGroup; private TagGroup mBeautyTagGroup; private TagGroup mBeautyInverseTagGroup; @@ -26,8 +28,9 @@ public class MainActivity extends ActionBarActivity { private TagGroup.OnTagClickListener mTagClickListener = new TagGroup.OnTagClickListener() { @Override - public void onTagClick(String tag) { + public void onTagClick(TagGroup tagGroup, String tag, int position) { Toast.makeText(MainActivity.this, tag, Toast.LENGTH_SHORT).show(); + tagGroup.setSelectedTag(position, !tagGroup.isSelectedTag(position)); } }; @@ -50,6 +53,8 @@ public void onClick(View v) { mDefaultTagGroup = (TagGroup) findViewById(R.id.tag_group); mSmallTagGroup = (TagGroup) findViewById(R.id.tag_group_small); mLargeTagGroup = (TagGroup) findViewById(R.id.tag_group_large); + mLargeMiddleTagGroup = (TagGroup) findViewById(R.id.tag_group_large_middle); + mLargeRightTagGroup = (TagGroup) findViewById(R.id.tag_group_large_right); mBeautyTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty); mBeautyInverseTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty_inverse); if (tags != null && tags.length > 0) { @@ -58,6 +63,11 @@ public void onClick(View v) { mLargeTagGroup.setTags(tags); mBeautyTagGroup.setTags(tags); mBeautyInverseTagGroup.setTags(tags); + + mLargeMiddleTagGroup.setTags(tags); + mLargeMiddleTagGroup.setGravity(TagGroup.TagGravity.MIDDLE); + mLargeRightTagGroup.setTags(tags); + mLargeRightTagGroup.setGravity(TagGroup.TagGravity.RIGHT); } MyTagGroupOnClickListener tgClickListener = new MyTagGroupOnClickListener(); @@ -85,6 +95,10 @@ protected void onResume() { mLargeTagGroup.setTags(tags); mBeautyTagGroup.setTags(tags); mBeautyInverseTagGroup.setTags(tags); + mLargeMiddleTagGroup.setTags(tags); + mLargeMiddleTagGroup.setGravity(TagGroup.TagGravity.MIDDLE); + mLargeRightTagGroup.setTags(tags); + mLargeRightTagGroup.setGravity(TagGroup.TagGravity.RIGHT); } @Override diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/demo/src/main/java/com/aotasoft/taggroup/demo/TagEditorActivity.java similarity index 51% rename from demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java rename to demo/src/main/java/com/aotasoft/taggroup/demo/TagEditorActivity.java index 27d2ea1..713b202 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java +++ b/demo/src/main/java/com/aotasoft/taggroup/demo/TagEditorActivity.java @@ -1,15 +1,19 @@ -package me.gujun.android.taggroup.demo; +package com.aotasoft.taggroup.demo; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; +import android.text.Editable; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.widget.Toast; -import me.gujun.android.taggroup.TagGroup; -import me.gujun.android.taggroup.demo.db.TagsManager; +import com.aotasoft.taggroup.TagGroup; +import com.aotasoft.taggroup.demo.db.TagsManager; public class TagEditorActivity extends ActionBarActivity { + final String TAG = "TagEditorActivity"; private TagGroup mTagGroup; private TagsManager mTagsManager; @@ -22,7 +26,32 @@ protected void onCreate(Bundle savedInstanceState) { String[] tags = mTagsManager.getTags(); mTagGroup = (TagGroup) findViewById(R.id.tag_group); + mTagGroup.setGravity(TagGroup.TagGravity.LEFT); mTagGroup.setTags(tags); + mTagGroup.setOnTagInputTextListener(new TagGroup.OnTagInputTextListener() { + @Override + public void beforeTextChanged(TagGroup.TagView tv, CharSequence s, int start, int count, int after) { + Log.i(TAG, "beforeTextChanged="+s.toString()); + } + + @Override + public void onTextChanged(TagGroup.TagView tv, CharSequence s, int start, int before, int count) { + Log.i(TAG, "onTextChanged="+s.toString()); + } + + @Override + public void afterTextChanged(TagGroup.TagView tv, Editable s) { + Log.i(TAG, "afterTextChanged="+s.toString()); + } + }); + + mTagGroup.setOnSubmitActionListener(new TagGroup.OnSubmitActionListener() { + @Override + public boolean onSubmit(TagGroup.TagView tv) { + mTagGroup.submitTag(); + return false; + } + }); } @Override diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java b/demo/src/main/java/com/aotasoft/taggroup/demo/db/DatabaseHelper.java similarity index 94% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java rename to demo/src/main/java/com/aotasoft/taggroup/demo/db/DatabaseHelper.java index ba10f8d..a3b161c 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java +++ b/demo/src/main/java/com/aotasoft/taggroup/demo/db/DatabaseHelper.java @@ -1,4 +1,4 @@ -package me.gujun.android.taggroup.demo.db; +package com.aotasoft.taggroup.demo.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java b/demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsManager.java similarity index 97% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java rename to demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsManager.java index 841fc28..fcee7f7 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java +++ b/demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsManager.java @@ -1,4 +1,4 @@ -package me.gujun.android.taggroup.demo.db; +package com.aotasoft.taggroup.demo.db; import android.content.ContentValues; import android.content.Context; diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java b/demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsTable.java similarity index 87% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java rename to demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsTable.java index b05a5c1..2c4109d 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java +++ b/demo/src/main/java/com/aotasoft/taggroup/demo/db/TagsTable.java @@ -1,4 +1,4 @@ -package me.gujun.android.taggroup.demo.db; +package com.aotasoft.taggroup.demo.db; import android.provider.BaseColumns; diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml index db8f830..9598991 100644 --- a/demo/src/main/res/layout/activity_main.xml +++ b/demo/src/main/res/layout/activity_main.xml @@ -1,81 +1,112 @@ - - - + android:layout_height="match_parent"> - + android:orientation="vertical" + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + tools:context="com.aotasoft.taggroup.demo.MainActivity"> - + - - - - - - - - - + - + - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/src/main/res/layout/activity_tag_editor.xml b/demo/src/main/res/layout/activity_tag_editor.xml index 6749944..ee5690a 100644 --- a/demo/src/main/res/layout/activity_tag_editor.xml +++ b/demo/src/main/res/layout/activity_tag_editor.xml @@ -9,9 +9,9 @@ android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" - tools:context=".TagEditorActivity"> + tools:context="com.aotasoft.taggroup.demo.TagEditorActivity"> - diff --git a/demo/src/main/res/values-en/strings.xml b/demo/src/main/res/values-en/strings.xml deleted file mode 100644 index 5f2428d..0000000 --- a/demo/src/main/res/values-en/strings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - TagGroup-Demo - Add Tags - Edit Tags - Tags (Default) - Tags (Large) - Tags (Small) - \ No newline at end of file diff --git a/demo/src/main/res/values-zh/strings.xml b/demo/src/main/res/values-zh/strings.xml new file mode 100644 index 0000000..9f66a03 --- /dev/null +++ b/demo/src/main/res/values-zh/strings.xml @@ -0,0 +1,12 @@ + + TagGroup-Demo + 编辑标签 + 添加标签 + 标签(默认) + 标签(小号) + 标签(大号) + Submit + Edit + Tags (Large-Middle) + Tags (Large-Right) + diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml index 88f07de..f59f303 100644 --- a/demo/src/main/res/values/strings.xml +++ b/demo/src/main/res/values/strings.xml @@ -1,10 +1,13 @@ + TagGroup-Demo - 编辑标签 - 添加标签 - 标签(默认) - 标签(小号) - 标签(大号) - Submit - Edit - + Add Tags + Edit Tags + Tags (Default) + Tags (Large-Left-Default) + Tags (Small) + Submit + Edit + Tags (Large-Middle) + Tags (Large-Right) + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index e61bff9..07048fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,20 +17,21 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -VERSION_NAME=1.4 -VERSION_CODE=14 -GROUP=me.gujun.android.taggroup +#VERSION_NAME=1.6-SNAPSHOT +VERSION_NAME=1.8 +VERSION_CODE=18 +GROUP=com.aotasoft.taggroup POM_DESCRIPTION=Android Library to display a set of tags -POM_URL=https://github.com/2dxgujun/AndroidTagGroup -POM_SCM_URL=https://github.com/2dxgujun/AndroidTagGroup -POM_SCM_CONNECTION=scm:https://github.com/2dxgujun/AndroidTagGroup.git -POM_SCM_DEV_CONNECTION=scm:https://github.com/2dxgujun/AndroidTagGroup.git +POM_URL=https://github.com/leonacky/AndroidTagGroup +POM_SCM_URL=https://github.com/leonacky/AndroidTagGroup +POM_SCM_CONNECTION=scm:https://github.com/leonacky/AndroidTagGroup.git +POM_SCM_DEV_CONNECTION=scm:https://github.com/leonacky/AndroidTagGroup.git POM_LICENCE_NAME=The Apache Software License, Version 2.0 POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt POM_LICENCE_DIST=repo -POM_DEVELOPER_ID=2dxgujun -POM_DEVELOPER_NAME=Jun Gu +POM_DEVELOPER_ID=leonacky +POM_DEVELOPER_NAME=Tuan Dinh SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c71e76..fc7bc95 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Wed Oct 05 17:05:13 ICT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/library/build.gradle b/library/build.gradle index 87bfd43..fab6280 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,4 +1,11 @@ apply plugin: 'com.android.library' + +ext { + PUBLISH_GROUP_ID = 'com.aotasoft.taggroup' + PUBLISH_ARTIFACT_ID = 'library' + PUBLISH_VERSION = '1.8' +} + android { compileSdkVersion 21 buildToolsVersion '21.1.1' @@ -14,5 +21,7 @@ android { } // Used to push in maven apply from: '../maven-push.gradle' +// Use for jCenter +//apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle' dependencies { } \ No newline at end of file diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index 5fe5d86..4be2190 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java b/library/src/main/java/com/aotasoft/taggroup/TagGroup.java similarity index 78% rename from library/src/main/java/me/gujun/android/taggroup/TagGroup.java rename to library/src/main/java/com/aotasoft/taggroup/TagGroup.java index 5f2ae99..b7d84eb 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/com/aotasoft/taggroup/TagGroup.java @@ -1,4 +1,4 @@ -package me.gujun.android.taggroup; +package com.aotasoft.taggroup; import android.content.Context; import android.content.res.TypedArray; @@ -17,8 +17,8 @@ import android.text.TextWatcher; import android.text.method.ArrowKeyMovementMethod; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; -import android.view.Gravity; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; @@ -26,6 +26,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; +import android.widget.EditText; import android.widget.TextView; import java.util.ArrayList; @@ -45,9 +46,14 @@ * is not focusable. *

* + * * @author Jun Gu (http://2dxgujun.com) - * @version 2.0 * @since 2015-2-3 14:16:32 + * + * Development by + * @author Tuan Dinh (http://aotasoft.com) + * @version 1.5 + * @since 2016-6-9 09:32:20 */ public class TagGroup extends ViewGroup { private final int default_border_color = Color.rgb(0x49, 0xC1, 0x20); @@ -68,72 +74,143 @@ public class TagGroup extends ViewGroup { private final float default_horizontal_padding; private final float default_vertical_padding; - /** Indicates whether this TagGroup is set up to APPEND mode or DISPLAY mode. Default is false. */ + /** + * Indicates whether this TagGroup is set up to APPEND mode or DISPLAY mode. Default is false. + */ private boolean isAppendMode; - /** The text to be displayed when the text of the INPUT tag is empty. */ + /** + * The text to be displayed when the text of the INPUT tag is empty. + */ private CharSequence inputHint; - /** The tag outline border color. */ + /** + * The tag outline border color. + */ private int borderColor; - /** The tag text color. */ + /** + * The tag text color. + */ private int textColor; - /** The tag background color. */ + /** + * The tag background color. + */ private int backgroundColor; - /** The dash outline border color. */ + /** + * The dash outline border color. + */ private int dashBorderColor; - /** The input tag hint text color. */ + /** + * The input tag hint text color. + */ private int inputHintColor; - /** The input tag type text color. */ + /** + * The input tag type text color. + */ private int inputTextColor; - /** The checked tag outline border color. */ + /** + * The checked tag outline border color. + */ private int checkedBorderColor; - /** The check text color */ + /** + * The check text color + */ private int checkedTextColor; - /** The checked marker color. */ + /** + * The checked marker color. + */ private int checkedMarkerColor; - /** The checked tag background color. */ + /** + * The checked tag background color. + */ private int checkedBackgroundColor; - /** The tag background color, when the tag is being pressed. */ + /** + * The tag background color, when the tag is being pressed. + */ private int pressedBackgroundColor; - /** The tag outline border stroke width, default is 0.5dp. */ + /** + * The tag outline border stroke width, default is 0.5dp. + */ private float borderStrokeWidth; - /** The tag text size, default is 13sp. */ + /** + * The tag text size, default is 13sp. + */ private float textSize; - /** The horizontal tag spacing, default is 8.0dp. */ + /** + * The horizontal tag spacing, default is 8.0dp. + */ private int horizontalSpacing; - /** The vertical tag spacing, default is 4.0dp. */ + /** + * The vertical tag spacing, default is 4.0dp. + */ private int verticalSpacing; - /** The horizontal tag padding, default is 12.0dp. */ + /** + * The horizontal tag padding, default is 12.0dp. + */ private int horizontalPadding; - /** The vertical tag padding, default is 3.0dp. */ + /** + * The vertical tag padding, default is 3.0dp. + */ private int verticalPadding; - /** Listener used to dispatch tag change event. */ + /** + * Listener used to dispatch tag change event. + */ private OnTagChangeListener mOnTagChangeListener; - /** Listener used to dispatch tag click event. */ + /** + * Listener used to dispatch tag click event. + */ private OnTagClickListener mOnTagClickListener; - /** Listener used to handle tag click event. */ + /** + * Listener used to dispatch tag input event. + */ + private OnTagInputTextListener mOnTagInputTextListener; + + private OnSubmitActionListener mOnSubmitAction; + + /** + * Listener used to handle tag click event. + */ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener(); + /** + * TagGravity in taggroup + * Added by Tuan Dinh + */ + private TagGravity gravity = TagGravity.LEFT; + + public void setGravity(TagGravity gravity) { + this.gravity = gravity; + } + + public TagGravity getGravity() { + return this.gravity; + } + + public enum TagGravity { + LEFT, + MIDDLE, + RIGHT + } + public TagGroup(Context context) { this(context, null); } @@ -259,6 +336,9 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { heightMode == MeasureSpec.EXACTLY ? heightSize : height); } + + List> _tags = new ArrayList<>(); + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int parentLeft = getPaddingLeft(); @@ -270,6 +350,9 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { int childTop = parentTop; int rowMaxHeight = 0; + int row = 0; + + _tags.clear(); final int count = getChildCount(); for (int i = 0; i < count; i++) { @@ -282,14 +365,73 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { childLeft = parentLeft; childTop += rowMaxHeight + verticalSpacing; rowMaxHeight = height; + row++; } else { rowMaxHeight = Math.max(rowMaxHeight, height); } - child.layout(childLeft, childTop, childLeft + width, childTop + height); + //Comment by Tuan Dinh +// child.layout(childLeft, childTop, childLeft + width, childTop + height); + ArrayList tagrow = new ArrayList<>(); + if (_tags.size() == row) + _tags.add(tagrow); + else + tagrow = _tags.get(row); + ChildHolder childHolder = new ChildHolder(); + childHolder.child = child; + childHolder.left = childLeft; + childHolder.top = childTop; + childHolder.right = childLeft + width; + childHolder.bottom = childTop + height; + tagrow.add(childHolder); childLeft += width + horizontalSpacing; } } + + + /** + * Calculating new postion for Tags in TagGravity + * Added by Tuan Dinh + * */ + for (int i = 0; i < _tags.size(); i++) { + ArrayList tagrow = _tags.get(i); + if (tagrow.size() > 0) { + ChildHolder lastChildHolder = tagrow.get(tagrow.size() - 1); + int space = (parentRight - lastChildHolder.right); + int space2 = space / 2; + for (int j = 0; j < tagrow.size(); j++) { + ChildHolder childHolder = tagrow.get(j); + if (getGravity() == TagGravity.MIDDLE) + childHolder.child.layout(childHolder.left + space2, childHolder.top, childHolder.right + space2, childHolder.bottom); + if (getGravity() == TagGravity.LEFT) + childHolder.child.layout(childHolder.left, childHolder.top, childHolder.right, childHolder.bottom); + if (getGravity() == TagGravity.RIGHT) + childHolder.child.layout(childHolder.left + space, childHolder.top, childHolder.right + space, childHolder.bottom); + } + } + } + } + + public List getSelectedTags() { + List selected = new ArrayList<>(); + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final TagView child = (TagView) getChildAt(i); + if (child.isSelectedTag()) { + selected.add(i); + } + } + return selected; + } + + public boolean isSelectedTag(int position) { + TagView child = (TagView) getChildAt(position); + return child.isSelectedTag(); + } + + public void setSelectedTag(int position, boolean selected) { + TagView child = (TagView) getChildAt(position); + child.setSelectedTag(selected); } @Override @@ -386,7 +528,7 @@ public String[] getTags() { } /** - * @see #setTags(String...) + * @param tagList The list string of Tag */ public void setTags(List tagList) { setTags(tagList.toArray(new String[tagList.size()])); @@ -399,8 +541,10 @@ public void setTags(List tagList) { */ public void setTags(String... tags) { removeAllViews(); + int i = 0; for (final String tag : tags) { - appendTag(tag); + appendTag(tag, i); + i++; } if (isAppendMode) { @@ -477,6 +621,7 @@ protected void appendInputTag(String tag) { final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag); newInputTag.setOnClickListener(mInternalTagClickListener); + newInputTag.setPosition(-1); addView(newInputTag); } @@ -484,9 +629,11 @@ protected void appendInputTag(String tag) { * Append tag to this group. * * @param tag the tag to append. + * @param position the position of tag in TagGroup. */ - protected void appendTag(CharSequence tag) { + protected void appendTag(CharSequence tag, int position) { final TagView newTag = new TagView(getContext(), TagView.STATE_NORMAL, tag); + newTag.setPosition(position); newTag.setOnClickListener(mInternalTagClickListener); addView(newTag); } @@ -515,6 +662,14 @@ public void setOnTagClickListener(OnTagClickListener l) { mOnTagClickListener = l; } + public void setOnTagInputTextListener(OnTagInputTextListener l) { + mOnTagInputTextListener = l; + } + + public void setOnSubmitActionListener(OnSubmitActionListener l) { + mOnSubmitAction = l; + } + protected void deleteTag(TagView tagView) { removeView(tagView); if (mOnTagChangeListener != null) { @@ -528,14 +683,14 @@ protected void deleteTag(TagView tagView) { public interface OnTagChangeListener { /** * Called when a tag has been appended to the group. - * + * @param tagGroup the TagGroup object. * @param tag the appended tag. */ void onAppend(TagGroup tagGroup, String tag); /** * Called when a tag has been deleted from the the group. - * + * @param tagGroup the TagGroup object. * @param tag the deleted tag. */ void onDelete(TagGroup tagGroup, String tag); @@ -547,10 +702,24 @@ public interface OnTagChangeListener { public interface OnTagClickListener { /** * Called when a tag has been clicked. - * - * @param tag The tag text of the tag that was clicked. + * @param tagGroup The TagGroup object + * @param tag The text of tag that was clicked. + * @param position The position of tag that was clicked. */ - void onTagClick(String tag); + void onTagClick(TagGroup tagGroup, String tag, int position); + } + + /** + * Interface definition for a callback to be invoked when input text. + */ + public interface OnTagInputTextListener { + void beforeTextChanged(TagView tv, CharSequence s, int start, int count, int after); + void onTextChanged(TagView tv, CharSequence s, int start, int before, int count); + void afterTextChanged(TagView tv, Editable s); + } + + public interface OnSubmitActionListener { + boolean onSubmit(TagView tv); } /** @@ -639,7 +808,7 @@ public void onClick(View v) { } } else { if (mOnTagClickListener != null) { - mOnTagClickListener.onTagClick(tag.getText().toString()); + mOnTagClickListener.onTagClick(TagGroup.this, tag.getText().toString(), tag.getPosition()); } } } @@ -648,23 +817,40 @@ public void onClick(View v) { /** * The tag view which has two states can be either NORMAL or INPUT. */ - class TagView extends TextView { + public class TagView extends TextView { public static final int STATE_NORMAL = 1; public static final int STATE_INPUT = 2; - /** The offset to the text. */ + private int position = 0; + + /** + * The offset to the text. + */ private static final int CHECKED_MARKER_OFFSET = 3; - /** The stroke width of the checked marker */ + /** + * The stroke width of the checked marker + */ private static final int CHECKED_MARKER_STROKE_WIDTH = 4; - /** The current state. */ + /** + * The current state. + */ private int mState; - /** Indicates the tag if checked. */ + /** + * Indicates the tag if checked. + */ private boolean isChecked = false; - /** Indicates the tag if pressed. */ + /** + * Indicates the tag if selected. + */ + private boolean isSelectedTag = false; + + /** + * Indicates the tag if pressed. + */ private boolean isPressed = false; private Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); @@ -673,28 +859,44 @@ class TagView extends TextView { private Paint mCheckedMarkerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - /** The rect for the tag's left corner drawing. */ + /** + * The rect for the tag's left corner drawing. + */ private RectF mLeftCornerRectF = new RectF(); - /** The rect for the tag's right corner drawing. */ + /** + * The rect for the tag's right corner drawing. + */ private RectF mRightCornerRectF = new RectF(); - /** The rect for the tag's horizontal blank fill area. */ + /** + * The rect for the tag's horizontal blank fill area. + */ private RectF mHorizontalBlankFillRectF = new RectF(); - /** The rect for the tag's vertical blank fill area. */ + /** + * The rect for the tag's vertical blank fill area. + */ private RectF mVerticalBlankFillRectF = new RectF(); - /** The rect for the checked mark draw bound. */ + /** + * The rect for the checked mark draw bound. + */ private RectF mCheckedMarkerBound = new RectF(); - /** Used to detect the touch event. */ + /** + * Used to detect the touch event. + */ private Rect mOutRect = new Rect(); - /** The path for draw the tag's outline border. */ + /** + * The path for draw the tag's outline border. + */ private Path mBorderPath = new Path(); - /** The path effect provide draw the dash border. */ + /** + * The path effect provide draw the dash border. + */ private PathEffect mPathEffect = new DashPathEffect(new float[]{10, 5}, 0); { @@ -714,7 +916,7 @@ public TagView(Context context, final int state, CharSequence text) { TagGroup.LayoutParams.WRAP_CONTENT, TagGroup.LayoutParams.WRAP_CONTENT)); - setGravity(Gravity.CENTER); + setGravity(android.view.Gravity.CENTER); setText(text); setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); @@ -725,6 +927,11 @@ public TagView(Context context, final int state, CharSequence text) { setFocusableInTouchMode(state == STATE_INPUT); setHint(state == STATE_INPUT ? inputHint : null); setMovementMethod(state == STATE_INPUT ? ArrowKeyMovementMethod.getInstance() : null); + if(state == STATE_INPUT) { + setImeOptions(EditorInfo.IME_ACTION_DONE); + } + + setSingleLine(); // Interrupted long click event to avoid PAUSE popup. setOnLongClickListener(new OnLongClickListener() { @@ -755,6 +962,13 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { } return true; } + if (actionId == EditorInfo.IME_ACTION_DONE && mOnSubmitAction!=null) { + //do here your stuff f + if (isInputAvailable()) { + endInput(); + return mOnSubmitAction.onSubmit(TagView.this); + } + } return false; } }); @@ -797,14 +1011,23 @@ public void beforeTextChanged(CharSequence s, int start, int count, int after) { if (checkedTagView != null) { checkedTagView.setChecked(false); } + if(mOnTagInputTextListener!=null) { + mOnTagInputTextListener.beforeTextChanged(TagView.this, s, start, count, after); + } } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { + if(mOnTagInputTextListener!=null) { + mOnTagInputTextListener.onTextChanged(TagView.this, s, start, before, count); + } } @Override public void afterTextChanged(Editable s) { + if(mOnTagInputTextListener!=null) { + mOnTagInputTextListener.afterTextChanged(TagView.this, s); + } } }); } @@ -822,12 +1045,34 @@ public void setChecked(boolean checked) { // Make the checked mark drawing region. setPadding(horizontalPadding, verticalPadding, - isChecked ? (int) (horizontalPadding + getHeight() / 2.5f + CHECKED_MARKER_OFFSET) - : horizontalPadding, + isChecked ? (int) (horizontalPadding + getHeight() / 2.5f + CHECKED_MARKER_OFFSET) : horizontalPadding, verticalPadding); invalidatePaint(); } + /** + * Set whether this tag view is in the selected state. + * + * @param selected true is selected, false otherwise + */ + public void setSelectedTag(boolean selected) { + isSelectedTag = selected; + // Make the checked mark drawing region. + invalidatePaint(); + } + + public boolean isSelectedTag() { + return isSelectedTag; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } + /** * Call this method to end this tag's INPUT state. */ @@ -873,6 +1118,10 @@ private void invalidatePaint() { mBorderPaint.setColor(checkedBorderColor); mBackgroundPaint.setColor(checkedBackgroundColor); setTextColor(checkedTextColor); + } else if (isSelectedTag) { + mBorderPaint.setColor(checkedBorderColor); + mBackgroundPaint.setColor(checkedBackgroundColor); + setTextColor(checkedTextColor); } else { mBorderPaint.setColor(borderColor); mBackgroundPaint.setColor(backgroundColor); @@ -880,9 +1129,15 @@ private void invalidatePaint() { } } } else { - mBorderPaint.setColor(borderColor); - mBackgroundPaint.setColor(backgroundColor); - setTextColor(textColor); + if (isSelectedTag) { + mBorderPaint.setColor(checkedBorderColor); + mBackgroundPaint.setColor(checkedBackgroundColor); + setTextColor(checkedTextColor); + } else { + mBorderPaint.setColor(borderColor); + mBackgroundPaint.setColor(backgroundColor); + setTextColor(textColor); + } } if (isPressed) { @@ -1022,4 +1277,12 @@ public boolean deleteSurroundingText(int beforeLength, int afterLength) { } } } + + /** + * A class holder of a Tag (TagGravity) + */ + class ChildHolder { + View child; + int left, top, right, bottom; + } } \ No newline at end of file diff --git a/maven-push.gradle b/maven-push.gradle index 2291817..719bcdd 100644 --- a/maven-push.gradle +++ b/maven-push.gradle @@ -28,15 +28,15 @@ def getReleaseRepositoryUrl() { def getSnapshotRepositoryUrl() { return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL - : "https://oss.sonatype.org/content/repositories/snapshots/" + : "https://oss.sonatype.org/content/repositories:w!/snapshots/" } def getRepositoryUsername() { - return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" + return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "leonacky" } def getRepositoryPassword() { - return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" + return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "@dinhtuan1\$" } afterEvaluate { project ->