diff --git a/README.md b/README.md index 2a6aa9f..6e3a2a8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ -# `AndroidTagGroup` +# `Droid Tag Group 2017 version` -[![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) +[![](https://jitpack.io/v/LorenzoZaccagnini/DroidTag.svg)](https://jitpack.io/#LorenzoZaccagnini/DroidTag) The TagGroup is a special layout with a set of tags. You can use it to tag people, books or anything you want. @@ -11,14 +8,10 @@ Also you can contribute new idea to me. # Demo -### 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) +![screenshot1](https://preview.ibb.co/bBobP5/normaltag_Crop.png) +![screenshot1](https://preview.ibb.co/jMKfHQ/autocomplete_Crop.png) -[Download Demo](https://github.com/2dxgujun/AndroidTagGroup/releases/download/v1.4/AndroidTagGroup-Demo-v1.4.apk) # Usage @@ -27,18 +20,16 @@ Also you can contribute new idea to me. #### Gradle ```groovy dependencies { - compile 'me.gujun.android.taggroup:library:1.4@aar' -} +compile 'com.github.LorenzoZaccagnini:DroidTag:1.6'} ``` #### Maven ```xml - - me.gujun.android.taggroup - library - 1.4 - apklib - + + com.github.LorenzoZaccagnini + DroidTag + 1.6 + ``` ## Step 2 @@ -60,12 +51,25 @@ Use `setTags(...)` to set the initial tags in the group. 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 add an autocomplete list? + +Just add a string array, this an example for a fragment + + private String[] suggestionsArray = { "Tag1", "Tag2", "Tag3", "Tag4", "Tag5"}; + + mTagGroup.setOnTagCharEntryListener(new TagGroup.OnTagCharEntryListener() { + @Override + public void onCharEntry(String text) { + + mTagGroup.getTagView().setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, suggestionsArray)); + } + }); + #### How to detect tag click event? Implement a callback interface: `TagGroup.OnTagClickListener`, and set the listener via `setOnTagClickListener()`. @@ -107,7 +111,18 @@ There are several attributes you can set: | atg_horizontalPadding | 12dp | The horizontal tag padding.(Mark3) | | atg_verticalPadding | 3dp | The vertical tag padding.(Mark4) | -# Developed By +# New version by + +Lorenzo Zaccagnini - + + + Follow me on Facebook + + + Follow me on LinkedIn + + +# Fork of Jun Gu - <2dxgujun@gmail.com> diff --git a/demo/build.gradle b/demo/build.gradle index 8b3ed8d..6bbf077 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -1,3 +1,4 @@ + apply plugin: 'com.android.application' android { diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml index 732aefd..000e8f3 100644 --- a/demo/src/main/AndroidManifest.xml +++ b/demo/src/main/AndroidManifest.xml @@ -14,14 +14,6 @@ - - - diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java b/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java index 872bf9f..1a698d3 100644 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java +++ b/demo/src/main/java/me/gujun/android/taggroup/demo/MainActivity.java @@ -1,116 +1,31 @@ package me.gujun.android.taggroup.demo; -import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; +import android.widget.ArrayAdapter; import me.gujun.android.taggroup.TagGroup; -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 TagsManager mTagsManager; - - private TagGroup.OnTagClickListener mTagClickListener = new TagGroup.OnTagClickListener() { - @Override - public void onTagClick(String tag) { - Toast.makeText(MainActivity.this, tag, Toast.LENGTH_SHORT).show(); - } - }; - + private TagGroup mTagGroup; + //TODO REMOVE suggestion string when backend is ready + private String[] autoFakeServerCompleteTag = { "Tag1", "Tag2", "Tag3", "Tag4", "Tag5"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - mTagsManager = TagsManager.getInstance(getApplicationContext()); - String[] tags = mTagsManager.getTags(); - - mPromptText = (TextView) findViewById(R.id.tv_prompt); - mPromptText.setVisibility((tags == null || tags.length == 0) ? View.VISIBLE : View.GONE); - mPromptText.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - launchTagEditorActivity(); - } - }); - - mDefaultTagGroup = (TagGroup) findViewById(R.id.tag_group); - mSmallTagGroup = (TagGroup) findViewById(R.id.tag_group_small); - mLargeTagGroup = (TagGroup) findViewById(R.id.tag_group_large); - mBeautyTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty); - mBeautyInverseTagGroup = (TagGroup) findViewById(R.id.tag_group_beauty_inverse); - if (tags != null && tags.length > 0) { - mDefaultTagGroup.setTags(tags); - mSmallTagGroup.setTags(tags); - mLargeTagGroup.setTags(tags); - mBeautyTagGroup.setTags(tags); - mBeautyInverseTagGroup.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); - } - - @Override - 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); - } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_main_activity, menu); - return true; - } + mTagGroup = (TagGroup) findViewById(R.id.tag_group); - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.action_edit) { - launchTagEditorActivity(); - return true; - } - return false; - } + //get Fake Autocomplete server string array - protected void launchTagEditorActivity() { - Intent intent = new Intent(MainActivity.this, TagEditorActivity.class); - startActivity(intent); - } + mTagGroup.setOnTagCharEntryListener(new TagGroup.OnTagCharEntryListener() { + @Override + public void onCharEntry(String text) { - class MyTagGroupOnClickListener implements View.OnClickListener { - @Override - public void onClick(View v) { - launchTagEditorActivity(); - } + mTagGroup.getTagView().setAdapter(new ArrayAdapter<>(MainActivity.this, R.layout.taglist, autoFakeServerCompleteTag)); + } + }); } } \ No newline at end of file diff --git a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java b/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java deleted file mode 100644 index 27d2ea1..0000000 --- a/demo/src/main/java/me/gujun/android/taggroup/demo/TagEditorActivity.java +++ /dev/null @@ -1,52 +0,0 @@ -package me.gujun.android.taggroup.demo; - -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.view.Menu; -import android.view.MenuItem; - -import me.gujun.android.taggroup.TagGroup; -import me.gujun.android.taggroup.demo.db.TagsManager; - - -public class TagEditorActivity extends ActionBarActivity { - private TagGroup mTagGroup; - private TagsManager mTagsManager; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_tag_editor); - - mTagsManager = TagsManager.getInstance(getApplicationContext()); - String[] tags = mTagsManager.getTags(); - - mTagGroup = (TagGroup) findViewById(R.id.tag_group); - mTagGroup.setTags(tags); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_tag_editor_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - mTagsManager.updateTags(mTagGroup.getTags()); - finish(); - return true; - } else if (item.getItemId() == R.id.action_submit) { - mTagGroup.submitTag(); - return true; - } - return false; - } - - @Override - public void onBackPressed() { - mTagsManager.updateTags(mTagGroup.getTags()); - super.onBackPressed(); - } -} \ No newline at end of file diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml index db8f830..3467e6f 100644 --- a/demo/src/main/res/layout/activity_main.xml +++ b/demo/src/main/res/layout/activity_main.xml @@ -1,81 +1,30 @@ + - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + android:layout_height="match_parent"> + + + + + diff --git a/demo/src/main/res/layout/activity_tag_editor.xml b/demo/src/main/res/layout/activity_tag_editor.xml deleted file mode 100644 index 6749944..0000000 --- a/demo/src/main/res/layout/activity_tag_editor.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/demo/src/main/res/layout/taglist.xml b/demo/src/main/res/layout/taglist.xml new file mode 100644 index 0000000..c3e55c0 --- /dev/null +++ b/demo/src/main/res/layout/taglist.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c71e76..78c71d0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Sat Aug 26 11:56:33 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip 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..a739f94 100644 --- a/library/src/main/java/me/gujun/android/taggroup/TagGroup.java +++ b/library/src/main/java/me/gujun/android/taggroup/TagGroup.java @@ -1,6 +1,7 @@ package me.gujun.android.taggroup; import android.content.Context; +import android.text.InputType; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; @@ -17,6 +18,7 @@ import android.text.TextWatcher; import android.text.method.ArrowKeyMovementMethod; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; @@ -26,7 +28,10 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.TextView; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import java.util.ArrayList; import java.util.List; @@ -127,13 +132,18 @@ public class TagGroup extends ViewGroup { /** Listener used to dispatch tag change event. */ private OnTagChangeListener mOnTagChangeListener; - + + /** Autocomplete */ + private AutoCompleteTextView tagView; + /** Listener used to dispatch tag click event. */ private OnTagClickListener mOnTagClickListener; /** Listener used to handle tag click event. */ private InternalTagClickListener mInternalTagClickListener = new InternalTagClickListener(); + public OnTagCharEntryListener onTagCharEntryListener; + public TagGroup(Context context) { this(context, null); } @@ -329,7 +339,7 @@ public void onRestoreInstanceState(Parcelable state) { * * @return the INPUT state tag view or null if not exists */ - protected TagView getInputTag() { + public TagView getInputTag() { if (isAppendMode) { final int inputTagIndex = getChildCount() - 1; final TagView inputTag = getTagAt(inputTagIndex); @@ -366,7 +376,9 @@ protected TagView getLastNormalTagView() { TagView lastNormalTagView = getTagAt(lastNormalTagIndex); return lastNormalTagView; } - + public AutoCompleteTextView getTagView() { + return tagView; + } /** * Returns the tag array in group, except the INPUT tag. * @@ -521,7 +533,9 @@ protected void deleteTag(TagView tagView) { mOnTagChangeListener.onDelete(TagGroup.this, tagView.getText().toString()); } } - + public void setOnTagCharEntryListener(OnTagCharEntryListener listener) { + this.onTagCharEntryListener = listener; + } /** * Interface definition for a callback to be invoked when a tag group is changed. */ @@ -552,7 +566,9 @@ public interface OnTagClickListener { */ void onTagClick(String tag); } - + public interface OnTagCharEntryListener { + void onCharEntry(String text); + } /** * Per-child layout information for layouts. */ @@ -648,7 +664,7 @@ public void onClick(View v) { /** * The tag view which has two states can be either NORMAL or INPUT. */ - class TagView extends TextView { +class TagView extends AutoCompleteTextView { public static final int STATE_NORMAL = 1; public static final int STATE_INPUT = 2; @@ -717,7 +733,7 @@ public TagView(Context context, final int state, CharSequence text) { setGravity(Gravity.CENTER); setText(text); setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); - + setDropDownWidth(MATCH_PARENT); mState = state; setClickable(isAppendMode); @@ -736,6 +752,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() { @@ -758,7 +777,28 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { return false; } }); + //check changes + 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) { + tagView = TagView.this; + if(onTagCharEntryListener!=null && s !=null){ + onTagCharEntryListener.onCharEntry(s.toString()); + } + } + }); + // Handle the BACKSPACE key down. setOnKeyListener(new OnKeyListener() { @Override @@ -1022,4 +1062,4 @@ public boolean deleteSurroundingText(int beforeLength, int afterLength) { } } } -} \ No newline at end of file +}