From c4ef0e80b1b5e716a045b416dc920c75e8e86d39 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 01:52:44 +0530 Subject: [PATCH 1/6] Feat. Added Option to hide drawable when text is empty --- app/src/main/res/layout/activity_main.xml | 1 + .../editdrawabletext/EditDrawableText.kt | 209 +++++++++++------- .../src/main/res/values/attrs.xml | 6 + 3 files changed, 134 insertions(+), 82 deletions(-) create mode 100644 editdrawabletext/src/main/res/values/attrs.xml diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 532923f..c40b8ab 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -12,6 +12,7 @@ android:id="@+id/drawableEditText" android:layout_width="match_parent" android:layout_height="wrap_content" + app:isDrawableShownWhenTextIsEmpty="false" android:drawableRight="@drawable/ic_remove_red_eye_black_24dp" android:hint="@string/clickTheDrawables" android:inputType="text" diff --git a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt index ffeea93..1b8a3ef 100644 --- a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt +++ b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt @@ -1,14 +1,17 @@ package com.mindorks.editdrawabletext import android.content.Context +import android.content.res.TypedArray import android.graphics.Rect import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.TextWatcher import android.util.AttributeSet import android.view.MotionEvent import android.widget.EditText import kotlin.math.abs -class EditDrawableText : EditText { +class EditDrawableText(context: Context, attrs: AttributeSet) : EditText(context, attrs) { private var drawableRight: Drawable? = null private var drawableLeft: Drawable? = null @@ -16,12 +19,31 @@ class EditDrawableText : EditText { private var drawableBottom: Drawable? = null private var positionX: Int = 0 private var positionY: Int = 0 - + private var isDrawableShownWhenTextIsEmpty = true private var onDrawableClickListener: OnDrawableClickListener? = null - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) + init { + parseAttributes( + context.obtainStyledAttributes( + attrs, + R.styleable.EditDrawableText + ) + ) + } + + + private fun parseAttributes(obtainStyledAttributes: TypedArray) { + isDrawableShownWhenTextIsEmpty = obtainStyledAttributes.getBoolean(R.styleable.EditDrawableText_isDrawableShownWhenTextIsEmpty, isDrawableShownWhenTextIsEmpty); + obtainStyledAttributes.recycle() + hasDrawable(isDrawableShownWhenTextIsEmpty) + } + + private fun hasDrawable(value: Boolean) { + isDrawableShownWhenTextIsEmpty = value + if (!isDrawableShownWhenTextIsEmpty) this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + invalidate() + } override fun setCompoundDrawables(leftDrawable: Drawable?, topDrawable: Drawable?, @@ -33,99 +55,49 @@ class EditDrawableText : EditText { if (bottomDrawable != null) drawableBottom = bottomDrawable super.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable) } - + override fun onTouchEvent(event: MotionEvent): Boolean { var bounds: Rect? - if (event.action == MotionEvent.ACTION_DOWN) { - positionX = event.x.toInt() - positionY = event.y.toInt() - - - // this works for left since container shares 0,0 origin with bounds - if (drawableLeft != null) { - bounds = drawableLeft!!.bounds - - var xClickPosition: Int - var yClickPosition: Int - /* - * @return pixels into dp - */ - val extraClickArea = (13 * resources.displayMetrics.density + 0.5).toInt() + val editText = this + this.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(p0: Editable?) { - xClickPosition = positionX - yClickPosition = positionY + } - if (!bounds!!.contains(positionX, positionY)) { - /** Gives some extra space for tapping. */ - xClickPosition = positionX - extraClickArea - yClickPosition = positionY - extraClickArea + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + } - if (xClickPosition <= 0) xClickPosition = positionX - if (yClickPosition <= 0) yClickPosition = positionY + override fun onTextChanged(char: CharSequence, p1: Int, p2: Int, p3: Int) { + if (char.isEmpty()) { + if (!isDrawableShownWhenTextIsEmpty) editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + } else editText.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, drawableBottom) + } - /** Creates square from the smallest value from x or y*/ - if (xClickPosition < yClickPosition) yClickPosition = xClickPosition - } - if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) { - onDrawableClickListener!!.onClick(DrawablePosition.LEFT) - event.action = MotionEvent.ACTION_CANCEL - return false + }) + if (event.action == MotionEvent.ACTION_DOWN) { + positionX = event.x.toInt() + positionY = event.y.toInt() - } + // this works for left since container shares 0,0 origin with bounds + if (drawableLeft != null) { + bounds = drawableLeft?.bounds + setupDrawableLeftClick(bounds, event) } - + if (drawableRight != null) { - bounds = drawableRight!!.bounds - var xClickPosition: Int - var yClickPosition: Int - val extraClickingArea = 13 - - xClickPosition = positionX + extraClickingArea - yClickPosition = positionY - extraClickingArea - - /** - * It right drawable -> subtract the value of x from the width of view. so that width - tapped area * will result in x co-ordinate in drawable bound. - */ - xClickPosition = width - xClickPosition - if (xClickPosition <= 0) xClickPosition += extraClickingArea - - /* If after calculating for extra clickable area is negative. - * assign the original value so that after subtracting - * extra clicking area value doesn't go into negative value. - */ - - if (yClickPosition <= 0) yClickPosition = positionY - - /**If drawable bounds contains the x and y points then move ahead. */ - if (bounds!!.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) { - onDrawableClickListener!!.onClick(DrawablePosition.RIGHT) - event.action = MotionEvent.ACTION_CANCEL - return false - } - return super.onTouchEvent(event) + bounds = drawableRight?.bounds + setupDrawableRightClick(bounds, event) } if (drawableTop != null) { - bounds = drawableTop!!.bounds - val extraClickingArea = 13 - if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds.width() / 2 + extraClickingArea) { - onDrawableClickListener!!.onClick(DrawablePosition.TOP) - event.action = MotionEvent.ACTION_CANCEL - return false - } + bounds = drawableTop?.bounds + setupDrawableTopClick(bounds, event) } - if(drawableBottom!=null) - { - bounds = drawableBottom!!.bounds - val extraClickingArea = 13 - - if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds.width() / 2 + extraClickingArea) { - onDrawableClickListener!!.onClick(DrawablePosition.BOTTOM) - event.action = MotionEvent.ACTION_CANCEL - return false - } + if (drawableBottom != null) { + bounds = drawableBottom?.bounds + setupDrawableBottomClick(bounds, event) } @@ -133,6 +105,79 @@ class EditDrawableText : EditText { return super.onTouchEvent(event) } + private fun setupDrawableBottomClick(bounds: Rect?, event: MotionEvent) { + val extraClickingArea = 13 + if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds!!.width() / 2 + extraClickingArea) { + onDrawableClickListener?.onClick(DrawablePosition.BOTTOM) + event.action = MotionEvent.ACTION_CANCEL + } + } + + private fun setupDrawableTopClick(bounds: Rect?, event: MotionEvent) { + val extraClickingArea = 13 + if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds!!.width() / 2 + extraClickingArea) { + onDrawableClickListener?.onClick(DrawablePosition.TOP) + event.action = MotionEvent.ACTION_CANCEL + } + } + + private fun setupDrawableLeftClick(bounds: Rect?, event: MotionEvent) { + var xClickPosition: Int + var yClickPosition: Int + /* + * @return pixels into dp + */ + val extraClickArea = (13 * resources.displayMetrics.density + 0.5).toInt() + + xClickPosition = positionX + yClickPosition = positionY + + if (!bounds!!.contains(positionX, positionY)) { + /** Gives some extra space for tapping. */ + xClickPosition = positionX - extraClickArea + yClickPosition = positionY - extraClickArea + + if (xClickPosition <= 0) xClickPosition = positionX + if (yClickPosition <= 0) yClickPosition = positionY + + /** Creates square from the smallest value from x or y*/ + if (xClickPosition < yClickPosition) yClickPosition = xClickPosition + } + + if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) { + onDrawableClickListener?.onClick(DrawablePosition.LEFT) + event.action = MotionEvent.ACTION_CANCEL + + } + } + + private fun setupDrawableRightClick(bounds: Rect?, event: MotionEvent) { + var xClickPosition: Int + var yClickPosition: Int + val extraClickingArea = 13 + + xClickPosition = positionX + extraClickingArea + yClickPosition = positionY - extraClickingArea + + /** + * It right drawable -> subtract the value of x from the width of view. so that width - tapped area * will result in x co-ordinate in drawable bound. + */ + xClickPosition = width - xClickPosition + if (xClickPosition <= 0) xClickPosition += extraClickingArea + + /* If after calculating for extra clickable area is negative. + * assign the original value so that after subtracting + * extra clicking area value doesn't go into negative value. + */ + + if (yClickPosition <= 0) yClickPosition = positionY + + /**If drawable bounds contains the x and y points then move ahead. */ + if (bounds!!.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) { + onDrawableClickListener?.onClick(DrawablePosition.RIGHT) + event.action = MotionEvent.ACTION_CANCEL + } + } fun setDrawableClickListener(OnDrawableClickListener: OnDrawableClickListener) { this.onDrawableClickListener = OnDrawableClickListener diff --git a/editdrawabletext/src/main/res/values/attrs.xml b/editdrawabletext/src/main/res/values/attrs.xml new file mode 100644 index 0000000..591465e --- /dev/null +++ b/editdrawabletext/src/main/res/values/attrs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From c6af753e6d67559ee19025f98b8609473ce69894 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 02:01:09 +0530 Subject: [PATCH 2/6] Feat. Added Option to hide drawable when text is empty --- README.md | 13 +++++++++++-- .../mindorks/editdrawabletext/EditDrawableText.kt | 1 - 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index abf9707..d47a8c4 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,17 @@ }) ``` -### TODO -* More features related to EditText + +5. You can also add an option so that the drawable is hidden by default and only shows when there is some text available in EditDrawableText +```XML + +``` +When the value is false, then the drawable is hidden by default and vice versa + ## If this library helps you in anyway, show your love :heart: by putting a :star: on this project :v: diff --git a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt index 1b8a3ef..0e443f3 100644 --- a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt +++ b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt @@ -32,7 +32,6 @@ class EditDrawableText(context: Context, attrs: AttributeSet) : EditText(context ) } - private fun parseAttributes(obtainStyledAttributes: TypedArray) { isDrawableShownWhenTextIsEmpty = obtainStyledAttributes.getBoolean(R.styleable.EditDrawableText_isDrawableShownWhenTextIsEmpty, isDrawableShownWhenTextIsEmpty); obtainStyledAttributes.recycle() From 9d22427484f6a5fa07d42475ddd7f36ae445b376 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 02:03:03 +0530 Subject: [PATCH 3/6] Feat. Added Option to hide drawable when text is empty --- README.md | 5 +++++ .../java/com/mindorks/editdrawabletextsample/MainActivity.kt | 2 +- .../java/com/mindorks/editdrawabletext/EditDrawableText.kt | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d47a8c4..a17ccc3 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,11 @@ /> ``` +or +```kotlin + drawableEditTextTop.hasDrawable(/**YOUR VALIUE**/) + +``` When the value is false, then the drawable is hidden by default and vice versa diff --git a/app/src/main/java/com/mindorks/editdrawabletextsample/MainActivity.kt b/app/src/main/java/com/mindorks/editdrawabletextsample/MainActivity.kt index 2f367d5..eb3e382 100644 --- a/app/src/main/java/com/mindorks/editdrawabletextsample/MainActivity.kt +++ b/app/src/main/java/com/mindorks/editdrawabletextsample/MainActivity.kt @@ -25,7 +25,7 @@ class MainActivity : AppCompatActivity() { } } } - + }) drawableEditTextLeft.setDrawableClickListener(object : OnDrawableClickListener { override fun onClick(target: DrawablePosition) { diff --git a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt index 0e443f3..9919670 100644 --- a/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt +++ b/editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt @@ -38,7 +38,7 @@ class EditDrawableText(context: Context, attrs: AttributeSet) : EditText(context hasDrawable(isDrawableShownWhenTextIsEmpty) } - private fun hasDrawable(value: Boolean) { + fun hasDrawable(value: Boolean) { isDrawableShownWhenTextIsEmpty = value if (!isDrawableShownWhenTextIsEmpty) this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) invalidate() From 2b0a68555267da5bd90c6f33916892df9dc57933 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 02:03:24 +0530 Subject: [PATCH 4/6] Feat. Added Option to hide drawable when text is empty --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a17ccc3..18ac947 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ ``` or ```kotlin - drawableEditTextTop.hasDrawable(/**YOUR VALIUE**/) + drawableEditTextTop.hasDrawable(/**YOUR VALUE**/) ``` When the value is false, then the drawable is hidden by default and vice versa From f4c135af4fdd51f6b722c4414cd0f3930cdcfb71 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 02:03:45 +0530 Subject: [PATCH 5/6] Feat. Added Option to hide drawable when text is empty --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 18ac947..935e358 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ ``` or ```kotlin - drawableEditTextTop.hasDrawable(/**YOUR VALUE**/) + drawableEditText.hasDrawable(/**YOUR VALUE**/) ``` When the value is false, then the drawable is hidden by default and vice versa From 6f7c8249c516b24d436fb5d8e8cafd8b35349ca0 Mon Sep 17 00:00:00 2001 From: Himanshu Singh Date: Tue, 3 Sep 2019 02:04:27 +0530 Subject: [PATCH 6/6] Feat. Added Option to hide drawable when text is empty --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 935e358..c87080a 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,11 @@ ``` or ```kotlin - drawableEditText.hasDrawable(/**YOUR VALUE**/) + drawableEditText.hasDrawable(/**YOUR VALUE**/) ``` When the value is false, then the drawable is hidden by default and vice versa