diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..bdb0cab
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,17 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/.travis.yml b/.travis.yml
index 3c8a6ed..0804fe7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,37 +1,29 @@
-language: java
+language: android
jdk: oraclejdk7
branches:
only:
- master
env:
- matrix:
- - ANDROID_TARGET=android-21 ANDROID_ABI=armeabi-v7a
+ global:
+ - ADB_INSTALL_TIMEOUT=8 # minutes (2 minutes by default)
+android:
+ components:
+ - tools
+ - build-tools-23.0.2
+ - android-23
-before_install:
- # Install base Android SDK
- - sudo apt-get update -qq
- - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch > /dev/null; fi
- - wget http://dl.google.com/android/android-sdk_r24.0.2-linux.tgz
- - tar xzf android-sdk_r24.0.2-linux.tgz
- - export ANDROID_HOME=$PWD/android-sdk-linux
- - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
- - chmod +x gradlew
+ - extra-android-m2repository
+
+ - sys-img-armeabi-v7a-android-23
- # 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
- - export PATH=$GRADLE_HOME/bin:$PATH
+ licenses:
+ - 'android-sdk-license-.+'
- # 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 --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
+before_install:
+ - chmod +x gradlew
-install:
- - ./gradlew assemble
\ No newline at end of file
+before_script:
+ - echo no | android create avd --force -n test -t android-23 --abi armeabi-v7a
+ - emulator -avd test -no-skin -no-audio -no-window &
+ - android-wait-for-emulator
+ - adb shell input keyevent 82 &
\ No newline at end of file
diff --git a/CHANGELOG b/CHANGELOG
deleted file mode 100644
index 5e48513..0000000
--- a/CHANGELOG
+++ /dev/null
@@ -1,35 +0,0 @@
-Change Log
-==========
-
-Version 1.4 *(2015-05-23)*
-----------------------------
-
-- Fix: Duplicate "attr" name issues when using multiple Android libraries.
-
-Version 1.3 *(2015-05-21)*
-----------------------------
-
-- Attributes refactor.
-- Add listener for detect tag click event.
-- Fix: Interrupted click event by touch event.
-
-
-Version 1.2 *(2015-04-14)*
-----------------------------
-
-- Fix: Google soft keyboard backspace issue.
-- Add tag background color feature.
-
-
-Version 1.1 *(2015-02-28)*
-----------------------------
-
-- Fix: EditorActionListener.
-- Fix: Uncheck tag when user is typing.
-- Add `submitTag()` to submit a new tag.
-
-
-Version 1.0 *(2015-02-10)*
-----------------------------
-
-- Initial release.
\ No newline at end of file
diff --git a/README.md b/README.md
index 2a6aa9f..825fac4 100644
--- a/README.md
+++ b/README.md
@@ -1,132 +1,72 @@
-# `AndroidTagGroup`
+# 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)
-
-The TagGroup is a special layout with a set of tags. You can use it to tag people, books or anything you want.
-
-Also you can contribute new idea to me.
-
-# Demo
+AndroidTagGroup is a special layout with a set of tags. You can use it to tag people, books or anything you want.
### Screenshot
![screenshot1](http://ww4.sinaimg.cn/large/bce2dea9jw1esbsby9v5fj20u00w8jxx.jpg)
-
-### Edit Tags
![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)
-
-# Usage
-
-## Step 1
-
-#### Gradle
-```groovy
-dependencies {
- compile 'me.gujun.android.taggroup:library:1.4@aar'
-}
-```
-
-#### Maven
-```xml
-
- me.gujun.android.taggroup
- library
- 1.4
- apklib
-
-```
-
-## Step 2
+## Usage
+### Step 1
+Follow [these steps](https://jitpack.io/#alirezaaa/AndroidTagGroup/v1.7.3).
+### Step 2
Use it in your own code:
```xml
-
+
```
```java
-TagGroup mTagGroup = (TagGroup) findViewById(R.id.tag_group);
-mTagGroup.setTags(new String[]{"Tag1", "Tag2", "Tag3"});
+AndroidTagGroup mTagGroup = (AndroidTagGroup) findViewById(R.id.androidTagGroup);
+mTagGroup.setTags(new String[]{"Tag 1", "Tag 2", "Tag 3"});
```
-Use `setTags(...)` to set the initial tags in the group.
-
-#### How to submit a new tag?
-
-To "submit" a new tag as user press "Enter" or tap the blank area of the tag group, also you can "submit" a new tag via `submitTag()`.
-
-**Note**: Google keyboard (a few soft keyboard not honour the key event) currently not supported "Enter" key to "submit" a new tag.
-
-#### How to delete a tag?
-To delete a tag as user press "Backspace" key or double-tap the tag which you want to delete.
-
-#### How to detect tag click event?
-
-Implement a callback interface: `TagGroup.OnTagClickListener`, and set the listener via `setOnTagClickListener()`.
-
-
-# Build
-
-run `./gradlew assembleDebug` (Mac/Linux)
-
-or
-
-run `gradlew.bat assembleDebug` (Windows)
+### Notes
+- Use `setTags(...)` to set the initial tags in the group.
+- To submit a new tag as user press "Enter" key or tap the blank area of the tag group, use `submitTag()`.
+- To delete a tag as user press "Backspace", double-tap the tag which you want to delete.
+- There are following interfaces to implement; `OnTagLimitationExceedListener`, `OnTagChangeListener`, and `OnTagClickListener`.
# Attributes
-
-There are several attributes you can set:
-
-![Dimension illustrate](http://ww2.sinaimg.cn/large/bce2dea9gw1epov0i8x6kj20rk054q4g.jpg)
-
-| 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_borderColor | #49C120 | The tag outline border color. |
-| atg_textColor | #49C120 | The tag text color. |
-| atg_backgroundColor | #FFFFFF | The tag background color. |
-| atg_dashBorderColor | #AAAAAA | The tag dash outline border color. |
-| atg_inputHintColor | #80000000 | The input tag hint text color. |
-| atg_inputTextColor | #DE000000 | The input tag type text color.. |
-| atg_checkedBorderColor | #49C120 | The checked tag outline border color. |
-| atg_checkedTextColor | #FFFFFF | The checked text color. |
-| atg_checkedMarkerColor | #FFFFFF | The checked marker color. |
-| atg_checkedBackgroundColor| #49C120 | The checked tag background color. |
-| atg_pressedBackgroundColor| #EDEDED | The tag background color when the tag is being pressed. |
-| atg_borderStrokeWidth | 0.5dp | The tag outline border stroke width. |
-| atg_textSize | 13sp | The tag text size. |
-| atg_horizontalSpacing | 8dp | The horizontal tag spacing.(Mark1) |
-| atg_verticalSpacing | 4dp | The vertical tag spacing.(Mark2) |
-| atg_horizontalPadding | 12dp | The horizontal tag padding.(Mark3) |
-| atg_verticalPadding | 3dp | The vertical tag padding.(Mark4) |
-
-# Developed By
-
-Jun Gu - <2dxgujun@gmail.com>
-
-
-
-
-
-
-
-
-# License
-
+| Attribute | Default Value | Description |
+|:------------------------------|:-----------------------|:--------------------------------------------------------|
+| atg_isAppendMode | false | Determine the mode. |
+| 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. |
+| atg_dashBorderColor | #AAAAAA | The tag dash outline border color. |
+| atg_inputHintColor | #80000000 | The input tag hint text color. |
+| atg_inputTextColor | #DE000000 | The input tag type text color.. |
+| atg_checkedBorderColor | #49C120 | The checked tag outline border color. |
+| atg_checkedTextColor | #FFFFFF | The checked text color. |
+| atg_checkedMarkerColor | #FFFFFF | The checked marker color. |
+| atg_checkedBackgroundColor | #49C120 | The checked tag background color. |
+| atg_pressedBackgroundColor | #EDEDED | The tag background color when the tag is being pressed. |
+| atg_borderStrokeWidth | 0.5dp | The tag outline border stroke width. |
+| atg_textSize | 13sp | The tag text size. |
+| atg_horizontalSpacing | 8dp | The horizontal tag spacing. |
+| atg_verticalSpacing | 4dp | The vertical tag spacing. |
+| atg_horizontalPadding | 12dp | The horizontal tag padding. |
+| atg_verticalPadding | 3dp | The vertical tag padding. |
+| atg_tagsLimitation | no limitation | Adding tags limitation |
+| atg_charsLimitation | no limitation | Characters limitation |
+
+## Developed By
+- Jun Gu - <2dxgujun@gmail.com>
+- Alireza Eskandarpour Shoferi -
+
+## License
Copyright 2015 Jun Gu
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
+ 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,
diff --git a/demo/.gitignore b/app/.gitignore
similarity index 100%
rename from demo/.gitignore
rename to app/.gitignore
diff --git a/demo/build.gradle b/app/build.gradle
similarity index 63%
rename from demo/build.gradle
rename to app/build.gradle
index 8b3ed8d..8f3aaa1 100644
--- a/demo/build.gradle
+++ b/app/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 21
- buildToolsVersion '21.1.1'
+ compileSdkVersion 23
+ buildToolsVersion '23.0.2'
defaultConfig {
- applicationId 'me.gujun.android.taggroup.demo'
+ applicationId 'me.gujun.android.taggroup.app'
minSdkVersion 8
- targetSdkVersion 21
+ targetSdkVersion 23
versionName project.VERSION_NAME
versionCode Integer.parseInt(project.VERSION_CODE)
}
@@ -18,9 +18,13 @@ android {
}
productFlavors {
}
+ // Travis CI needing
+ lintOptions {
+ abortOnError false
+ }
}
dependencies {
compile project(':library')
- compile 'com.android.support:appcompat-v7:21.0.3'
+ compile 'com.android.support:appcompat-v7:23.2.1'
}
\ No newline at end of file
diff --git a/demo/proguard-rules.pro b/app/proguard-rules.pro
similarity index 100%
rename from demo/proguard-rules.pro
rename to app/proguard-rules.pro
diff --git a/demo/src/androidTest/java/me/gujun/android/taggroup/ApplicationTest.java b/app/src/androidTest/java/me/gujun/android/taggroup/ApplicationTest.java
similarity index 100%
rename from demo/src/androidTest/java/me/gujun/android/taggroup/ApplicationTest.java
rename to app/src/androidTest/java/me/gujun/android/taggroup/ApplicationTest.java
diff --git a/demo/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
similarity index 54%
rename from demo/src/main/AndroidManifest.xml
rename to app/src/main/AndroidManifest.xml
index 732aefd..ae1c65d 100644
--- a/demo/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,26 +1,26 @@
-
+
-
+ android:theme="@style/AppTheme">
+
-
+
-
+
+ android:parentActivityName="me.gujun.android.taggroup.app.MainActivity">
+ android:value="me.gujun.android.taggroup.app.MainActivity"/>
diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/app/src/main/java/me/gujun/android/taggroup/app/MainActivity.java
similarity index 51%
rename from demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java
rename to app/src/main/java/me/gujun/android/taggroup/app/MainActivity.java
index 872bf9f..5c9e8e1 100644
--- a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java
+++ b/app/src/main/java/me/gujun/android/taggroup/app/MainActivity.java
@@ -1,4 +1,4 @@
-package me.gujun.android.taggroup.demo;
+package me.gujun.android.taggroup.app;
import android.content.Intent;
import android.os.Bundle;
@@ -9,22 +9,22 @@
import android.widget.TextView;
import android.widget.Toast;
-import me.gujun.android.taggroup.TagGroup;
-import me.gujun.android.taggroup.demo.db.TagsManager;
+import me.gujun.android.taggroup.AndroidTagGroup;
+import me.gujun.android.taggroup.app.db.TagsManager;
public class MainActivity extends ActionBarActivity {
private TextView mPromptText;
- private TagGroup mDefaultTagGroup;
- private TagGroup mSmallTagGroup;
- private TagGroup mLargeTagGroup;
- private TagGroup mBeautyTagGroup;
- private TagGroup mBeautyInverseTagGroup;
+ private AndroidTagGroup mDefaultAndroidTagGroup;
+ private AndroidTagGroup mSmallAndroidTagGroup;
+ private AndroidTagGroup mLargeAndroidTagGroup;
+ private AndroidTagGroup mBeautyAndroidTagGroup;
+ private AndroidTagGroup mBeautyInverseAndroidTagGroup;
private TagsManager mTagsManager;
- private TagGroup.OnTagClickListener mTagClickListener = new TagGroup.OnTagClickListener() {
+ private AndroidTagGroup.OnTagClickListener mTagClickListener = new AndroidTagGroup.OnTagClickListener() {
@Override
public void onTagClick(String tag) {
Toast.makeText(MainActivity.this, tag, Toast.LENGTH_SHORT).show();
@@ -47,32 +47,37 @@ 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);
- mBeautyTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty);
- mBeautyInverseTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty_inverse);
+ mDefaultAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.androidTagGroup);
+ mSmallAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.tag_group_small);
+ mLargeAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.tag_group_large);
+ mBeautyAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.tag_group_beauty);
+ mBeautyInverseAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.tag_group_beauty_inverse);
if (tags != null && tags.length > 0) {
- mDefaultTagGroup.setTags(tags);
- mSmallTagGroup.setTags(tags);
- mLargeTagGroup.setTags(tags);
- mBeautyTagGroup.setTags(tags);
- mBeautyInverseTagGroup.setTags(tags);
+ mDefaultAndroidTagGroup.setTags(tags);
+ mSmallAndroidTagGroup.setTags(tags);
+ mLargeAndroidTagGroup.setTags(tags);
+ mBeautyAndroidTagGroup.setTags(tags);
+ mBeautyInverseAndroidTagGroup.setTags(tags);
}
MyTagGroupOnClickListener tgClickListener = new MyTagGroupOnClickListener();
- mDefaultTagGroup.setOnClickListener(tgClickListener);
- mSmallTagGroup.setOnClickListener(tgClickListener);
- mLargeTagGroup.setOnClickListener(tgClickListener);
- mBeautyTagGroup.setOnClickListener(tgClickListener);
- mBeautyInverseTagGroup.setOnClickListener(tgClickListener);
-
- mDefaultTagGroup.setOnTagClickListener(mTagClickListener);
- mSmallTagGroup.setOnTagClickListener(mTagClickListener);
- mLargeTagGroup.setOnTagClickListener(mTagClickListener);
- mBeautyTagGroup.setOnTagClickListener(mTagClickListener);
- mBeautyInverseTagGroup.setOnTagClickListener(mTagClickListener);
+ mDefaultAndroidTagGroup.setOnClickListener(tgClickListener);
+ mSmallAndroidTagGroup.setOnClickListener(tgClickListener);
+ mLargeAndroidTagGroup.setOnClickListener(tgClickListener);
+ mBeautyAndroidTagGroup.setOnClickListener(tgClickListener);
+ mBeautyInverseAndroidTagGroup.setOnClickListener(tgClickListener);
+
+ mDefaultAndroidTagGroup.setOnTagClickListener(mTagClickListener);
+ mSmallAndroidTagGroup.setOnTagClickListener(mTagClickListener);
+ mLargeAndroidTagGroup.setOnTagClickListener(mTagClickListener);
+ mBeautyAndroidTagGroup.setOnTagClickListener(mTagClickListener);
+ mBeautyInverseAndroidTagGroup.setOnTagClickListener(mTagClickListener);
+ }
+
+ protected void launchTagEditorActivity() {
+ Intent intent = new Intent(MainActivity.this, TagEditorActivity.class);
+ startActivity(intent);
}
@Override
@@ -80,11 +85,11 @@ protected void onResume() {
super.onResume();
String[] tags = mTagsManager.getTags();
mPromptText.setVisibility((tags == null || tags.length == 0) ? View.VISIBLE : View.GONE);
- mDefaultTagGroup.setTags(tags);
- mSmallTagGroup.setTags(tags);
- mLargeTagGroup.setTags(tags);
- mBeautyTagGroup.setTags(tags);
- mBeautyInverseTagGroup.setTags(tags);
+ mDefaultAndroidTagGroup.setTags(tags);
+ mSmallAndroidTagGroup.setTags(tags);
+ mLargeAndroidTagGroup.setTags(tags);
+ mBeautyAndroidTagGroup.setTags(tags);
+ mBeautyInverseAndroidTagGroup.setTags(tags);
}
@Override
@@ -102,11 +107,6 @@ public boolean onOptionsItemSelected(MenuItem item) {
return false;
}
- protected void launchTagEditorActivity() {
- Intent intent = new Intent(MainActivity.this, TagEditorActivity.class);
- startActivity(intent);
- }
-
class MyTagGroupOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/app/src/main/java/me/gujun/android/taggroup/app/TagEditorActivity.java
similarity index 69%
rename from demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java
rename to app/src/main/java/me/gujun/android/taggroup/app/TagEditorActivity.java
index 27d2ea1..e1fb089 100644
--- a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java
+++ b/app/src/main/java/me/gujun/android/taggroup/app/TagEditorActivity.java
@@ -1,16 +1,16 @@
-package me.gujun.android.taggroup.demo;
+package me.gujun.android.taggroup.app;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
-import me.gujun.android.taggroup.TagGroup;
-import me.gujun.android.taggroup.demo.db.TagsManager;
+import me.gujun.android.taggroup.AndroidTagGroup;
+import me.gujun.android.taggroup.app.db.TagsManager;
public class TagEditorActivity extends ActionBarActivity {
- private TagGroup mTagGroup;
+ private AndroidTagGroup mAndroidTagGroup;
private TagsManager mTagsManager;
@Override
@@ -21,8 +21,8 @@ protected void onCreate(Bundle savedInstanceState) {
mTagsManager = TagsManager.getInstance(getApplicationContext());
String[] tags = mTagsManager.getTags();
- mTagGroup = (TagGroup) findViewById(R.id.tag_group);
- mTagGroup.setTags(tags);
+ mAndroidTagGroup = (AndroidTagGroup) findViewById(R.id.androidTagGroup);
+ mAndroidTagGroup.setTags(tags);
}
@Override
@@ -34,11 +34,11 @@ public boolean onCreateOptionsMenu(Menu menu) {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
- mTagsManager.updateTags(mTagGroup.getTags());
+ mTagsManager.updateTags(mAndroidTagGroup.getTags());
finish();
return true;
} else if (item.getItemId() == R.id.action_submit) {
- mTagGroup.submitTag();
+ mAndroidTagGroup.submitTag();
return true;
}
return false;
@@ -46,7 +46,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
@Override
public void onBackPressed() {
- mTagsManager.updateTags(mTagGroup.getTags());
+ mTagsManager.updateTags(mAndroidTagGroup.getTags());
super.onBackPressed();
}
}
\ No newline at end of file
diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java b/app/src/main/java/me/gujun/android/taggroup/app/db/DatabaseHelper.java
similarity index 94%
rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java
rename to app/src/main/java/me/gujun/android/taggroup/app/db/DatabaseHelper.java
index ba10f8d..d72b4b7 100644
--- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java
+++ b/app/src/main/java/me/gujun/android/taggroup/app/db/DatabaseHelper.java
@@ -1,4 +1,4 @@
-package me.gujun.android.taggroup.demo.db;
+package me.gujun.android.taggroup.app.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/app/src/main/java/me/gujun/android/taggroup/app/db/TagsManager.java
similarity index 97%
rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java
rename to app/src/main/java/me/gujun/android/taggroup/app/db/TagsManager.java
index 841fc28..aabc1de 100644
--- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java
+++ b/app/src/main/java/me/gujun/android/taggroup/app/db/TagsManager.java
@@ -1,4 +1,4 @@
-package me.gujun.android.taggroup.demo.db;
+package me.gujun.android.taggroup.app.db;
import android.content.ContentValues;
import android.content.Context;
@@ -52,17 +52,17 @@ public void updateTags(CharSequence... tags) {
}
}
- public void addTag(CharSequence tag) {
- ContentValues values = new ContentValues();
+ public void clearTags() {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
- values.put(TagsTable.TAG, tag.toString());
- db.insert(TagsTable.TABLE_NAME, null, values);
+ db.delete(TagsTable.TABLE_NAME, null, null);
db.close();
}
- public void clearTags() {
+ public void addTag(CharSequence tag) {
+ ContentValues values = new ContentValues();
SQLiteDatabase db = mDbHelper.getWritableDatabase();
- db.delete(TagsTable.TABLE_NAME, null, null);
+ values.put(TagsTable.TAG, tag.toString());
+ db.insert(TagsTable.TABLE_NAME, null, values);
db.close();
}
}
\ No newline at end of file
diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java b/app/src/main/java/me/gujun/android/taggroup/app/db/TagsTable.java
similarity index 87%
rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java
rename to app/src/main/java/me/gujun/android/taggroup/app/db/TagsTable.java
index b05a5c1..e2864cb 100644
--- a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java
+++ b/app/src/main/java/me/gujun/android/taggroup/app/db/TagsTable.java
@@ -1,4 +1,4 @@
-package me.gujun.android.taggroup.demo.db;
+package me.gujun.android.taggroup.app.db;
import android.provider.BaseColumns;
diff --git a/demo/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
similarity index 56%
rename from demo/src/main/res/layout/activity_main.xml
rename to app/src/main/res/layout/activity_main.xml
index db8f830..b33684c 100644
--- a/demo/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,19 +1,19 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ 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=".MainActivity">
+ android:textSize="16sp"/>
+ android:textColor="@android:color/darker_gray"/>
-
+
+ android:background="#DDD"/>
-
+ android:layout_marginTop="5dp"/>
+ android:background="#DDD"/>
-
+ android:layout_marginTop="5dp"/>
+ android:textSize="14sp"/>
-
+ android:layout_marginTop="10dp"/>
+ android:textSize="18sp"/>
-
+ android:layout_marginTop="10dp"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_tag_editor.xml b/app/src/main/res/layout/activity_tag_editor.xml
new file mode 100644
index 0000000..1f2da8f
--- /dev/null
+++ b/app/src/main/res/layout/activity_tag_editor.xml
@@ -0,0 +1,15 @@
+
+
+
+
\ No newline at end of file
diff --git a/demo/src/main/res/menu/menu_main_activity.xml b/app/src/main/res/menu/menu_main_activity.xml
similarity index 67%
rename from demo/src/main/res/menu/menu_main_activity.xml
rename to app/src/main/res/menu/menu_main_activity.xml
index f1764e9..1b8bd5f 100644
--- a/demo/src/main/res/menu/menu_main_activity.xml
+++ b/app/src/main/res/menu/menu_main_activity.xml
@@ -1,8 +1,8 @@
\ No newline at end of file
diff --git a/demo/src/main/res/menu/menu_tag_editor_activity.xml b/app/src/main/res/menu/menu_tag_editor_activity.xml
similarity index 67%
rename from demo/src/main/res/menu/menu_tag_editor_activity.xml
rename to app/src/main/res/menu/menu_tag_editor_activity.xml
index 6d473cf..567904b 100644
--- a/demo/src/main/res/menu/menu_tag_editor_activity.xml
+++ b/app/src/main/res/menu/menu_tag_editor_activity.xml
@@ -1,8 +1,8 @@
\ No newline at end of file
diff --git a/demo/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from demo/src/main/res/mipmap-hdpi/ic_launcher.png
rename to app/src/main/res/mipmap-hdpi/ic_launcher.png
diff --git a/demo/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from demo/src/main/res/mipmap-mdpi/ic_launcher.png
rename to app/src/main/res/mipmap-mdpi/ic_launcher.png
diff --git a/demo/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from demo/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to app/src/main/res/mipmap-xhdpi/ic_launcher.png
diff --git a/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to app/src/main/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/demo/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
similarity index 100%
rename from demo/src/main/res/values-w820dp/dimens.xml
rename to app/src/main/res/values-w820dp/dimens.xml
diff --git a/demo/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
similarity index 100%
rename from demo/src/main/res/values/dimens.xml
rename to app/src/main/res/values/dimens.xml
diff --git a/demo/src/main/res/values-en/strings.xml b/app/src/main/res/values/strings.xml
similarity index 70%
rename from demo/src/main/res/values-en/strings.xml
rename to app/src/main/res/values/strings.xml
index 5f2428d..e012f49 100644
--- a/demo/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,9 +1,11 @@
- TagGroup-Demo
+ AndroidTagGroup Demo
Add Tags
Edit Tags
Tags (Default)
Tags (Large)
Tags (Small)
+ Edit
+ Submit
\ No newline at end of file
diff --git a/demo/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
similarity index 100%
rename from demo/src/main/res/values/styles.xml
rename to app/src/main/res/values/styles.xml
diff --git a/build.gradle b/build.gradle
index cd74ded..e9e7e83 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.2.3'
+ classpath 'com.android.tools.build:gradle:1.5.0'
}
}
diff --git a/demo/src/main/res/layout/activity_tag_editor.xml b/demo/src/main/res/layout/activity_tag_editor.xml
deleted file mode 100644
index 6749944..0000000
--- a/demo/src/main/res/layout/activity_tag_editor.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml
deleted file mode 100644
index 88f07de..0000000
--- a/demo/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
- TagGroup-Demo
- 编辑标签
- 添加标签
- 标签(默认)
- 标签(小号)
- 标签(大号)
- Submit
- Edit
-
diff --git a/gradle.properties b/gradle.properties
index e61bff9..c0552be 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,20 +17,6 @@
# 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
-
-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_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
-
-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
+VERSION_NAME=1.7.3
+VERSION_CODE=18
+GROUP=me.gujun.android.taggroup
\ No newline at end of file
diff --git a/library/build.gradle b/library/build.gradle
index 87bfd43..158a74c 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -1,18 +1,28 @@
apply plugin: 'com.android.library'
+
android {
- compileSdkVersion 21
- buildToolsVersion '21.1.1'
+ compileSdkVersion 23
+ buildToolsVersion "23.0.2"
+
defaultConfig {
minSdkVersion 8
- targetSdkVersion 21
+ targetSdkVersion 23
+ versionCode 1
+ versionName "1.0"
}
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ // Travis CI needing
lintOptions {
abortOnError false
}
- productFlavors {
- }
}
-// Used to push in maven
-apply from: '../maven-push.gradle'
+
dependencies {
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+ compile 'com.android.support:support-annotations:23.2.1'
}
\ No newline at end of file
diff --git a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java b/library/src/main/java/me/gujun/android/taggroup/AndroidTagGroup.java
similarity index 62%
rename from library/src/main/java/me/gujun/android/taggroup/TagGroup.java
rename to library/src/main/java/me/gujun/android/taggroup/AndroidTagGroup.java
index 5f2ae99..1307f98 100644
--- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java
+++ b/library/src/main/java/me/gujun/android/taggroup/AndroidTagGroup.java
@@ -12,7 +12,9 @@
import android.graphics.RectF;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.ColorInt;
import android.text.Editable;
+import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.ArrowKeyMovementMethod;
@@ -49,146 +51,231 @@
* @version 2.0
* @since 2015-2-3 14:16:32
*/
-public class TagGroup extends ViewGroup {
- private final int default_border_color = Color.rgb(0x49, 0xC1, 0x20);
- private final int default_text_color = Color.rgb(0x49, 0xC1, 0x20);
- private final int default_background_color = Color.WHITE;
- private final int default_dash_border_color = Color.rgb(0xAA, 0xAA, 0xAA);
- private final int default_input_hint_color = Color.argb(0x80, 0x00, 0x00, 0x00);
- private final int default_input_text_color = Color.argb(0xDE, 0x00, 0x00, 0x00);
- private final int default_checked_border_color = Color.rgb(0x49, 0xC1, 0x20);
- private final int default_checked_text_color = Color.WHITE;
- private final int default_checked_marker_color = Color.WHITE;
- private final int default_checked_background_color = Color.rgb(0x49, 0xC1, 0x20);
- private final int default_pressed_background_color = Color.rgb(0xED, 0xED, 0xED);
- private final float default_border_stroke_width;
- private final float default_text_size;
- private final float default_horizontal_spacing;
- private final float default_vertical_spacing;
- 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. */
- private boolean isAppendMode;
+public class AndroidTagGroup extends ViewGroup {
+ private final int DEFAULT_BORDER_COLOR = Color.rgb(0x49, 0xC1, 0x20);
+ private final int DEFAULT_TEXT_COLOR = Color.rgb(0x49, 0xC1, 0x20);
+ private final int DEFAULT_BACKGROUND_COLOR = Color.WHITE;
+ private final int DEFAULT_DASH_BORDER_COLOR = Color.rgb(0xAA, 0xAA, 0xAA);
+ private final int DEFAULT_INPUT_HINT_COLOR = Color.argb(0x80, 0x00, 0x00, 0x00);
+ private final int DEFAULT_INPUT_TEXT_COLOR = Color.argb(0xDE, 0x00, 0x00, 0x00);
+ private final int DEFAULT_CHECKED_BORDER_COLOR = Color.rgb(0x49, 0xC1, 0x20);
+ private final int DEFAULT_CHECKED_TEXT_COLOR = Color.WHITE;
+ private final int DEFAULT_CHECKED_MARKER_COLOR = Color.WHITE;
+ private final int DEFAULT_CHECKED_BACKGROUND_COLOR = Color.rgb(0x49, 0xC1, 0x20);
+ private final int DEFAULT_PRESSED_BACKGROUND_COLOR = Color.rgb(0xED, 0xED, 0xED);
+ private final float mDefaultBorderStrokeWidth;
+ private final float mDefaultTextSize;
+ private final float mDefaultHorizontalSpacing;
+ private final float mDefaultVerticalSpacing;
+ private final float mDefaultHorizontalPadding;
+ private final float mDefaultVerticalPadding;
+ // Characters limitation (Default: no limitation)
+ private int mCharsLimitation = -1;
+ // Indicates whether this TagGroup is set up to APPEND mode or DISPLAY mode. Default is false.
+ private boolean mIsAppendMode;
+ // The text to be displayed when the text of the INPUT tag is empty.
+ private CharSequence mInputHint;
+ @ColorInt
+ // The tag outline border color.
+ private int mBorderColor;
+ @ColorInt
+ // The tag text color.
+ private int mTextColor;
+ @ColorInt
+ // The tag background color.
+ private int mBackgroundColor;
+ @ColorInt
+ // The dash outline border color.
+ private int mDashBorderColor;
+ @ColorInt
+ // The input tag hint text color.
+ private int mInputHintColor;
+ @ColorInt
+ // The input tag type text color.
+ private int mInputTextColor;
+ @ColorInt
+ // The checked tag outline border color.
+ private int mCheckedBorderColor;
+ @ColorInt
+ // The check text color
+ private int mCheckedTextColor;
+ @ColorInt
+ // The checked marker color.
+ private int mCheckedMarkerColor;
+ @ColorInt
+ // The checked tag background color.
+ private int mCheckedBackgroundColor;
+ @ColorInt
+ // The tag background color, when the tag is being pressed.
+ private int mPressedBackgroundColor;
+ // The tag outline border stroke width, default is 0.5dp.
+ private float mBorderStrokeWidth;
+ // The tag text size, default is 13sp.
+ private float mTextSize;
+ // The horizontal tag spacing, default is 8.0dp.
+ private int mHorizontalSpacing;
+ // The vertical tag spacing, default is 4.0dp.
+ private int mVerticalSpacing;
+ // The horizontal tag padding, default is 12.0dp.
+ private int mHorizontalPadding;
+ // The vertical tag padding, default is 3.0dp.
+ private int mVerticalPadding;
+ // Listener used to dispatch tag change event.
+ private OnTagChangeListener mOnTagChangeListener;
+ private OnTagLimitationExceedListener mOnTagLimitationExceedListener;
+ // Listener used to dispatch tag click event.
+ private OnTagClickListener mOnTagClickListener;
+ // Adding tags limitation.
+ private int mTagsLimitation = -1;
+ // Listener used to handle tag click event.
+ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener();
- /** The text to be displayed when the text of the INPUT tag is empty. */
- private CharSequence inputHint;
+ public AndroidTagGroup(Context context) {
+ this(context, null);
+ }
- /** The tag outline border color. */
- private int borderColor;
+ public AndroidTagGroup(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.tagGroupStyle);
+ }
- /** The tag text color. */
- private int textColor;
+ public AndroidTagGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mDefaultBorderStrokeWidth = AndroidUtils.dp2px(getContext(), 0.5f);
+ mDefaultTextSize = AndroidUtils.sp2px(getContext(), 13.0f);
+ mDefaultHorizontalSpacing = AndroidUtils.dp2px(getContext(), 8.0f);
+ mDefaultVerticalSpacing = AndroidUtils.dp2px(getContext(), 4.0f);
+ mDefaultHorizontalPadding = AndroidUtils.dp2px(getContext(), 12.0f);
+ mDefaultVerticalPadding = AndroidUtils.dp2px(getContext(), 3.0f);
- /** The tag background color. */
- private int backgroundColor;
+ // Load styled attributes.
+ final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AndroidTagGroup, defStyleAttr, R.style.AndroidTagGroup);
+ try {
+ mIsAppendMode = typedArray.getBoolean(R.styleable.AndroidTagGroup_atg_isAppendMode, false);
+ mInputHint = typedArray.getText(R.styleable.AndroidTagGroup_atg_inputHint);
+ mBorderColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_borderColor, DEFAULT_BORDER_COLOR);
+ mTextColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_textColor, DEFAULT_TEXT_COLOR);
+ mBackgroundColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_backgroundColor, DEFAULT_BACKGROUND_COLOR);
+ mDashBorderColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_dashBorderColor, DEFAULT_DASH_BORDER_COLOR);
+ mInputHintColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_inputHintColor, DEFAULT_INPUT_HINT_COLOR);
+ mInputTextColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_inputTextColor, DEFAULT_INPUT_TEXT_COLOR);
+ mCheckedBorderColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_checkedBorderColor, DEFAULT_CHECKED_BORDER_COLOR);
+ mCheckedTextColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_checkedTextColor, DEFAULT_CHECKED_TEXT_COLOR);
+ mCheckedMarkerColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_checkedMarkerColor, DEFAULT_CHECKED_MARKER_COLOR);
+ mCheckedBackgroundColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_checkedBackgroundColor, DEFAULT_CHECKED_BACKGROUND_COLOR);
+ mPressedBackgroundColor = typedArray.getColor(R.styleable.AndroidTagGroup_atg_pressedBackgroundColor, DEFAULT_PRESSED_BACKGROUND_COLOR);
+ mBorderStrokeWidth = typedArray.getDimension(R.styleable.AndroidTagGroup_atg_borderStrokeWidth, mDefaultBorderStrokeWidth);
+ mTextSize = typedArray.getDimension(R.styleable.AndroidTagGroup_atg_textSize, mDefaultTextSize);
+ mHorizontalSpacing = (int) typedArray.getDimension(R.styleable.AndroidTagGroup_atg_horizontalSpacing, mDefaultHorizontalSpacing);
+ mVerticalSpacing = (int) typedArray.getDimension(R.styleable.AndroidTagGroup_atg_verticalSpacing, mDefaultVerticalSpacing);
+ mHorizontalPadding = (int) typedArray.getDimension(R.styleable.AndroidTagGroup_atg_horizontalPadding, mDefaultHorizontalPadding);
+ mVerticalPadding = (int) typedArray.getDimension(R.styleable.AndroidTagGroup_atg_verticalPadding, mDefaultVerticalPadding);
+ mTagsLimitation = typedArray.getInteger(R.styleable.AndroidTagGroup_atg_tagsLimitation, -1);
+ mCharsLimitation = typedArray.getInteger(R.styleable.AndroidTagGroup_atg_charsLimitation, -1);
+ } finally {
+ typedArray.recycle();
+ }
- /** The dash outline border color. */
- private int dashBorderColor;
+ if (mIsAppendMode) {
+ // Append the initial INPUT tag.
+ appendInputTag();
- /** The input tag hint text color. */
- private int inputHintColor;
+ // Set the click listener to detect the end-input event.
+ setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ submitTag();
+ }
+ });
+ }
+ }
- /** The input tag type text color. */
- private int inputTextColor;
+ public void setAppendMode(boolean appendMode) {
+ mIsAppendMode = appendMode;
+ }
- /** The checked tag outline border color. */
- private int checkedBorderColor;
+ public void setInputHint(CharSequence inputHint) {
+ mInputHint = inputHint;
+ }
- /** The check text color */
- private int checkedTextColor;
+ public void setBorderColor(@ColorInt int borderColor) {
+ mBorderColor = borderColor;
+ }
- /** The checked marker color. */
- private int checkedMarkerColor;
+ public void setTextColor(@ColorInt int textColor) {
+ mTextColor = textColor;
+ }
- /** The checked tag background color. */
- private int checkedBackgroundColor;
+ public void setViewBackgroundColor(@ColorInt int backgroundColor) {
+ mBackgroundColor = backgroundColor;
+ }
- /** The tag background color, when the tag is being pressed. */
- private int pressedBackgroundColor;
+ public void setDashBorderColor(@ColorInt int dashBorderColor) {
+ mDashBorderColor = dashBorderColor;
+ }
- /** The tag outline border stroke width, default is 0.5dp. */
- private float borderStrokeWidth;
+ public void setInputHintColor(@ColorInt int inputHintColor) {
+ mInputHintColor = inputHintColor;
+ }
- /** The tag text size, default is 13sp. */
- private float textSize;
+ public void setInputTextColor(@ColorInt int inputTextColor) {
+ mInputTextColor = inputTextColor;
+ }
- /** The horizontal tag spacing, default is 8.0dp. */
- private int horizontalSpacing;
+ public void setCheckedBorderColor(@ColorInt int checkedBorderColor) {
+ mCheckedBorderColor = checkedBorderColor;
+ }
- /** The vertical tag spacing, default is 4.0dp. */
- private int verticalSpacing;
+ public void setCheckedTextColor(@ColorInt int checkedTextColor) {
+ mCheckedTextColor = checkedTextColor;
+ }
- /** The horizontal tag padding, default is 12.0dp. */
- private int horizontalPadding;
+ public void setCheckedMarkerColor(@ColorInt int checkedMarkerColor) {
+ mCheckedMarkerColor = checkedMarkerColor;
+ }
- /** The vertical tag padding, default is 3.0dp. */
- private int verticalPadding;
+ public void setCheckedBackgroundColor(@ColorInt int checkedBackgroundColor) {
+ mCheckedBackgroundColor = checkedBackgroundColor;
+ }
- /** Listener used to dispatch tag change event. */
- private OnTagChangeListener mOnTagChangeListener;
+ public void setPressedBackgroundColor(@ColorInt int pressedBackgroundColor) {
+ mPressedBackgroundColor = pressedBackgroundColor;
+ }
- /** Listener used to dispatch tag click event. */
- private OnTagClickListener mOnTagClickListener;
+ public void setBorderStrokeWidth(float borderStrokeWidth) {
+ mBorderStrokeWidth = borderStrokeWidth;
+ }
- /** Listener used to handle tag click event. */
- private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener();
+ public void setTextSize(float textSize) {
+ mTextSize = textSize;
+ }
- public TagGroup(Context context) {
- this(context, null);
+ public void setHorizontalSpacing(int horizontalSpacing) {
+ mHorizontalSpacing = horizontalSpacing;
}
- public TagGroup(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.tagGroupStyle);
+ public void setVerticalSpacing(int verticalSpacing) {
+ mVerticalSpacing = verticalSpacing;
}
- public TagGroup(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- default_border_stroke_width = dp2px(0.5f);
- default_text_size = sp2px(13.0f);
- default_horizontal_spacing = dp2px(8.0f);
- default_vertical_spacing = dp2px(4.0f);
- default_horizontal_padding = dp2px(12.0f);
- default_vertical_padding = dp2px(3.0f);
+ public void setHorizontalPadding(int horizontalPadding) {
+ mHorizontalPadding = horizontalPadding;
+ }
- // Load styled attributes.
- final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TagGroup, defStyleAttr, R.style.TagGroup);
- try {
- isAppendMode = a.getBoolean(R.styleable.TagGroup_atg_isAppendMode, false);
- inputHint = a.getText(R.styleable.TagGroup_atg_inputHint);
- borderColor = a.getColor(R.styleable.TagGroup_atg_borderColor, default_border_color);
- textColor = a.getColor(R.styleable.TagGroup_atg_textColor, default_text_color);
- backgroundColor = a.getColor(R.styleable.TagGroup_atg_backgroundColor, default_background_color);
- dashBorderColor = a.getColor(R.styleable.TagGroup_atg_dashBorderColor, default_dash_border_color);
- inputHintColor = a.getColor(R.styleable.TagGroup_atg_inputHintColor, default_input_hint_color);
- inputTextColor = a.getColor(R.styleable.TagGroup_atg_inputTextColor, default_input_text_color);
- checkedBorderColor = a.getColor(R.styleable.TagGroup_atg_checkedBorderColor, default_checked_border_color);
- checkedTextColor = a.getColor(R.styleable.TagGroup_atg_checkedTextColor, default_checked_text_color);
- checkedMarkerColor = a.getColor(R.styleable.TagGroup_atg_checkedMarkerColor, default_checked_marker_color);
- checkedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_checkedBackgroundColor, default_checked_background_color);
- pressedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_pressedBackgroundColor, default_pressed_background_color);
- borderStrokeWidth = a.getDimension(R.styleable.TagGroup_atg_borderStrokeWidth, default_border_stroke_width);
- textSize = a.getDimension(R.styleable.TagGroup_atg_textSize, default_text_size);
- horizontalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalSpacing, default_horizontal_spacing);
- verticalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_verticalSpacing, default_vertical_spacing);
- horizontalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalPadding, default_horizontal_padding);
- verticalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_verticalPadding, default_vertical_padding);
- } finally {
- a.recycle();
- }
+ public void setVerticalPadding(int verticalPadding) {
+ mVerticalPadding = verticalPadding;
+ }
- if (isAppendMode) {
- // Append the initial INPUT tag.
- appendInputTag();
+ /**
+ * Register a callback to be invoked when limitation exceed.
+ *
+ * @param onTagLimitationExceedListener
+ */
+ public void setOnTagLimitationExceedListener(OnTagLimitationExceedListener onTagLimitationExceedListener) {
+ mOnTagLimitationExceedListener = onTagLimitationExceedListener;
+ }
- // Set the click listener to detect the end-input event.
- setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- submitTag();
- }
- });
- }
+ public void setCharsLimitation(int limitation) {
+ mCharsLimitation = limitation;
}
/**
@@ -200,12 +287,165 @@ public void submitTag() {
inputTag.endInput();
if (mOnTagChangeListener != null) {
- mOnTagChangeListener.onAppend(TagGroup.this, inputTag.getText().toString());
+ mOnTagChangeListener.onAppend(AndroidTagGroup.this, inputTag.getText().toString());
}
appendInputTag();
}
}
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int parentLeft = getPaddingLeft();
+ final int parentRight = r - l - getPaddingRight();
+ final int parentTop = getPaddingTop();
+
+ int childLeft = parentLeft;
+ int childTop = parentTop;
+
+ int rowMaxHeight = 0;
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final int width = child.getMeasuredWidth();
+ final int height = child.getMeasuredHeight();
+
+ if (child.getVisibility() != GONE) {
+ if (childLeft + width > parentRight) { // Next line
+ childLeft = parentLeft;
+ childTop += rowMaxHeight + mVerticalSpacing;
+ rowMaxHeight = height;
+ } else {
+ rowMaxHeight = Math.max(rowMaxHeight, height);
+ }
+ child.layout(childLeft, childTop, childLeft + width, childTop + height);
+
+ childLeft += width + mHorizontalSpacing;
+ }
+ }
+ }
+
+ @Override
+ public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ /**
+ * Return the last NORMAL state tag view in this group.
+ *
+ * @return the last NORMAL state tag view or null if not exists
+ */
+ protected TagView getLastNormalTagView() {
+ final int lastNormalTagIndex = mIsAppendMode ? getChildCount() - 2 : getChildCount() - 1;
+ return getTagAt(lastNormalTagIndex);
+ }
+
+ /**
+ * Returns the tag view at the specified position in the group.
+ *
+ * @param index the position at which to get the tag view from.
+ * @return the tag view at the specified position or null if the position
+ * does not exists within this group.
+ */
+ protected TagView getTagAt(int index) {
+ return (TagView) getChildAt(index);
+ }
+
+ /**
+ * Returns the checked tag view in the group.
+ *
+ * @return the checked tag view or null if not exists.
+ */
+ protected TagView getCheckedTag() {
+ final int checkedTagIndex = getCheckedTagIndex();
+ if (checkedTagIndex != -1) {
+ return getTagAt(checkedTagIndex);
+ }
+ return null;
+ }
+
+ /**
+ * Return the checked tag index.
+ *
+ * @return the checked tag index, or -1 if not exists.
+ */
+ protected int getCheckedTagIndex() {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final TagView tag = getTagAt(i);
+ if (tag.isChecked) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Register a callback to be invoked when this tag group is changed.
+ *
+ * @param l the callback that will run
+ */
+ public void setOnTagChangeListener(OnTagChangeListener l) {
+ mOnTagChangeListener = l;
+ }
+
+ public void setTagsLimitation(int tagsLimitation) {
+ this.mTagsLimitation = tagsLimitation;
+ }
+
+ /**
+ * Register a callback to be invoked when a tag is clicked.
+ *
+ * @param l the callback that will run.
+ */
+ public void setOnTagClickListener(OnTagClickListener l) {
+ mOnTagClickListener = l;
+ }
+
+ protected void deleteTag(TagView tagView) {
+ removeView(tagView);
+ if (mOnTagChangeListener != null) {
+ mOnTagChangeListener.onDelete(AndroidTagGroup.this, tagView.getText().toString());
+ }
+ if (getInputTag().mState == TagView.STATE_INPUT) {
+ if (!getInputTag().isEnabled()) {
+ getInputTag().setEnabled(true);
+ }
+ }
+ }
+
+ /**
+ * Returns the INPUT tag view in this group.
+ *
+ * @return the INPUT state tag view or null if not exists
+ */
+ protected TagView getInputTag() {
+ if (mIsAppendMode) {
+ final int inputTagIndex = getChildCount() - 1;
+ final TagView inputTag = getTagAt(inputTagIndex);
+ if (inputTag != null && inputTag.mState == TagView.STATE_INPUT) {
+ return inputTag;
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the INPUT state tag in this group.
+ *
+ * @return the INPUT state tag view or null if not exists
+ */
+ public String getInputTagText() {
+ final TagView inputTagView = getInputTag();
+ if (inputTagView != null) {
+ return inputTagView.getText().toString();
+ }
+ return null;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@@ -215,7 +455,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
- int width = 0;
+ int width;
int height = 0;
int row = 0; // The row counter.
@@ -232,13 +472,13 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
rowWidth += childWidth;
if (rowWidth > widthSize) { // Next line.
rowWidth = childWidth; // The next row width.
- height += rowMaxHeight + verticalSpacing;
+ height += rowMaxHeight + mVerticalSpacing;
rowMaxHeight = childHeight; // The next row max height.
row++;
} else { // This line.
rowMaxHeight = Math.max(rowMaxHeight, childHeight);
}
- rowWidth += horizontalSpacing;
+ rowWidth += mHorizontalSpacing;
}
}
// Account for the last row height.
@@ -259,39 +499,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMode == MeasureSpec.EXACTLY ? heightSize : height);
}
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- final int parentLeft = getPaddingLeft();
- final int parentRight = r - l - getPaddingRight();
- final int parentTop = getPaddingTop();
- final int parentBottom = b - t - getPaddingBottom();
-
- int childLeft = parentLeft;
- int childTop = parentTop;
-
- int rowMaxHeight = 0;
-
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- final int width = child.getMeasuredWidth();
- final int height = child.getMeasuredHeight();
-
- if (child.getVisibility() != GONE) {
- if (childLeft + width > parentRight) { // Next line
- childLeft = parentLeft;
- childTop += rowMaxHeight + verticalSpacing;
- rowMaxHeight = height;
- } else {
- rowMaxHeight = Math.max(rowMaxHeight, height);
- }
- child.layout(childLeft, childTop, childLeft + width, childTop + height);
-
- childLeft += width + horizontalSpacing;
- }
- }
- }
-
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
@@ -324,49 +531,6 @@ public void onRestoreInstanceState(Parcelable state) {
}
}
- /**
- * Returns the INPUT tag view in this group.
- *
- * @return the INPUT state tag view or null if not exists
- */
- protected TagView getInputTag() {
- if (isAppendMode) {
- final int inputTagIndex = getChildCount() - 1;
- final TagView inputTag = getTagAt(inputTagIndex);
- if (inputTag != null && inputTag.mState == TagView.STATE_INPUT) {
- return inputTag;
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- /**
- * Returns the INPUT state tag in this group.
- *
- * @return the INPUT state tag view or null if not exists
- */
- public String getInputTagText() {
- final TagView inputTagView = getInputTag();
- if (inputTagView != null) {
- return inputTagView.getText().toString();
- }
- return null;
- }
-
- /**
- * Return the last NORMAL state tag view in this group.
- *
- * @return the last NORMAL state tag view or null if not exists
- */
- protected TagView getLastNormalTagView() {
- final int lastNormalTagIndex = isAppendMode ? getChildCount() - 2 : getChildCount() - 1;
- TagView lastNormalTagView = getTagAt(lastNormalTagIndex);
- return lastNormalTagView;
- }
-
/**
* Returns the tag array in group, except the INPUT tag.
*
@@ -398,65 +562,19 @@ public void setTags(List tagList) {
* @param tags the tag list to set.
*/
public void setTags(String... tags) {
+ if (mTagsLimitation != -1 && tags.length > mTagsLimitation) {
+ throw new IllegalStateException(String.format("There is a limitation (%1$d) in adding tags.", mTagsLimitation));
+ }
removeAllViews();
for (final String tag : tags) {
appendTag(tag);
}
- if (isAppendMode) {
+ if (mIsAppendMode) {
appendInputTag();
}
}
- /**
- * Returns the tag view at the specified position in the group.
- *
- * @param index the position at which to get the tag view from.
- * @return the tag view at the specified position or null if the position
- * does not exists within this group.
- */
- protected TagView getTagAt(int index) {
- return (TagView) getChildAt(index);
- }
-
- /**
- * Returns the checked tag view in the group.
- *
- * @return the checked tag view or null if not exists.
- */
- protected TagView getCheckedTag() {
- final int checkedTagIndex = getCheckedTagIndex();
- if (checkedTagIndex != -1) {
- return getTagAt(checkedTagIndex);
- }
- return null;
- }
-
- /**
- * Return the checked tag index.
- *
- * @return the checked tag index, or -1 if not exists.
- */
- protected int getCheckedTagIndex() {
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final TagView tag = getTagAt(i);
- if (tag.isChecked) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Register a callback to be invoked when this tag group is changed.
- *
- * @param l the callback that will run
- */
- public void setOnTagChangeListener(OnTagChangeListener l) {
- mOnTagChangeListener = l;
- }
-
/**
* @see #appendInputTag(String)
*/
@@ -472,10 +590,40 @@ protected void appendInputTag() {
protected void appendInputTag(String tag) {
final TagView previousInputTag = getInputTag();
if (previousInputTag != null) {
- throw new IllegalStateException("Already has a INPUT tag in group.");
+ throw new IllegalStateException("Already has an INPUT tag in group.");
}
final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag);
+
+ if (mCharsLimitation != -1) {
+ newInputTag.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (getInputTagText().length() - 1 == mCharsLimitation) {
+ newInputTag.setText(getInputTagText().substring(0, mCharsLimitation));
+ newInputTag.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
+ }
+ }
+ });
+ }
+
+ // If limitation exceed, disable the input and invoke a callback.
+ if (mTagsLimitation != -1 && getTags().length >= mTagsLimitation) {
+ if (mOnTagLimitationExceedListener != null) {
+ mOnTagLimitationExceedListener.onLimitationExceed();
+ }
+ newInputTag.setEnabled(false);
+ }
newInputTag.setOnClickListener(mInternalTagClickListener);
addView(newInputTag);
}
@@ -491,36 +639,17 @@ protected void appendTag(CharSequence tag) {
addView(newTag);
}
- public float dp2px(float dp) {
- return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
- getResources().getDisplayMetrics());
- }
-
- public float sp2px(float sp) {
- return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
- getResources().getDisplayMetrics());
- }
-
- @Override
- public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
- return new TagGroup.LayoutParams(getContext(), attrs);
- }
/**
- * Register a callback to be invoked when a tag is clicked.
- *
- * @param l the callback that will run.
+ * Interface definition for a callback to be invoked when adding tags limitation exceed.
*/
- public void setOnTagClickListener(OnTagClickListener l) {
- mOnTagClickListener = l;
+ public interface OnTagLimitationExceedListener {
+ /**
+ * Called when limitation exceed.
+ */
+ void onLimitationExceed();
}
- protected void deleteTag(TagView tagView) {
- removeView(tagView);
- if (mOnTagChangeListener != null) {
- mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString());
- }
- }
/**
* Interface definition for a callback to be invoked when a tag group is changed.
@@ -531,16 +660,17 @@ public interface OnTagChangeListener {
*
* @param tag the appended tag.
*/
- void onAppend(TagGroup tagGroup, String tag);
+ void onAppend(AndroidTagGroup androidTagGroup, String tag);
/**
* Called when a tag has been deleted from the the group.
*
* @param tag the deleted tag.
*/
- void onDelete(TagGroup tagGroup, String tag);
+ void onDelete(AndroidTagGroup androidTagGroup, String tag);
}
+
/**
* Interface definition for a callback to be invoked when a tag is clicked.
*/
@@ -554,20 +684,7 @@ public interface OnTagClickListener {
}
/**
- * Per-child layout information for layouts.
- */
- public static class LayoutParams extends ViewGroup.LayoutParams {
- public LayoutParams(Context c, AttributeSet attrs) {
- super(c, attrs);
- }
-
- public LayoutParams(int width, int height) {
- super(width, height);
- }
- }
-
- /**
- * For {@link TagGroup} save and restore state.
+ * For {@link AndroidTagGroup} save and restore state.
*/
static class SavedState extends BaseSavedState {
public static final Parcelable.Creator CREATOR =
@@ -616,7 +733,7 @@ class InternalTagClickListener implements OnClickListener {
@Override
public void onClick(View v) {
final TagView tag = (TagView) v;
- if (isAppendMode) {
+ if (mIsAppendMode) {
if (tag.mState == TagView.STATE_INPUT) {
// If the clicked tag is in INPUT state, uncheck the previous checked tag if exists.
final TagView checkedTag = getCheckedTag();
@@ -652,19 +769,29 @@ class TagView extends TextView {
public static final int STATE_NORMAL = 1;
public static final int STATE_INPUT = 2;
- /** The offset to the text. */
+ /**
+ * 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 pressed.
+ */
private boolean isPressed = false;
private Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -673,57 +800,73 @@ 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);
{
mBorderPaint.setStyle(Paint.Style.STROKE);
- mBorderPaint.setStrokeWidth(borderStrokeWidth);
+ mBorderPaint.setStrokeWidth(mBorderStrokeWidth);
mBackgroundPaint.setStyle(Paint.Style.FILL);
mCheckedMarkerPaint.setStyle(Paint.Style.FILL);
mCheckedMarkerPaint.setStrokeWidth(CHECKED_MARKER_STROKE_WIDTH);
- mCheckedMarkerPaint.setColor(checkedMarkerColor);
+ mCheckedMarkerPaint.setColor(mCheckedMarkerColor);
}
public TagView(Context context, final int state, CharSequence text) {
super(context);
- setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
- setLayoutParams(new TagGroup.LayoutParams(
- TagGroup.LayoutParams.WRAP_CONTENT,
- TagGroup.LayoutParams.WRAP_CONTENT));
+ setPadding(mHorizontalPadding, mVerticalPadding, mHorizontalPadding, mVerticalPadding);
+ setLayoutParams(new LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
setGravity(Gravity.CENTER);
setText(text);
- setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
mState = state;
- setClickable(isAppendMode);
+ setClickable(mIsAppendMode);
setFocusable(state == STATE_INPUT);
setFocusableInTouchMode(state == STATE_INPUT);
- setHint(state == STATE_INPUT ? inputHint : null);
+ setHint(state == STATE_INPUT ? mInputHint : null);
setMovementMethod(state == STATE_INPUT ? ArrowKeyMovementMethod.getInstance() : null);
// Interrupted long click event to avoid PAUSE popup.
@@ -736,6 +879,9 @@ public boolean onLongClick(View v) {
if (state == STATE_INPUT) {
requestFocus();
+ //Replace Enter (new line) button with Action Go
+ setRawInputType(InputType.TYPE_CLASS_TEXT);
+ setImeOptions(EditorInfo.IME_ACTION_GO);
// Handle the ENTER key down.
setOnEditorActionListener(new OnEditorActionListener() {
@@ -749,7 +895,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// the event, then append a new INPUT state tag.
endInput();
if (mOnTagChangeListener != null) {
- mOnTagChangeListener.onAppend(TagGroup.this, getText().toString());
+ mOnTagChangeListener.onAppend(AndroidTagGroup.this, getText().toString());
}
appendInputTag();
}
@@ -771,7 +917,7 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
if (lastNormalTagView.isChecked) {
removeView(lastNormalTagView);
if (mOnTagChangeListener != null) {
- mOnTagChangeListener.onDelete(TagGroup.this, lastNormalTagView.getText().toString());
+ mOnTagChangeListener.onDelete(AndroidTagGroup.this, lastNormalTagView.getText().toString());
}
} else {
final TagView checkedTagView = getCheckedTag();
@@ -813,19 +959,12 @@ public void afterTextChanged(Editable s) {
}
/**
- * Set whether this tag view is in the checked state.
+ * Indicates whether the input content is available.
*
- * @param checked true is checked, false otherwise
+ * @return True if the input content is available, false otherwise.
*/
- public void setChecked(boolean checked) {
- isChecked = checked;
- // Make the checked mark drawing region.
- setPadding(horizontalPadding,
- verticalPadding,
- isChecked ? (int) (horizontalPadding + getHeight() / 2.5f + CHECKED_MARKER_OFFSET)
- : horizontalPadding,
- verticalPadding);
- invalidatePaint();
+ public boolean isInputAvailable() {
+ return getText() != null && getText().length() > 0;
}
/**
@@ -845,51 +984,58 @@ public void endInput() {
requestLayout();
}
- @Override
- protected boolean getDefaultEditable() {
- return true;
- }
-
/**
- * Indicates whether the input content is available.
+ * Set whether this tag view is in the checked state.
*
- * @return True if the input content is available, false otherwise.
+ * @param checked true is checked, false otherwise
*/
- public boolean isInputAvailable() {
- return getText() != null && getText().length() > 0;
+ public void setChecked(boolean checked) {
+ isChecked = checked;
+ // Make the checked mark drawing region.
+ setPadding(mHorizontalPadding,
+ mVerticalPadding,
+ isChecked ? (int) (mHorizontalPadding + getHeight() / 2.5f + CHECKED_MARKER_OFFSET)
+ : mHorizontalPadding,
+ mVerticalPadding);
+ invalidatePaint();
}
private void invalidatePaint() {
- if (isAppendMode) {
+ if (mIsAppendMode) {
if (mState == STATE_INPUT) {
- mBorderPaint.setColor(dashBorderColor);
+ mBorderPaint.setColor(mDashBorderColor);
mBorderPaint.setPathEffect(mPathEffect);
- mBackgroundPaint.setColor(backgroundColor);
- setHintTextColor(inputHintColor);
- setTextColor(inputTextColor);
+ mBackgroundPaint.setColor(mBackgroundColor);
+ setHintTextColor(mInputHintColor);
+ setTextColor(mInputTextColor);
} else {
mBorderPaint.setPathEffect(null);
if (isChecked) {
- mBorderPaint.setColor(checkedBorderColor);
- mBackgroundPaint.setColor(checkedBackgroundColor);
- setTextColor(checkedTextColor);
+ mBorderPaint.setColor(mCheckedBorderColor);
+ mBackgroundPaint.setColor(mCheckedBackgroundColor);
+ setTextColor(mCheckedTextColor);
} else {
- mBorderPaint.setColor(borderColor);
- mBackgroundPaint.setColor(backgroundColor);
- setTextColor(textColor);
+ mBorderPaint.setColor(mBorderColor);
+ mBackgroundPaint.setColor(mBackgroundColor);
+ setTextColor(mTextColor);
}
}
} else {
- mBorderPaint.setColor(borderColor);
- mBackgroundPaint.setColor(backgroundColor);
- setTextColor(textColor);
+ mBorderPaint.setColor(mBorderColor);
+ mBackgroundPaint.setColor(mBackgroundColor);
+ setTextColor(mTextColor);
}
if (isPressed) {
- mBackgroundPaint.setColor(pressedBackgroundColor);
+ mBackgroundPaint.setColor(mPressedBackgroundColor);
}
}
+ @Override
+ protected boolean getDefaultEditable() {
+ return true;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
canvas.drawArc(mLeftCornerRectF, -180, 90, true, mBackgroundPaint);
@@ -912,13 +1058,60 @@ protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ /*
+ Following line returns null if the view is not enabled
+ We need to check if the returned value is null or not because of enabling or disabling the input view for
+ have the limitation feature.
+ */
+ InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+ if (inputConnection != null) {
+ return new ZanyInputConnection(super.onCreateInputConnection(outAttrs), true);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mState == STATE_INPUT) {
+ // The INPUT tag doesn't change background color on the touch event.
+ return super.onTouchEvent(event);
+ }
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN: {
+ getDrawingRect(mOutRect);
+ isPressed = true;
+ invalidatePaint();
+ invalidate();
+ break;
+ }
+ case MotionEvent.ACTION_MOVE: {
+ if (!mOutRect.contains((int) event.getX(), (int) event.getY())) {
+ isPressed = false;
+ invalidatePaint();
+ invalidate();
+ }
+ break;
+ }
+ case MotionEvent.ACTION_UP: {
+ isPressed = false;
+ invalidatePaint();
+ invalidate();
+ break;
+ }
+ }
+ return super.onTouchEvent(event);
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- int left = (int) borderStrokeWidth;
- int top = (int) borderStrokeWidth;
- int right = (int) (left + w - borderStrokeWidth * 2);
- int bottom = (int) (top + h - borderStrokeWidth * 2);
+ int left = (int) mBorderStrokeWidth;
+ int top = (int) mBorderStrokeWidth;
+ int right = (int) (left + w - mBorderStrokeWidth * 2);
+ int bottom = (int) (top + h - mBorderStrokeWidth * 2);
int d = bottom - top;
@@ -949,58 +1142,20 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
int m = (int) (h / 2.5f);
h = bottom - top;
- mCheckedMarkerBound.set(right - m - horizontalPadding + CHECKED_MARKER_OFFSET,
+ mCheckedMarkerBound.set(right - m - mHorizontalPadding + CHECKED_MARKER_OFFSET,
top + h / 2 - m / 2,
- right - horizontalPadding + CHECKED_MARKER_OFFSET,
+ right - mHorizontalPadding + CHECKED_MARKER_OFFSET,
bottom - h / 2 + m / 2);
// Ensure the checked mark drawing region is correct across screen orientation changes.
if (isChecked) {
- setPadding(horizontalPadding,
- verticalPadding,
- (int) (horizontalPadding + h / 2.5f + CHECKED_MARKER_OFFSET),
- verticalPadding);
+ setPadding(mHorizontalPadding,
+ mVerticalPadding,
+ (int) (mHorizontalPadding + h / 2.5f + CHECKED_MARKER_OFFSET),
+ mVerticalPadding);
}
}
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mState == STATE_INPUT) {
- // The INPUT tag doesn't change background color on the touch event.
- return super.onTouchEvent(event);
- }
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- getDrawingRect(mOutRect);
- isPressed = true;
- invalidatePaint();
- invalidate();
- break;
- }
- case MotionEvent.ACTION_MOVE: {
- if (!mOutRect.contains((int) event.getX(), (int) event.getY())) {
- isPressed = false;
- invalidatePaint();
- invalidate();
- }
- break;
- }
- case MotionEvent.ACTION_UP: {
- isPressed = false;
- invalidatePaint();
- invalidate();
- break;
- }
- }
- return super.onTouchEvent(event);
- }
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- return new ZanyInputConnection(super.onCreateInputConnection(outAttrs), true);
- }
-
/**
* Solve edit text delete(backspace) key detect, see
* Android: Backspace in WebView/BaseInputConnection
@@ -1020,6 +1175,13 @@ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
}
return super.deleteSurroundingText(beforeLength, afterLength);
}
+
+ @Override
+ public boolean sendKeyEvent(KeyEvent event) {
+ return super.sendKeyEvent(event);
+ }
}
}
+
+
}
\ No newline at end of file
diff --git a/library/src/main/java/me/gujun/android/taggroup/AndroidUtils.java b/library/src/main/java/me/gujun/android/taggroup/AndroidUtils.java
new file mode 100644
index 0000000..450d0b8
--- /dev/null
+++ b/library/src/main/java/me/gujun/android/taggroup/AndroidUtils.java
@@ -0,0 +1,19 @@
+package me.gujun.android.taggroup;
+
+import android.content.Context;
+import android.util.TypedValue;
+
+/**
+ * Created by Alireza Eskandarpour Shoferi on 12/22/2015.
+ */
+public class AndroidUtils {
+ public static float dp2px(Context context, float dp) {
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+ context.getResources().getDisplayMetrics());
+ }
+
+ public static float sp2px(Context context, float sp) {
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
+ context.getResources().getDisplayMetrics());
+ }
+}
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
index 3cf9b16..0dc6f4e 100644
--- a/library/src/main/res/values/attrs.xml
+++ b/library/src/main/res/values/attrs.xml
@@ -1,48 +1,50 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml
index 416e530..811d6e3 100644
--- a/library/src/main/res/values/styles.xml
+++ b/library/src/main/res/values/styles.xml
@@ -1,7 +1,7 @@
-
-
-
-
-