From ee041c2f9dac8c9b4632f451484b1cde000d32ef Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 23 Sep 2015 18:24:46 +0330 Subject: [PATCH 01/37] Limitation feature added --- .../me/gujun/android/taggroup/TagGroup.java | 195 ++++++++++++++---- library/src/main/res/values/attrs.xml | 1 + 2 files changed, 159 insertions(+), 37 deletions(-) diff --git a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java index 5f2ae99..efbc88d 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -68,70 +68,121 @@ 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. */ + private OnTagLimitationExceedListener mOnTagLimitationExceedListener; + + /** + * Listener used to dispatch tag click event. + */ private OnTagClickListener mOnTagClickListener; - /** Listener used to handle tag click event. */ + /** + * Adding tags limitation. + */ + private int limitation = -1; + + /** + * Listener used to handle tag click event. + */ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener(); public TagGroup(Context context) { @@ -173,6 +224,7 @@ public TagGroup(Context context, AttributeSet attrs, int defStyleAttr) { 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); + limitation = a.getInteger(R.styleable.TagGroup_atg_limitation, -1); } finally { a.recycle(); } @@ -398,6 +450,9 @@ public void setTags(List tagList) { * @param tags the tag list to set. */ public void setTags(String... tags) { + if (limitation != -1 && tags.length >= limitation) { + throw new IllegalStateException(String.format("There is a limitation (%1$d) in adding tags.", limitation)); + } removeAllViews(); for (final String tag : tags) { appendTag(tag); @@ -457,6 +512,13 @@ public void setOnTagChangeListener(OnTagChangeListener l) { mOnTagChangeListener = l; } + /** + * Register a callback to be invoked when limitation exceed. + */ + public void setOnLimitationExceedListener(OnTagLimitationExceedListener l) { + mOnTagLimitationExceedListener = l; + } + /** * @see #appendInputTag(String) */ @@ -472,14 +534,23 @@ 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 limitation exceed, disable the input and invoke a callback. + if (limitation != -1 && getTags().length >= limitation) { + mOnTagLimitationExceedListener.onLimitationExceed(); + newInputTag.setEnabled(false); + } newInputTag.setOnClickListener(mInternalTagClickListener); addView(newInputTag); } + public void setLimitation(int limitation) { + this.limitation = limitation; + } + /** * Append tag to this group. * @@ -520,6 +591,21 @@ protected void deleteTag(TagView tagView) { if (mOnTagChangeListener != null) { mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString()); } + if (getInputTag().mState == TagView.STATE_INPUT) { + if (!getInputTag().isEnabled()) { + getInputTag().setEnabled(true); + } + } + } + + /** + * Interface definition for a callback to be invoked when adding tags limitation exceed. + */ + public interface OnTagLimitationExceedListener { + /** + * Called when limitation exceed. + */ + void onLimitationExceed(); } /** @@ -652,19 +738,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,28 +769,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); { @@ -998,7 +1110,16 @@ public boolean onTouchEvent(MotionEvent event) { @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - return new ZanyInputConnection(super.onCreateInputConnection(outAttrs), true); + /* + 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; } /** diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 3cf9b16..ac69fa2 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -40,6 +40,7 @@ + From 06ce155444f23d49679e47ef917b57a3121aaa30 Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 23 Sep 2015 18:29:10 +0330 Subject: [PATCH 02/37] Add limitation attribute to the table --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2a6aa9f..4c6ae71 100644 --- a/README.md +++ b/README.md @@ -85,12 +85,12 @@ There are several attributes you can set: ![Dimension illustrate](http://ww2.sinaimg.cn/large/bce2dea9gw1epov0i8x6kj20rk054q4g.jpg) -| attr | default | mean | +| attr | default | mean | |:------------------------- |:---------------- |:------------------------------------------------------- | -| atg_isAppendMode | false | Determine the TagGroup mode, APPEND or single DISPLAY. | +| 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_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. | @@ -100,12 +100,13 @@ There are several attributes you can set: | 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_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) | +| atg_limitation | 3 | Adding tags limitation | # Developed By From bc056e17ac67ccf4d76e8e68685b36a9d3610201 Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 23 Sep 2015 18:36:35 +0330 Subject: [PATCH 03/37] minor fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c6ae71..6a632b8 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ There are several attributes you can set: | atg_verticalSpacing | 4dp | The vertical tag spacing.(Mark2) | | atg_horizontalPadding | 12dp | The horizontal tag padding.(Mark3) | | atg_verticalPadding | 3dp | The vertical tag padding.(Mark4) | -| atg_limitation | 3 | Adding tags limitation | +| atg_limitation | -1 (no limitation) | Adding tags limitation | # Developed By From e354cbd73827e93710ca11a9e1a48f79f35a7644 Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 23 Sep 2015 19:21:10 +0330 Subject: [PATCH 04/37] Update gradle and fix Google Keyboard issue (by tajchert) --- demo/build.gradle | 8 ++++---- library/build.gradle | 11 ++++++++--- library/src/main/AndroidManifest.xml | 2 +- .../me/gujun/android/taggroup/TagGroup.java | 18 +++++++++++------- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/demo/build.gradle b/demo/build.gradle index 8b3ed8d..008bd7d 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 23 + buildToolsVersion '23.0.1' defaultConfig { applicationId 'me.gujun.android.taggroup.demo' minSdkVersion 8 - targetSdkVersion 21 + targetSdkVersion 23 versionName project.VERSION_NAME versionCode Integer.parseInt(project.VERSION_CODE) } @@ -22,5 +22,5 @@ android { dependencies { compile project(':library') - compile 'com.android.support:appcompat-v7:21.0.3' + compile 'com.android.support:appcompat-v7:23.0.0' } \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 87bfd43..6cdca2f 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,16 +1,21 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 21 - buildToolsVersion '21.1.1' + compileSdkVersion 23 + buildToolsVersion '23.0.1' defaultConfig { minSdkVersion 8 - targetSdkVersion 21 + targetSdkVersion 23 } lintOptions { abortOnError false } productFlavors { } + buildTypes { + release { + minifyEnabled false + } + } } // Used to push in maven apply from: '../maven-push.gradle' diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index 5fe5d86..7433580 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/me/gujun/android/taggroup/TagGroup.java index efbc88d..a233b0c 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -13,6 +13,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.Editable; +import android.text.InputType; import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.ArrowKeyMovementMethod; @@ -437,13 +438,6 @@ public String[] getTags() { return tagList.toArray(new String[tagList.size()]); } - /** - * @see #setTags(String...) - */ - public void setTags(List tagList) { - setTags(tagList.toArray(new String[tagList.size()])); - } - /** * Set the tags. It will remove all previous tags first. * @@ -463,6 +457,13 @@ public void setTags(String... tags) { } } + /** + * @see #setTags(String...) + */ + public void setTags(List tagList) { + setTags(tagList.toArray(new String[tagList.size()])); + } + /** * Returns the tag view at the specified position in the group. * @@ -848,6 +849,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() { From f6abaaad9d2b874a126b5c783f5f908e4c1865c6 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 18 Dec 2015 18:35:59 +0330 Subject: [PATCH 05/37] change demo app name to `app` and update libs and the Gradle --- {demo => app}/.gitignore | 0 {demo => app}/build.gradle | 4 +-- {demo => app}/proguard-rules.pro | 0 .../android/taggroup/ApplicationTest.java | 0 {demo => app}/src/main/AndroidManifest.xml | 0 .../android/taggroup/demo/MainActivity.java | 0 .../taggroup/demo/TagEditorActivity.java | 0 .../taggroup/demo/db/DatabaseHelper.java | 0 .../android/taggroup/demo/db/TagsManager.java | 0 .../android/taggroup/demo/db/TagsTable.java | 0 .../src/main/res/layout/activity_main.xml | 0 .../main/res/layout/activity_tag_editor.xml | 0 .../src/main/res/menu/menu_main_activity.xml | 0 .../res/menu/menu_tag_editor_activity.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../src/main/res/values-en/strings.xml | 0 .../src/main/res/values-w820dp/dimens.xml | 0 {demo => app}/src/main/res/values/dimens.xml | 0 {demo => app}/src/main/res/values/strings.xml | 0 {demo => app}/src/main/res/values/styles.xml | 0 build.gradle | 2 +- library/build.gradle | 2 +- .../me/gujun/android/taggroup/TagGroup.java | 33 ++++++++++++++++-- settings.gradle | 2 +- 27 files changed, 36 insertions(+), 7 deletions(-) rename {demo => app}/.gitignore (100%) rename {demo => app}/build.gradle (86%) rename {demo => app}/proguard-rules.pro (100%) rename {demo => app}/src/androidTest/java/me/gujun/android/taggroup/ApplicationTest.java (100%) rename {demo => app}/src/main/AndroidManifest.xml (100%) rename {demo => app}/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java (100%) rename {demo => app}/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java (100%) rename {demo => app}/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java (100%) rename {demo => app}/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java (100%) rename {demo => app}/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java (100%) rename {demo => app}/src/main/res/layout/activity_main.xml (100%) rename {demo => app}/src/main/res/layout/activity_tag_editor.xml (100%) rename {demo => app}/src/main/res/menu/menu_main_activity.xml (100%) rename {demo => app}/src/main/res/menu/menu_tag_editor_activity.xml (100%) rename {demo => app}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {demo => app}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {demo => app}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {demo => app}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {demo => app}/src/main/res/values-en/strings.xml (100%) rename {demo => app}/src/main/res/values-w820dp/dimens.xml (100%) rename {demo => app}/src/main/res/values/dimens.xml (100%) rename {demo => app}/src/main/res/values/strings.xml (100%) rename {demo => app}/src/main/res/values/styles.xml (100%) 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 86% rename from demo/build.gradle rename to app/build.gradle index 008bd7d..b0a360e 100644 --- a/demo/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion '23.0.1' + buildToolsVersion '23.0.2' defaultConfig { applicationId 'me.gujun.android.taggroup.demo' minSdkVersion 8 @@ -22,5 +22,5 @@ android { dependencies { compile project(':library') - compile 'com.android.support:appcompat-v7:23.0.0' + compile 'com.android.support:appcompat-v7:23.1.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 100% rename from demo/src/main/AndroidManifest.xml rename to app/src/main/AndroidManifest.xml diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java similarity index 100% rename from demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java rename to app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java similarity index 100% rename from demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java rename to app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java b/app/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java similarity index 100% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java rename to app/src/main/java/me/gujun/android/taggroup/demo/db/DatabaseHelper.java diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java b/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java similarity index 100% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java rename to app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java b/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java similarity index 100% rename from demo/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java rename to app/src/main/java/me/gujun/android/taggroup/demo/db/TagsTable.java diff --git a/demo/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml similarity index 100% rename from demo/src/main/res/layout/activity_main.xml rename to app/src/main/res/layout/activity_main.xml diff --git a/demo/src/main/res/layout/activity_tag_editor.xml b/app/src/main/res/layout/activity_tag_editor.xml similarity index 100% rename from demo/src/main/res/layout/activity_tag_editor.xml rename to app/src/main/res/layout/activity_tag_editor.xml diff --git a/demo/src/main/res/menu/menu_main_activity.xml b/app/src/main/res/menu/menu_main_activity.xml similarity index 100% rename from demo/src/main/res/menu/menu_main_activity.xml rename to app/src/main/res/menu/menu_main_activity.xml 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 100% rename from demo/src/main/res/menu/menu_tag_editor_activity.xml rename to app/src/main/res/menu/menu_tag_editor_activity.xml 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-en/strings.xml b/app/src/main/res/values-en/strings.xml similarity index 100% rename from demo/src/main/res/values-en/strings.xml rename to app/src/main/res/values-en/strings.xml 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/strings.xml b/app/src/main/res/values/strings.xml similarity index 100% rename from demo/src/main/res/values/strings.xml rename to app/src/main/res/values/strings.xml 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/library/build.gradle b/library/build.gradle index 6cdca2f..7dd3040 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.library' android { compileSdkVersion 23 - buildToolsVersion '23.0.1' + buildToolsVersion '23.0.2' defaultConfig { minSdkVersion 8 targetSdkVersion 23 diff --git a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java index a233b0c..b065465 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -444,7 +444,7 @@ public String[] getTags() { * @param tags the tag list to set. */ public void setTags(String... tags) { - if (limitation != -1 && tags.length >= limitation) { + if (limitation != -1 && tags.length > limitation) { throw new IllegalStateException(String.format("There is a limitation (%1$d) in adding tags.", limitation)); } removeAllViews(); @@ -539,9 +539,33 @@ protected void appendInputTag(String tag) { } final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag); + + 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) { + CharSequence sequence = newInputTag.getText(); + + if (sequence.toString().length() >= 12) { + newInputTag.setText(sequence.toString().substring(0, 11)); + newInputTag.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); + } + } + }); // If limitation exceed, disable the input and invoke a callback. if (limitation != -1 && getTags().length >= limitation) { - mOnTagLimitationExceedListener.onLimitationExceed(); + if (mOnTagLimitationExceedListener != null) { + mOnTagLimitationExceedListener.onLimitationExceed(); + } newInputTag.setEnabled(false); } newInputTag.setOnClickListener(mInternalTagClickListener); @@ -1135,6 +1159,11 @@ public ZanyInputConnection(android.view.inputmethod.InputConnection target, bool super(target, mutable); } + @Override + public boolean sendKeyEvent(KeyEvent event) { + return super.sendKeyEvent(event); + } + @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace diff --git a/settings.gradle b/settings.gradle index 462ba77..6a834e4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':demo', ':library' +include ':library', ':app' From 12261dc2aff08d82c1122ebc0b50088aa7152f2a Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 18 Dec 2015 18:51:10 +0330 Subject: [PATCH 06/37] Reformat, XML attr `limitation` to `tagsLimitation`, new `charsLimitation` attr --- README.md | 3 +- app/src/main/AndroidManifest.xml | 16 +- .../android/taggroup/demo/MainActivity.java | 10 +- .../android/taggroup/demo/db/TagsManager.java | 12 +- app/src/main/res/layout/activity_main.xml | 40 +- app/src/main/res/menu/menu_main_activity.xml | 4 +- .../res/menu/menu_tag_editor_activity.xml | 4 +- library/src/main/AndroidManifest.xml | 2 +- .../me/gujun/android/taggroup/TagGroup.java | 721 +++++++++--------- library/src/main/res/values/attrs.xml | 43 +- 10 files changed, 434 insertions(+), 421 deletions(-) diff --git a/README.md b/README.md index 6a632b8..ff14dba 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,8 @@ There are several attributes you can set: | atg_verticalSpacing | 4dp | The vertical tag spacing.(Mark2) | | atg_horizontalPadding | 12dp | The horizontal tag padding.(Mark3) | | atg_verticalPadding | 3dp | The vertical tag padding.(Mark4) | -| atg_limitation | -1 (no limitation) | Adding tags limitation | +| atg_tagsLimitation | -1 (no limitation) | Adding tags limitation | +| atg_charsLimitation | -1 (no limitation) | Characters limitation | # Developed By diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 732aefd..51c71ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,26 +1,26 @@ - + - + android:theme="@style/AppTheme"> + - + - + + android:parentActivityName=".MainActivity"> + android:value="me.gujun.android.taggroup.demo.MainActivity"/> diff --git a/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java index 872bf9f..5fa784c 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java @@ -75,6 +75,11 @@ public void onClick(View v) { mBeautyInverseTagGroup.setOnTagClickListener(mTagClickListener); } + protected void launchTagEditorActivity() { + Intent intent = new Intent(MainActivity.this, TagEditorActivity.class); + startActivity(intent); + } + @Override protected void onResume() { super.onResume(); @@ -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/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java b/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java index 841fc28..a44723a 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/db/TagsManager.java @@ -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/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index db8f830..00718e3 100644 --- a/app/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:layout_marginTop="10dp"/> + 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/menu/menu_main_activity.xml b/app/src/main/res/menu/menu_main_activity.xml index f1764e9..1b8bd5f 100644 --- a/app/src/main/res/menu/menu_main_activity.xml +++ b/app/src/main/res/menu/menu_main_activity.xml @@ -1,8 +1,8 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + app:showAsAction="always"/> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_tag_editor_activity.xml b/app/src/main/res/menu/menu_tag_editor_activity.xml index 6d473cf..567904b 100644 --- a/app/src/main/res/menu/menu_tag_editor_activity.xml +++ b/app/src/main/res/menu/menu_tag_editor_activity.xml @@ -1,8 +1,8 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + app:showAsAction="always"/> \ No newline at end of file diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index 7433580..5fe5d86 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/me/gujun/android/taggroup/TagGroup.java index b065465..ad153a7 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -68,101 +68,102 @@ public class TagGroup extends ViewGroup { private final float default_vertical_spacing; private final float default_horizontal_padding; private final float default_vertical_padding; + private final int mCharsLimitation; /** * Indicates whether this TagGroup is set up to APPEND mode or DISPLAY mode. Default is false. */ - private boolean isAppendMode; + private boolean mIsAppendMode; /** * The text to be displayed when the text of the INPUT tag is empty. */ - private CharSequence inputHint; + private CharSequence mInputHint; /** * The tag outline border color. */ - private int borderColor; + private int mBorderColor; /** * The tag text color. */ - private int textColor; + private int mTextColor; /** * The tag background color. */ - private int backgroundColor; + private int mBackgroundColor; /** * The dash outline border color. */ - private int dashBorderColor; + private int mDashBorderColor; /** * The input tag hint text color. */ - private int inputHintColor; + private int mInputHintColor; /** * The input tag type text color. */ - private int inputTextColor; + private int mInputTextColor; /** * The checked tag outline border color. */ - private int checkedBorderColor; + private int mCheckedBorderColor; /** * The check text color */ - private int checkedTextColor; + private int mCheckedTextColor; /** * The checked marker color. */ - private int checkedMarkerColor; + private int mCheckedMarkerColor; /** * The checked tag background color. */ - private int checkedBackgroundColor; + private int mCheckedBackgroundColor; /** * The tag background color, when the tag is being pressed. */ - private int pressedBackgroundColor; + private int mPressedBackgroundColor; /** * The tag outline border stroke width, default is 0.5dp. */ - private float borderStrokeWidth; + private float mBorderStrokeWidth; /** * The tag text size, default is 13sp. */ - private float textSize; + private float mTextSize; /** * The horizontal tag spacing, default is 8.0dp. */ - private int horizontalSpacing; + private int mHorizontalSpacing; /** * The vertical tag spacing, default is 4.0dp. */ - private int verticalSpacing; + private int mVerticalSpacing; /** * The horizontal tag padding, default is 12.0dp. */ - private int horizontalPadding; + private int mHorizontalPadding; /** * The vertical tag padding, default is 3.0dp. */ - private int verticalPadding; + private int mVerticalPadding; /** * Listener used to dispatch tag change event. @@ -179,7 +180,7 @@ public class TagGroup extends ViewGroup { /** * Adding tags limitation. */ - private int limitation = -1; + private int mTagsLimitation = -1; /** * Listener used to handle tag click event. @@ -206,31 +207,32 @@ public TagGroup(Context context, AttributeSet attrs, int defStyleAttr) { // 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); - limitation = a.getInteger(R.styleable.TagGroup_atg_limitation, -1); + mIsAppendMode = a.getBoolean(R.styleable.TagGroup_atg_isAppendMode, false); + mInputHint = a.getText(R.styleable.TagGroup_atg_inputHint); + mBorderColor = a.getColor(R.styleable.TagGroup_atg_borderColor, default_border_color); + mTextColor = a.getColor(R.styleable.TagGroup_atg_textColor, default_text_color); + mBackgroundColor = a.getColor(R.styleable.TagGroup_atg_backgroundColor, default_background_color); + mDashBorderColor = a.getColor(R.styleable.TagGroup_atg_dashBorderColor, default_dash_border_color); + mInputHintColor = a.getColor(R.styleable.TagGroup_atg_inputHintColor, default_input_hint_color); + mInputTextColor = a.getColor(R.styleable.TagGroup_atg_inputTextColor, default_input_text_color); + mCheckedBorderColor = a.getColor(R.styleable.TagGroup_atg_checkedBorderColor, default_checked_border_color); + mCheckedTextColor = a.getColor(R.styleable.TagGroup_atg_checkedTextColor, default_checked_text_color); + mCheckedMarkerColor = a.getColor(R.styleable.TagGroup_atg_checkedMarkerColor, default_checked_marker_color); + mCheckedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_checkedBackgroundColor, default_checked_background_color); + mPressedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_pressedBackgroundColor, default_pressed_background_color); + mBorderStrokeWidth = a.getDimension(R.styleable.TagGroup_atg_borderStrokeWidth, default_border_stroke_width); + mTextSize = a.getDimension(R.styleable.TagGroup_atg_textSize, default_text_size); + mHorizontalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalSpacing, default_horizontal_spacing); + mVerticalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_verticalSpacing, default_vertical_spacing); + mHorizontalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalPadding, default_horizontal_padding); + mVerticalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_verticalPadding, default_vertical_padding); + mTagsLimitation = a.getInteger(R.styleable.TagGroup_atg_tagsLimitation, -1); + mCharsLimitation = a.getInteger(R.styleable.TagGroup_atg_charsLimitation, -1); } finally { a.recycle(); } - if (isAppendMode) { + if (mIsAppendMode) { // Append the initial INPUT tag. appendInputTag(); @@ -259,65 +261,11 @@ public void submitTag() { } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - final int widthSize = MeasureSpec.getSize(widthMeasureSpec); - final int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - measureChildren(widthMeasureSpec, heightMeasureSpec); - - int width = 0; - int height = 0; - - int row = 0; // The row counter. - int rowWidth = 0; // Calc the current row width. - int rowMaxHeight = 0; // Calc the max tag height, in current row. - - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - final int childWidth = child.getMeasuredWidth(); - final int childHeight = child.getMeasuredHeight(); - - if (child.getVisibility() != GONE) { - rowWidth += childWidth; - if (rowWidth > widthSize) { // Next line. - rowWidth = childWidth; // The next row width. - height += rowMaxHeight + verticalSpacing; - rowMaxHeight = childHeight; // The next row max height. - row++; - } else { // This line. - rowMaxHeight = Math.max(rowMaxHeight, childHeight); - } - rowWidth += horizontalSpacing; - } - } - // Account for the last row height. - height += rowMaxHeight; - - // Account for the padding too. - height += getPaddingTop() + getPaddingBottom(); - - // If the tags grouped in one row, set the width to wrap the tags. - if (row == 0) { - width = rowWidth; - width += getPaddingLeft() + getPaddingRight(); - } else {// If the tags grouped exceed one line, set the width to match the parent. - width = widthSize; - } - - setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width, - 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; @@ -333,48 +281,34 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { if (child.getVisibility() != GONE) { if (childLeft + width > parentRight) { // Next line childLeft = parentLeft; - childTop += rowMaxHeight + verticalSpacing; + childTop += rowMaxHeight + mVerticalSpacing; rowMaxHeight = height; } else { rowMaxHeight = Math.max(rowMaxHeight, height); } child.layout(childLeft, childTop, childLeft + width, childTop + height); - childLeft += width + horizontalSpacing; + childLeft += width + mHorizontalSpacing; } } } @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.tags = getTags(); - ss.checkedPosition = getCheckedTagIndex(); - if (getInputTag() != null) { - ss.input = getInputTag().getText().toString(); - } - return ss; + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new TagGroup.LayoutParams(getContext(), attrs); } - @Override - public void onRestoreInstanceState(Parcelable state) { - if (!(state instanceof SavedState)) { - super.onRestoreInstanceState(state); - return; - } - - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - - setTags(ss.tags); - TagView checkedTagView = getTagAt(ss.checkedPosition); - if (checkedTagView != null) { - checkedTagView.setChecked(true); - } - if (getInputTag() != null) { - getInputTag().setText(ss.input); + /** + * 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; } /** @@ -383,7 +317,7 @@ public void onRestoreInstanceState(Parcelable state) { * @return the INPUT state tag view or null if not exists */ protected TagView getInputTag() { - if (isAppendMode) { + if (mIsAppendMode) { final int inputTagIndex = getChildCount() - 1; final TagView inputTag = getTagAt(inputTagIndex); if (inputTag != null && inputTag.mState == TagView.STATE_INPUT) { @@ -397,16 +331,14 @@ protected TagView getInputTag() { } /** - * Returns the INPUT state tag in this group. + * Returns the tag view at the specified position in the group. * - * @return the INPUT state tag view or null if not exists + * @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. */ - public String getInputTagText() { - final TagView inputTagView = getInputTag(); - if (inputTagView != null) { - return inputTagView.getText().toString(); - } - return null; + protected TagView getTagAt(int index) { + return (TagView) getChildAt(index); } /** @@ -415,64 +347,59 @@ public String getInputTagText() { * @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; - } + final int lastNormalTagIndex = mIsAppendMode ? getChildCount() - 2 : getChildCount() - 1; + return getTagAt(lastNormalTagIndex); + } @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + final int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + measureChildren(widthMeasureSpec, heightMeasureSpec); + + int width; + int height = 0; + + int row = 0; // The row counter. + int rowWidth = 0; // Calc the current row width. + int rowMaxHeight = 0; // Calc the max tag height, in current row. - /** - * Returns the tag array in group, except the INPUT tag. - * - * @return the tag array. - */ - public String[] getTags() { final int count = getChildCount(); - final List tagList = new ArrayList<>(); for (int i = 0; i < count; i++) { - final TagView tagView = getTagAt(i); - if (tagView.mState == TagView.STATE_NORMAL) { - tagList.add(tagView.getText().toString()); + final View child = getChildAt(i); + final int childWidth = child.getMeasuredWidth(); + final int childHeight = child.getMeasuredHeight(); + + if (child.getVisibility() != GONE) { + rowWidth += childWidth; + if (rowWidth > widthSize) { // Next line. + rowWidth = childWidth; // The next row width. + height += rowMaxHeight + mVerticalSpacing; + rowMaxHeight = childHeight; // The next row max height. + row++; + } else { // This line. + rowMaxHeight = Math.max(rowMaxHeight, childHeight); + } + rowWidth += mHorizontalSpacing; } } + // Account for the last row height. + height += rowMaxHeight; - return tagList.toArray(new String[tagList.size()]); - } - - /** - * Set the tags. It will remove all previous tags first. - * - * @param tags the tag list to set. - */ - public void setTags(String... tags) { - if (limitation != -1 && tags.length > limitation) { - throw new IllegalStateException(String.format("There is a limitation (%1$d) in adding tags.", limitation)); - } - removeAllViews(); - for (final String tag : tags) { - appendTag(tag); - } + // Account for the padding too. + height += getPaddingTop() + getPaddingBottom(); - if (isAppendMode) { - appendInputTag(); + // If the tags grouped in one row, set the width to wrap the tags. + if (row == 0) { + width = rowWidth; + width += getPaddingLeft() + getPaddingRight(); + } else {// If the tags grouped exceed one line, set the width to match the parent. + width = widthSize; } - } - - /** - * @see #setTags(String...) - */ - public void setTags(List tagList) { - setTags(tagList.toArray(new String[tagList.size()])); - } - /** - * 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); + setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width, + heightMode == MeasureSpec.EXACTLY ? heightSize : height); } /** @@ -520,71 +447,8 @@ public void setOnLimitationExceedListener(OnTagLimitationExceedListener l) { mOnTagLimitationExceedListener = l; } - /** - * @see #appendInputTag(String) - */ - protected void appendInputTag() { - appendInputTag(null); - } - - /** - * Append a INPUT tag to this group. It will throw an exception if there has a previous INPUT tag. - * - * @param tag the tag text. - */ - protected void appendInputTag(String tag) { - final TagView previousInputTag = getInputTag(); - if (previousInputTag != null) { - throw new IllegalStateException("Already has an INPUT tag in group."); - } - - final TagView newInputTag = new TagView(getContext(), TagView.STATE_INPUT, tag); - - 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) { - CharSequence sequence = newInputTag.getText(); - - if (sequence.toString().length() >= 12) { - newInputTag.setText(sequence.toString().substring(0, 11)); - newInputTag.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); - } - } - }); - // If limitation exceed, disable the input and invoke a callback. - if (limitation != -1 && getTags().length >= limitation) { - if (mOnTagLimitationExceedListener != null) { - mOnTagLimitationExceedListener.onLimitationExceed(); - } - newInputTag.setEnabled(false); - } - newInputTag.setOnClickListener(mInternalTagClickListener); - addView(newInputTag); - } - - public void setLimitation(int limitation) { - this.limitation = limitation; - } - - /** - * Append tag to this group. - * - * @param tag the tag to append. - */ - protected void appendTag(CharSequence tag) { - final TagView newTag = new TagView(getContext(), TagView.STATE_NORMAL, tag); - newTag.setOnClickListener(mInternalTagClickListener); - addView(newTag); + public void setTagsLimitation(int tagsLimitation) { + this.mTagsLimitation = tagsLimitation; } public float dp2px(float dp) { @@ -595,11 +459,16 @@ public float dp2px(float dp) { 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); + } @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.tags = getTags(); + ss.checkedPosition = getCheckedTagIndex(); + if (getInputTag() != null) { + ss.input = getInputTag().getText().toString(); + } + return ss; } /** @@ -675,6 +544,24 @@ public LayoutParams(Context c, AttributeSet attrs) { public LayoutParams(int width, int height) { super(width, height); } + } @Override + public void onRestoreInstanceState(Parcelable state) { + if (!(state instanceof SavedState)) { + super.onRestoreInstanceState(state); + return; + } + + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + + setTags(ss.tags); + TagView checkedTagView = getTagAt(ss.checkedPosition); + if (checkedTagView != null) { + checkedTagView.setChecked(true); + } + if (getInputTag() != null) { + getInputTag().setText(ss.input); + } } /** @@ -727,7 +614,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(); @@ -836,31 +723,31 @@ class TagView extends TextView { { 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); + setPadding(mHorizontalPadding, mVerticalPadding, mHorizontalPadding, mVerticalPadding); setLayoutParams(new TagGroup.LayoutParams( TagGroup.LayoutParams.WRAP_CONTENT, TagGroup.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. @@ -953,19 +840,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; } /** @@ -985,51 +865,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); @@ -1053,54 +940,17 @@ protected void onDraw(Canvas canvas) { } @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 d = bottom - top; - - mLeftCornerRectF.set(left, top, left + d, top + d); - mRightCornerRectF.set(right - d, top, right, top + d); - - mBorderPath.reset(); - mBorderPath.addArc(mLeftCornerRectF, -180, 90); - mBorderPath.addArc(mLeftCornerRectF, -270, 90); - mBorderPath.addArc(mRightCornerRectF, -90, 90); - mBorderPath.addArc(mRightCornerRectF, 0, 90); - - int l = (int) (d / 2.0f); - mBorderPath.moveTo(left + l, top); - mBorderPath.lineTo(right - l, top); - - mBorderPath.moveTo(left + l, bottom); - mBorderPath.lineTo(right - l, bottom); - - mBorderPath.moveTo(left, top + l); - mBorderPath.lineTo(left, bottom - l); - - mBorderPath.moveTo(right, top + l); - mBorderPath.lineTo(right, bottom - l); - - mHorizontalBlankFillRectF.set(left, top + l, right, bottom - l); - mVerticalBlankFillRectF.set(left + l, top, right - l, bottom); - - int m = (int) (h / 2.5f); - h = bottom - top; - mCheckedMarkerBound.set(right - m - horizontalPadding + CHECKED_MARKER_OFFSET, - top + h / 2 - m / 2, - right - horizontalPadding + 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); + 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 @@ -1137,17 +987,54 @@ public boolean onTouchEvent(MotionEvent event) { } @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); + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + 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; + + mLeftCornerRectF.set(left, top, left + d, top + d); + mRightCornerRectF.set(right - d, top, right, top + d); + + mBorderPath.reset(); + mBorderPath.addArc(mLeftCornerRectF, -180, 90); + mBorderPath.addArc(mLeftCornerRectF, -270, 90); + mBorderPath.addArc(mRightCornerRectF, -90, 90); + mBorderPath.addArc(mRightCornerRectF, 0, 90); + + int l = (int) (d / 2.0f); + mBorderPath.moveTo(left + l, top); + mBorderPath.lineTo(right - l, top); + + mBorderPath.moveTo(left + l, bottom); + mBorderPath.lineTo(right - l, bottom); + + mBorderPath.moveTo(left, top + l); + mBorderPath.lineTo(left, bottom - l); + + mBorderPath.moveTo(right, top + l); + mBorderPath.lineTo(right, bottom - l); + + mHorizontalBlankFillRectF.set(left, top + l, right, bottom - l); + mVerticalBlankFillRectF.set(left + l, top, right - l, bottom); + + int m = (int) (h / 2.5f); + h = bottom - top; + mCheckedMarkerBound.set(right - m - mHorizontalPadding + CHECKED_MARKER_OFFSET, + top + h / 2 - m / 2, + 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(mHorizontalPadding, + mVerticalPadding, + (int) (mHorizontalPadding + h / 2.5f + CHECKED_MARKER_OFFSET), + mVerticalPadding); } - return null; } /** @@ -1159,11 +1046,6 @@ public ZanyInputConnection(android.view.inputmethod.InputConnection target, bool super(target, mutable); } - @Override - public boolean sendKeyEvent(KeyEvent event) { - return super.sendKeyEvent(event); - } - @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace @@ -1174,6 +1056,135 @@ public boolean deleteSurroundingText(int beforeLength, int afterLength) { } return super.deleteSurroundingText(beforeLength, afterLength); } + + @Override + public boolean sendKeyEvent(KeyEvent event) { + return super.sendKeyEvent(event); + } + } + } + + + + + + + + + /** + * Returns the tag array in group, except the INPUT tag. + * + * @return the tag array. + */ + public String[] getTags() { + final int count = getChildCount(); + final List tagList = new ArrayList<>(); + for (int i = 0; i < count; i++) { + final TagView tagView = getTagAt(i); + if (tagView.mState == TagView.STATE_NORMAL) { + tagList.add(tagView.getText().toString()); + } + } + + return tagList.toArray(new String[tagList.size()]); + } + + + /** + * Set the tags. It will remove all previous tags first. + * + * @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 (mIsAppendMode) { + appendInputTag(); + } + } + + + /** + * @see #setTags(String...) + */ + public void setTags(List tagList) { + setTags(tagList.toArray(new String[tagList.size()])); + } + + + /** + * @see #appendInputTag(String) + */ + protected void appendInputTag() { + appendInputTag(null); + } + + + /** + * Append a INPUT tag to this group. It will throw an exception if there has a previous INPUT tag. + * + * @param tag the tag text. + */ + protected void appendInputTag(String tag) { + final TagView previousInputTag = getInputTag(); + if (previousInputTag != null) { + 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) { + CharSequence sequence = newInputTag.getText(); + + if (sequence.toString().length() >= mCharsLimitation) { + newInputTag.setText(sequence.toString().substring(0, mCharsLimitation - 1)); + 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); + } + + + /** + * Append tag to this group. + * + * @param tag the tag to append. + */ + protected void appendTag(CharSequence tag) { + final TagView newTag = new TagView(getContext(), TagView.STATE_NORMAL, tag); + newTag.setOnClickListener(mInternalTagClickListener); + addView(newTag); } + + } \ No newline at end of file diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index ac69fa2..1d459ca 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -1,49 +1,50 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + + - + \ No newline at end of file From 575e72cf25443eef2b452905ee30d53f11b834cf Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 18 Dec 2015 19:11:23 +0330 Subject: [PATCH 07/37] remove unnecessary files from base repo, fix minor bugs, more complex example --- .gitattributes | 17 ++ .travis.yml | 37 --- CHANGELOG | 35 --- .../android/taggroup/demo/MainActivity.java | 2 +- .../taggroup/demo/TagEditorActivity.java | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/activity_tag_editor.xml | 13 +- gradle.properties | 20 +- library/build.gradle | 18 +- .../me/gujun/android/taggroup/TagGroup.java | 219 +++++++++--------- maven-push.gradle | 127 ---------- 11 files changed, 146 insertions(+), 346 deletions(-) create mode 100644 .gitattributes delete mode 100644 .travis.yml delete mode 100644 CHANGELOG delete mode 100644 maven-push.gradle 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 deleted file mode 100644 index 3c8a6ed..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: java -jdk: oraclejdk7 -branches: - only: - - master -env: - matrix: - - ANDROID_TARGET=android-21 ANDROID_ABI=armeabi-v7a - -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 - - # 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 - - # 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 - -install: - - ./gradlew assemble \ 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/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java index 5fa784c..fcaf208 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java @@ -47,7 +47,7 @@ public void onClick(View v) { } }); - mDefaultTagGroup = (TagGroup) findViewById(R.id.tag_group); + mDefaultTagGroup = (TagGroup) findViewById(R.id.tagGroup); mSmallTagGroup = (TagGroup) findViewById(R.id.tag_group_small); mLargeTagGroup = (TagGroup) findViewById(R.id.tag_group_large); mBeautyTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty); diff --git a/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java index 27d2ea1..9938fc3 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java @@ -21,7 +21,7 @@ protected void onCreate(Bundle savedInstanceState) { mTagsManager = TagsManager.getInstance(getApplicationContext()); String[] tags = mTagsManager.getTags(); - mTagGroup = (TagGroup) findViewById(R.id.tag_group); + mTagGroup = (TagGroup) findViewById(R.id.tagGroup); mTagGroup.setTags(tags); } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 00718e3..95c0807 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -25,7 +25,7 @@ android:textColor="@android:color/darker_gray"/> diff --git a/app/src/main/res/layout/activity_tag_editor.xml b/app/src/main/res/layout/activity_tag_editor.xml index 6749944..c49f02b 100644 --- a/app/src/main/res/layout/activity_tag_editor.xml +++ b/app/src/main/res/layout/activity_tag_editor.xml @@ -1,18 +1,15 @@ + android:padding="@dimen/activity_vertical_margin"> + app:atg_charsLimitation="6" + app:atg_isAppendMode="true" + app:atg_tagsLimitation="4"/> \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index e61bff9..9ae1fdd 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.6 +VERSION_CODE=16 +GROUP=me.gujun.android.taggroup \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 7dd3040..bb5c0aa 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,23 +1,23 @@ apply plugin: 'com.android.library' + android { compileSdkVersion 23 - buildToolsVersion '23.0.2' + buildToolsVersion "23.0.2" + defaultConfig { minSdkVersion 8 targetSdkVersion 23 - } - lintOptions { - abortOnError false - } - productFlavors { + versionCode 1 + versionName "1.0" } buildTypes { release { minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } -// Used to push in maven -apply from: '../maven-push.gradle' + dependencies { -} \ No newline at end of file + compile fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java index ad153a7..6f3b1ff 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -299,6 +299,25 @@ public ViewGroup.LayoutParams generateLayoutParams(AttributeSet 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 INPUT state tag in this group. * * @return the INPUT state tag view or null if not exists @@ -312,43 +331,57 @@ public String getInputTagText() { } /** - * Returns the INPUT tag view in this group. + * Returns the checked tag view in the group. * - * @return the INPUT state tag view or null if not exists + * @return the checked 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; + protected TagView getCheckedTag() { + final int checkedTagIndex = getCheckedTagIndex(); + if (checkedTagIndex != -1) { + return getTagAt(checkedTagIndex); } + return null; } /** - * Returns the tag view at the specified position in the group. + * Return the checked tag index. * - * @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. + * @return the checked tag index, or -1 if not exists. */ - protected TagView getTagAt(int index) { - return (TagView) getChildAt(index); + 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; } /** - * Return the last NORMAL state tag view in this group. + * Register a callback to be invoked when this tag group is changed. * - * @return the last NORMAL state tag view or null if not exists + * @param l the callback that will run */ - protected TagView getLastNormalTagView() { - final int lastNormalTagIndex = mIsAppendMode ? getChildCount() - 2 : getChildCount() - 1; - return getTagAt(lastNormalTagIndex); + public void setOnTagChangeListener(OnTagChangeListener l) { + mOnTagChangeListener = l; + } + + /** + * Register a callback to be invoked when limitation exceed. + */ + public void setOnLimitationExceedListener(OnTagLimitationExceedListener l) { + mOnTagLimitationExceedListener = l; + } + + public void setTagsLimitation(int tagsLimitation) { + this.mTagsLimitation = tagsLimitation; + } + + public float dp2px(float dp) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + getResources().getDisplayMetrics()); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthMode = MeasureSpec.getMode(widthMeasureSpec); @@ -402,73 +435,9 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { heightMode == MeasureSpec.EXACTLY ? heightSize : height); } - /** - * 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; - } - - /** - * Register a callback to be invoked when limitation exceed. - */ - public void setOnLimitationExceedListener(OnTagLimitationExceedListener l) { - mOnTagLimitationExceedListener = l; - } - - public void setTagsLimitation(int tagsLimitation) { - this.mTagsLimitation = tagsLimitation; - } - - 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 Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.tags = getTags(); - ss.checkedPosition = getCheckedTagIndex(); - if (getInputTag() != null) { - ss.input = getInputTag().getText().toString(); - } - return ss; } /** @@ -492,6 +461,25 @@ protected void deleteTag(TagView tagView) { } } + /** + * 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; + } + } + /** * Interface definition for a callback to be invoked when adding tags limitation exceed. */ @@ -544,24 +532,6 @@ public LayoutParams(Context c, AttributeSet attrs) { public LayoutParams(int width, int height) { super(width, height); } - } @Override - public void onRestoreInstanceState(Parcelable state) { - if (!(state instanceof SavedState)) { - super.onRestoreInstanceState(state); - return; - } - - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - - setTags(ss.tags); - TagView checkedTagView = getTagAt(ss.checkedPosition); - if (checkedTagView != null) { - checkedTagView.setChecked(true); - } - if (getInputTag() != null) { - getInputTag().setText(ss.input); - } } /** @@ -605,6 +575,16 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(checkedPosition); dest.writeString(input); } + } @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.tags = getTags(); + ss.checkedPosition = getCheckedTagIndex(); + if (getInputTag() != null) { + ss.input = getInputTag().getText().toString(); + } + return ss; } /** @@ -1071,6 +1051,27 @@ public boolean sendKeyEvent(KeyEvent event) { + @Override + public void onRestoreInstanceState(Parcelable state) { + if (!(state instanceof SavedState)) { + super.onRestoreInstanceState(state); + return; + } + + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + + setTags(ss.tags); + TagView checkedTagView = getTagAt(ss.checkedPosition); + if (checkedTagView != null) { + checkedTagView.setChecked(true); + } + if (getInputTag() != null) { + getInputTag().setText(ss.input); + } + } + + /** * Returns the tag array in group, except the INPUT tag. * @@ -1153,10 +1154,8 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { @Override public void afterTextChanged(Editable s) { - CharSequence sequence = newInputTag.getText(); - - if (sequence.toString().length() >= mCharsLimitation) { - newInputTag.setText(sequence.toString().substring(0, mCharsLimitation - 1)); + if (getInputTagText().length() - 1 == mCharsLimitation) { + newInputTag.setText(getInputTagText().substring(0, mCharsLimitation)); newInputTag.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); } } diff --git a/maven-push.gradle b/maven-push.gradle deleted file mode 100644 index 2291817..0000000 --- a/maven-push.gradle +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2013 Chris Banes - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -apply plugin: 'maven' -apply plugin: 'signing' - -def isReleaseBuild() { - return VERSION_NAME.contains("SNAPSHOT") == false -} - -def getReleaseRepositoryUrl() { - return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL - : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" -} - -def getSnapshotRepositoryUrl() { - return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL - : "https://oss.sonatype.org/content/repositories/snapshots/" -} - -def getRepositoryUsername() { - return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" -} - -def getRepositoryPassword() { - return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" -} - -afterEvaluate { project -> - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - pom.groupId = GROUP - pom.artifactId = POM_ARTIFACT_ID - pom.version = VERSION_NAME - - repository(url: getReleaseRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - snapshotRepository(url: getSnapshotRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - - pom.project { - name POM_NAME - packaging POM_PACKAGING - description POM_DESCRIPTION - url POM_URL - - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEV_CONNECTION - } - - licenses { - license { - name POM_LICENCE_NAME - url POM_LICENCE_URL - distribution POM_LICENCE_DIST - } - } - - developers { - developer { - id POM_DEVELOPER_ID - name POM_DEVELOPER_NAME - } - } - } - } - } - } - - signing { - required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } - sign configurations.archives - } - - task apklib(type: Zip){ - appendix = extension = 'apklib' - - from 'AndroidManifest.xml' - into('res') { - from 'res' - } - into('src') { - from 'src' - } - } - - task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath() .join(File.pathSeparator)) - } - - task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { - classifier = 'javadoc' - from androidJavadocs.destinationDir - } - - task androidSourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs - } - - artifacts { - archives androidSourcesJar - archives androidJavadocsJar - archives apklib - } -} \ No newline at end of file From 44f1dbf866765e14658af946bc0ebc2b98cd42d2 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 18 Dec 2015 19:36:23 +0330 Subject: [PATCH 08/37] v1.7 rename `TagGroup` class to `AndroidTagGroup` and etc... --- README.md | 103 ++++-------------- .../android/taggroup/demo/MainActivity.java | 66 +++++------ .../taggroup/demo/TagEditorActivity.java | 14 +-- app/src/main/res/layout/activity_main.xml | 14 +-- .../main/res/layout/activity_tag_editor.xml | 6 +- gradle.properties | 4 +- .../{TagGroup.java => AndroidTagGroup.java} | 74 ++++++------- library/src/main/res/values/attrs.xml | 2 +- 8 files changed, 113 insertions(+), 170 deletions(-) rename library/src/main/java/me/gujun/android/taggroup/{TagGroup.java => AndroidTagGroup.java} (92%) diff --git a/README.md b/README.md index ff14dba..a8ee1be 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,45 @@ -# `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.4). +### 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"}); +TagGroup mTagGroup = (TagGroup) 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 | +| Attribute | Default | Description | |:------------------------- |:---------------- |:------------------------------------------------------- | | 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. | @@ -109,26 +60,18 @@ There are several attributes you can set: | atg_tagsLimitation | -1 (no limitation) | Adding tags limitation | | atg_charsLimitation | -1 (no limitation) | Characters limitation | -# Developed By - -Jun Gu - <2dxgujun@gmail.com> - - - Follow me on Weibo - - - Follow me on Google Plus - - -# License +## 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/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java index fcaf208..e3e28cf 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java @@ -9,22 +9,22 @@ import android.widget.TextView; import android.widget.Toast; -import me.gujun.android.taggroup.TagGroup; +import me.gujun.android.taggroup.AndroidTagGroup; import me.gujun.android.taggroup.demo.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,32 @@ public void onClick(View v) { } }); - mDefaultTagGroup = (TagGroup) findViewById(R.id.tagGroup); - 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() { @@ -85,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 diff --git a/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java index 9938fc3..4951149 100644 --- a/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java +++ b/app/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java @@ -5,12 +5,12 @@ import android.view.Menu; import android.view.MenuItem; -import me.gujun.android.taggroup.TagGroup; +import me.gujun.android.taggroup.AndroidTagGroup; import me.gujun.android.taggroup.demo.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.tagGroup); - 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/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 95c0807..b33684c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -24,9 +24,9 @@ android:text="@string/add_tags" android:textColor="@android:color/darker_gray"/> - - @@ -50,7 +50,7 @@ android:layout_marginTop="5dp" android:background="#DDD"/> - @@ -62,7 +62,7 @@ android:text="@string/tags_small" android:textSize="14sp"/> - @@ -74,7 +74,7 @@ android:text="@string/tags_large" android:textSize="18sp"/> - diff --git a/app/src/main/res/layout/activity_tag_editor.xml b/app/src/main/res/layout/activity_tag_editor.xml index c49f02b..1f2da8f 100644 --- a/app/src/main/res/layout/activity_tag_editor.xml +++ b/app/src/main/res/layout/activity_tag_editor.xml @@ -6,9 +6,9 @@ android:orientation="vertical" android:padding="@dimen/activity_vertical_margin"> - diff --git a/gradle.properties b/gradle.properties index 9ae1fdd..d349af9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,6 +17,6 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -VERSION_NAME=1.6 -VERSION_CODE=16 +VERSION_NAME=1.7 +VERSION_CODE=17 GROUP=me.gujun.android.taggroup \ 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 92% 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 6f3b1ff..79e74f8 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/AndroidTagGroup.java @@ -50,7 +50,7 @@ * @version 2.0 * @since 2015-2-3 14:16:32 */ -public class TagGroup extends ViewGroup { +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; @@ -187,15 +187,15 @@ public class TagGroup extends ViewGroup { */ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener(); - public TagGroup(Context context) { + public AndroidTagGroup(Context context) { this(context, null); } - public TagGroup(Context context, AttributeSet attrs) { + public AndroidTagGroup(Context context, AttributeSet attrs) { this(context, attrs, R.attr.tagGroupStyle); } - public TagGroup(Context context, AttributeSet attrs, int defStyleAttr) { + public AndroidTagGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); default_border_stroke_width = dp2px(0.5f); default_text_size = sp2px(13.0f); @@ -205,29 +205,29 @@ public TagGroup(Context context, AttributeSet attrs, int defStyleAttr) { default_vertical_padding = dp2px(3.0f); // Load styled attributes. - final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TagGroup, defStyleAttr, R.style.TagGroup); + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AndroidTagGroup, defStyleAttr, R.style.AndroidTagGroup); try { - mIsAppendMode = a.getBoolean(R.styleable.TagGroup_atg_isAppendMode, false); - mInputHint = a.getText(R.styleable.TagGroup_atg_inputHint); - mBorderColor = a.getColor(R.styleable.TagGroup_atg_borderColor, default_border_color); - mTextColor = a.getColor(R.styleable.TagGroup_atg_textColor, default_text_color); - mBackgroundColor = a.getColor(R.styleable.TagGroup_atg_backgroundColor, default_background_color); - mDashBorderColor = a.getColor(R.styleable.TagGroup_atg_dashBorderColor, default_dash_border_color); - mInputHintColor = a.getColor(R.styleable.TagGroup_atg_inputHintColor, default_input_hint_color); - mInputTextColor = a.getColor(R.styleable.TagGroup_atg_inputTextColor, default_input_text_color); - mCheckedBorderColor = a.getColor(R.styleable.TagGroup_atg_checkedBorderColor, default_checked_border_color); - mCheckedTextColor = a.getColor(R.styleable.TagGroup_atg_checkedTextColor, default_checked_text_color); - mCheckedMarkerColor = a.getColor(R.styleable.TagGroup_atg_checkedMarkerColor, default_checked_marker_color); - mCheckedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_checkedBackgroundColor, default_checked_background_color); - mPressedBackgroundColor = a.getColor(R.styleable.TagGroup_atg_pressedBackgroundColor, default_pressed_background_color); - mBorderStrokeWidth = a.getDimension(R.styleable.TagGroup_atg_borderStrokeWidth, default_border_stroke_width); - mTextSize = a.getDimension(R.styleable.TagGroup_atg_textSize, default_text_size); - mHorizontalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalSpacing, default_horizontal_spacing); - mVerticalSpacing = (int) a.getDimension(R.styleable.TagGroup_atg_verticalSpacing, default_vertical_spacing); - mHorizontalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_horizontalPadding, default_horizontal_padding); - mVerticalPadding = (int) a.getDimension(R.styleable.TagGroup_atg_verticalPadding, default_vertical_padding); - mTagsLimitation = a.getInteger(R.styleable.TagGroup_atg_tagsLimitation, -1); - mCharsLimitation = a.getInteger(R.styleable.TagGroup_atg_charsLimitation, -1); + mIsAppendMode = a.getBoolean(R.styleable.AndroidTagGroup_atg_isAppendMode, false); + mInputHint = a.getText(R.styleable.AndroidTagGroup_atg_inputHint); + mBorderColor = a.getColor(R.styleable.AndroidTagGroup_atg_borderColor, default_border_color); + mTextColor = a.getColor(R.styleable.AndroidTagGroup_atg_textColor, default_text_color); + mBackgroundColor = a.getColor(R.styleable.AndroidTagGroup_atg_backgroundColor, default_background_color); + mDashBorderColor = a.getColor(R.styleable.AndroidTagGroup_atg_dashBorderColor, default_dash_border_color); + mInputHintColor = a.getColor(R.styleable.AndroidTagGroup_atg_inputHintColor, default_input_hint_color); + mInputTextColor = a.getColor(R.styleable.AndroidTagGroup_atg_inputTextColor, default_input_text_color); + mCheckedBorderColor = a.getColor(R.styleable.AndroidTagGroup_atg_checkedBorderColor, default_checked_border_color); + mCheckedTextColor = a.getColor(R.styleable.AndroidTagGroup_atg_checkedTextColor, default_checked_text_color); + mCheckedMarkerColor = a.getColor(R.styleable.AndroidTagGroup_atg_checkedMarkerColor, default_checked_marker_color); + mCheckedBackgroundColor = a.getColor(R.styleable.AndroidTagGroup_atg_checkedBackgroundColor, default_checked_background_color); + mPressedBackgroundColor = a.getColor(R.styleable.AndroidTagGroup_atg_pressedBackgroundColor, default_pressed_background_color); + mBorderStrokeWidth = a.getDimension(R.styleable.AndroidTagGroup_atg_borderStrokeWidth, default_border_stroke_width); + mTextSize = a.getDimension(R.styleable.AndroidTagGroup_atg_textSize, default_text_size); + mHorizontalSpacing = (int) a.getDimension(R.styleable.AndroidTagGroup_atg_horizontalSpacing, default_horizontal_spacing); + mVerticalSpacing = (int) a.getDimension(R.styleable.AndroidTagGroup_atg_verticalSpacing, default_vertical_spacing); + mHorizontalPadding = (int) a.getDimension(R.styleable.AndroidTagGroup_atg_horizontalPadding, default_horizontal_padding); + mVerticalPadding = (int) a.getDimension(R.styleable.AndroidTagGroup_atg_verticalPadding, default_vertical_padding); + mTagsLimitation = a.getInteger(R.styleable.AndroidTagGroup_atg_tagsLimitation, -1); + mCharsLimitation = a.getInteger(R.styleable.AndroidTagGroup_atg_charsLimitation, -1); } finally { a.recycle(); } @@ -255,7 +255,7 @@ public void submitTag() { inputTag.endInput(); if (mOnTagChangeListener != null) { - mOnTagChangeListener.onAppend(TagGroup.this, inputTag.getText().toString()); + mOnTagChangeListener.onAppend(AndroidTagGroup.this, inputTag.getText().toString()); } appendInputTag(); } @@ -295,7 +295,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new TagGroup.LayoutParams(getContext(), attrs); + return new AndroidTagGroup.LayoutParams(getContext(), attrs); } /** @@ -452,7 +452,7 @@ public void setOnTagClickListener(OnTagClickListener l) { protected void deleteTag(TagView tagView) { removeView(tagView); if (mOnTagChangeListener != null) { - mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString()); + mOnTagChangeListener.onDelete(AndroidTagGroup.this, tagView.getText().toString()); } if (getInputTag().mState == TagView.STATE_INPUT) { if (!getInputTag().isEnabled()) { @@ -499,14 +499,14 @@ 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); } /** @@ -535,7 +535,7 @@ public LayoutParams(int width, int 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 = @@ -714,9 +714,9 @@ class TagView extends TextView { public TagView(Context context, final int state, CharSequence text) { super(context); setPadding(mHorizontalPadding, mVerticalPadding, mHorizontalPadding, mVerticalPadding); - setLayoutParams(new TagGroup.LayoutParams( - TagGroup.LayoutParams.WRAP_CONTENT, - TagGroup.LayoutParams.WRAP_CONTENT)); + setLayoutParams(new AndroidTagGroup.LayoutParams( + AndroidTagGroup.LayoutParams.WRAP_CONTENT, + AndroidTagGroup.LayoutParams.WRAP_CONTENT)); setGravity(Gravity.CENTER); setText(text); @@ -756,7 +756,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(); } @@ -778,7 +778,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(); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 1d459ca..0dc6f4e 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -1,5 +1,5 @@ - + From 4fda69c842a43b634782761c2ff516dbce64e5f7 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 18 Dec 2015 19:37:08 +0330 Subject: [PATCH 09/37] fix style --- library/src/main/res/values/styles.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 @@ - - - - -