diff --git a/README.md b/README.md
index 07c7b32..6af32d8 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Add below dependency in your **build.gradle** file.
```groovy
dependencies {
- compile 'co.lujun:androidtagview:1.0.3'
+ compile 'co.lujun:androidtagview:1.0.4'
}
```
@@ -75,6 +75,9 @@ Now, you have successfully created some TagViews. The following will show some m
| tag_clickable | boolean | Whether TagView can clickable(default unclickable)
| tag_theme | enum | The TagView [theme](#themes)
| tag_text_direction | enum | The TagView text [direction](#directions)
+| tag_ripple_color | color | The ripple effect color(default #EEEEEE)
+| tag_ripple_alpha | integer | The ripple effect color alpha(the value may between 0 - 255, default 128)
+| tag_ripple_duration | integer | The ripple effect duration(In milliseconds, default 1000ms)
**You can set these attributes in layout file, or use setters(each attribute has get and set method) to set them.**
@@ -179,6 +182,10 @@ mTagContainerLayout.removeAllTags();
```
## Change logs
+###1.0.4(2016-10-30)
+- Support ripple effect(Call requires API level 11), like [Android CustomButton](https://github.com/whilu/AndroidSample/tree/master/CustomButton)
+- fix bugs
+
###1.0.3(2016-4-3)
- add ```getTags()``` method to get the list for all tags
- fixed bugs in ListView/RecyclerView
diff --git a/androidtagview/build.gradle b/androidtagview/build.gradle
index 8839da5..cb0154f 100644
--- a/androidtagview/build.gradle
+++ b/androidtagview/build.gradle
@@ -7,8 +7,8 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
- versionCode 103
- versionName "1.0.3"
+ versionCode 104
+ versionName "1.0.4"
}
buildTypes {
release {
diff --git a/androidtagview/src/main/java/co/lujun/androidtagview/TagContainerLayout.java b/androidtagview/src/main/java/co/lujun/androidtagview/TagContainerLayout.java
index 9b5469a..7ca73bd 100644
--- a/androidtagview/src/main/java/co/lujun/androidtagview/TagContainerLayout.java
+++ b/androidtagview/src/main/java/co/lujun/androidtagview/TagContainerLayout.java
@@ -124,6 +124,15 @@ public class TagContainerLayout extends ViewGroup {
/** Default tag min length*/
private static final int TAG_MIN_LENGTH = 3;
+ /** The ripple effect duration(In milliseconds, default 1000ms)*/
+ private int mRippleDuration = 1000;
+
+ /** The ripple effect color(default #EEEEEE)*/
+ private int mRippleColor;
+
+ /** The ripple effect color alpha(the value may between 0 - 255, default 128)*/
+ private int mRippleAlpha = 128;
+
public TagContainerLayout(Context context) {
this(context, null);
}
@@ -178,6 +187,9 @@ private void init(Context context, AttributeSet attrs, int defStyleAttr){
mTagTextColor = attributes.getColor(R.styleable.AndroidTagView_tag_text_color, mTagTextColor);
mTagTextDirection = attributes.getInt(R.styleable.AndroidTagView_tag_text_direction, mTagTextDirection);
isTagViewClickable = attributes.getBoolean(R.styleable.AndroidTagView_tag_clickable, false);
+ mRippleColor = attributes.getColor(R.styleable.AndroidTagView_tag_ripple_color, Color.parseColor("#EEEEEE"));
+ mRippleAlpha = attributes.getInteger(R.styleable.AndroidTagView_tag_ripple_alpha, mRippleAlpha);
+ mRippleDuration = attributes.getInteger(R.styleable.AndroidTagView_tag_ripple_duration, mRippleDuration);
attributes.recycle();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -399,6 +411,9 @@ private void initTagView(TagView tagView){
tagView.setIsViewClickable(isTagViewClickable);
tagView.setBdDistance(mTagBdDistance);
tagView.setOnTagClickListener(mOnTagClickListener);
+ tagView.setRippleAlpha(mRippleAlpha);
+ tagView.setRippleColor(mRippleColor);
+ tagView.setRippleDuration(mRippleDuration);
}
private void invalidateTags(){
@@ -1011,6 +1026,54 @@ public void setTagTextColor(int color) {
this.mTagTextColor = color;
}
+ /**
+ * Get the ripple effect color's alpha.
+ * @return
+ */
+ public int getRippleAlpha() {
+ return mRippleAlpha;
+ }
+
+ /**
+ * Set TagView ripple effect alpha, the value may between 0 to 255, default is 128.
+ * @param mRippleAlpha
+ */
+ public void setRippleAlpha(int mRippleAlpha) {
+ this.mRippleAlpha = mRippleAlpha;
+ }
+
+ /**
+ * Get the ripple effect color.
+ * @return
+ */
+ public int getRippleColor() {
+ return mRippleColor;
+ }
+
+ /**
+ * Set TagView ripple effect color.
+ * @param mRippleColor
+ */
+ public void setRippleColor(int mRippleColor) {
+ this.mRippleColor = mRippleColor;
+ }
+
+ /**
+ * Get the ripple effect duration.
+ * @return
+ */
+ public int getRippleDuration() {
+ return mRippleDuration;
+ }
+
+ /**
+ * Set TagView ripple effect duration, default is 1000ms.
+ * @param mRippleDuration
+ */
+ public void setRippleDuration(int mRippleDuration) {
+ this.mRippleDuration = mRippleDuration;
+ }
+
public float dp2px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
diff --git a/androidtagview/src/main/java/co/lujun/androidtagview/TagView.java b/androidtagview/src/main/java/co/lujun/androidtagview/TagView.java
index 2009be1..adedfdc 100644
--- a/androidtagview/src/main/java/co/lujun/androidtagview/TagView.java
+++ b/androidtagview/src/main/java/co/lujun/androidtagview/TagView.java
@@ -1,10 +1,15 @@
package co.lujun.androidtagview;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.RectF;
+import android.graphics.Region;
import android.graphics.Typeface;
+import android.os.Build;
import android.support.v4.widget.ViewDragHelper;
import android.text.TextUtils;
import android.view.MotionEvent;
@@ -64,7 +69,7 @@ public class TagView extends View {
/** The distance between baseline and descent*/
private float bdDistance;
- private Paint mPaint;
+ private Paint mPaint, mRipplePaint;
private RectF mRectF;
@@ -75,9 +80,24 @@ public class TagView extends View {
private int mLastX, mLastY;
private float fontH, fontW;
+
+ private float mTouchX, mTouchY;
+
+ /** The ripple effect duration(default 1000ms)*/
+ private int mRippleDuration = 1000;
+
+ private float mRippleRadius;
+
+ private int mRippleColor;
+
+ private int mRippleAlpha;
+
+ private Path mPath;
private Typeface mTypeface;
+ private ValueAnimator mRippleValueAnimator;
+
private Runnable mLongClickHandle = new Runnable() {
@Override
public void run() {
@@ -98,7 +118,10 @@ public TagView(Context context, String text){
private void init(String text){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mRipplePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mRipplePaint.setStyle(Paint.Style.FILL);
mRectF = new RectF();
+ mPath = new Path();
mOriginText = text == null ? "" : text;
}
@@ -162,6 +185,9 @@ protected void onDraw(Canvas canvas) {
canvas.drawText(mAbstractText, getWidth() / 2 - fontW / 2,
getHeight() / 2 + fontH / 2 - bdDistance, mPaint);
}
+
+ // draw ripple for TagView
+ drawRipple(canvas);
}
@Override
@@ -192,6 +218,13 @@ public boolean dispatchTouchEvent(MotionEvent event) {
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ mRippleRadius = 0.0f;
+ mTouchX = event.getX();
+ mTouchY = event.getY();
+ splashRipple();
+ }
+
if (isViewClickable && mOnTagClickListener != null){
int x = (int) event.getX();
int y = (int) event.getY();
@@ -227,6 +260,42 @@ public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private void drawRipple(Canvas canvas){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && canvas != null){
+ canvas.save();
+ mPath.reset();
+
+ canvas.clipPath(mPath);
+ mPath.addRoundRect(mRectF, mBorderRadius, mBorderRadius, Path.Direction.CCW);
+
+ canvas.clipPath(mPath, Region.Op.REPLACE);
+ canvas.drawCircle(mTouchX, mTouchY, mRippleRadius, mRipplePaint);
+ canvas.restore();
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private void splashRipple(){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && mTouchX > 0 && mTouchY > 0){
+ mRipplePaint.setColor(mRippleColor);
+ mRipplePaint.setAlpha(mRippleAlpha);
+ final float maxDis = Math.max(Math.max(Math.max(mTouchX, mTouchY),
+ Math.abs(getMeasuredWidth() - mTouchX)), Math.abs(getMeasuredHeight() - mTouchY));
+
+ mRippleValueAnimator = ValueAnimator.ofFloat(0.0f, maxDis).setDuration(mRippleDuration);
+ mRippleValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float animValue = (float) animation.getAnimatedValue();
+ mRippleRadius = animValue >= maxDis ? 0 : animValue;
+ postInvalidate();
+ }
+ });
+ mRippleValueAnimator.start();
+ }
+ }
+
public String getText(){
return mOriginText;
}
@@ -299,6 +368,18 @@ public void setTypeface(Typeface typeface) {
onDealText();
}
+ public void setRippleAlpha(int mRippleAlpha) {
+ this.mRippleAlpha = mRippleAlpha;
+ }
+
+ public void setRippleColor(int mRippleColor) {
+ this.mRippleColor = mRippleColor;
+ }
+
+ public void setRippleDuration(int mRippleDuration) {
+ this.mRippleDuration = mRippleDuration;
+ }
+
public void setBdDistance(float bdDistance) {
this.bdDistance = bdDistance;
}
diff --git a/androidtagview/src/main/res/values/attrs.xml b/androidtagview/src/main/res/values/attrs.xml
index c0f676a..9a41220 100644
--- a/androidtagview/src/main/res/values/attrs.xml
+++ b/androidtagview/src/main/res/values/attrs.xml
@@ -38,5 +38,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index c03d0ad..66aa056 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.5.0'
- classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
+ classpath 'com.android.tools.build:gradle:2.2.1'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6216523..c4e826c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Oct 21 11:34:03 PDT 2015
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
+#Sun Oct 30 18:08:28 CST 2016
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
diff --git a/sample/src/main/res/layout/content_main.xml b/sample/src/main/res/layout/content_main.xml
index 7be6c24..0a25e7f 100644
--- a/sample/src/main/res/layout/content_main.xml
+++ b/sample/src/main/res/layout/content_main.xml
@@ -111,6 +111,9 @@
app:container_gravity="center"
app:horizontal_interval="10dp"
app:tag_clickable="true"
+ app:tag_ripple_alpha="47"
+ app:tag_ripple_color="#000000"
+ app:tag_ripple_duration="2000"
app:tag_theme="pure_teal"
app:vertical_interval="10dp" />