Skip to content

Commit

Permalink
Merge pull request #5 from MindorksOpenSource/feat/hide-drawable-when…
Browse files Browse the repository at this point in the history
…-edittext-is-empty

Feat/hide drawable when edittext is empty
  • Loading branch information
hi-manshu authored Sep 2, 2019
2 parents ea9190c + 6f7c824 commit 03f9101
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 85 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,21 @@
})

```
### 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
<com.mindorks.editdrawabletext.EditDrawableText
....
app:isDrawableShownWhenTextIsEmpty="false"
/>
```
or
```kotlin
drawableEditText.hasDrawable(/**YOUR VALUE**/)

```
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:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MainActivity : AppCompatActivity() {
}
}
}

})
drawableEditTextLeft.setDrawableClickListener(object : OnDrawableClickListener {
override fun onClick(target: DrawablePosition) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
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
private var drawableTop: Drawable? = null
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)
}

fun hasDrawable(value: Boolean) {
isDrawableShownWhenTextIsEmpty = value
if (!isDrawableShownWhenTextIsEmpty) this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
invalidate()
}

override fun setCompoundDrawables(leftDrawable: Drawable?,
topDrawable: Drawable?,
Expand All @@ -33,106 +54,129 @@ 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
val editText = this
this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {

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
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)
}


}
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
Expand Down
6 changes: 6 additions & 0 deletions editdrawabletext/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="EditDrawableText">
<attr name="isDrawableShownWhenTextIsEmpty" format="boolean"/>
</declare-styleable>
</resources>

0 comments on commit 03f9101

Please sign in to comment.